🐘 Nile Postgres Admin
Multi-tenant database with advanced extensions
📝 Nile DB Configuration
Nile Postgres provides multi-tenant capabilities with built-in extensions.
Features Available:
- ✅ Multi-tenancy - Isolate data by organization/tenant
- ✅ pgvector - Vector similarity search for AI embeddings
- ✅ pg_cron - Schedule database jobs
- ✅ PostGIS - Geographic data support
- ✅ Full-text search - Advanced text search
- ✅ Row-level security - Tenant isolation
Environment Variables Needed:
# Add to .env
NILE_POSTGRES_URL=postgresql://user:password@db.thenile.dev:5432/db_name
NILE_API_KEY=your_nile_api_key_here
Database Extensions
🔍 pgvector
Vector similarity search for AI embeddings
⏰ pg_cron
Schedule database jobs
🗺️ PostGIS
Geographic objects and spatial functions
🔎 pg_trgm
Fuzzy string matching
Extension Usage Examples
-- pgvector: Store and search embeddings
CREATE TABLE lyrics_embeddings (
id UUID PRIMARY KEY,
lyric_text TEXT,
embedding vector(1536), -- OpenAI embedding size
created_at TIMESTAMP DEFAULT NOW()
);
-- Create vector similarity index
CREATE INDEX ON lyrics_embeddings USING ivfflat (embedding vector_cosine_ops);
-- Search similar lyrics
SELECT lyric_text, embedding <=> '[...]'::vector AS distance
FROM lyrics_embeddings
ORDER BY distance LIMIT 10;
-- pg_cron: Schedule airdrop distributions
SELECT cron.schedule(
'distribute-weekly-airdrops',
'0 0 * * 1', -- Every Monday at midnight
$$SELECT distribute_airdrops('weekly');$$
);
-- PostGIS: Find nearby gardens
SELECT name, ST_Distance(location, ST_Point(-1.5, 36.8)) as distance
FROM gardens
WHERE ST_DWithin(location, ST_Point(-1.5, 36.8), 0.1)
ORDER BY distance; Multi-Tenant Management
Tenant Isolation
Nile provides built-in multi-tenancy for isolating data by organization or user.
-- Create tenant-aware table
CREATE TABLE battles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL, -- Nile automatically filters by this
challenger_id UUID,
opponent_id UUID,
status VARCHAR(20),
created_at TIMESTAMP DEFAULT NOW()
);
-- Enable RLS for tenant isolation
ALTER TABLE battles ENABLE ROW LEVEL SECURITY;
-- Policy: Users can only see their tenant's data
CREATE POLICY tenant_isolation ON battles
FOR ALL
USING (tenant_id = current_setting('app.tenant_id')::UUID);
-- Set tenant context in application
SET app.tenant_id = 'tenant-uuid-here';
-- Now all queries automatically filter by tenant
SELECT * FROM battles; -- Only returns battles for current tenant
Use Cases for WorldBridge One
- Organizations - Separate data for different refugee camps
- Communities - Isolate battle leagues or garden groups
- Events - Separate hackathon or tournament data
- Privacy - Ensure data doesn't leak between tenants
AI Vector Search
Use Cases
🎤 Lyric Similarity
Find similar rap bars based on meaning, not just keywords
🎵 Music Recommendations
Recommend tracks based on content similarity
📚 Content Discovery
Find related educational content or projects
🤖 Semantic Search
Search by meaning, not exact matches
Implementation Example
-- 1. Create embeddings table for battle submissions CREATE TABLE battle_submission_embeddings ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), submission_id UUID REFERENCES battle_submissions(id), bars_text TEXT, embedding vector(1536), created_at TIMESTAMP DEFAULT NOW() ); -- 2. Create index for fast similarity search CREATE INDEX battle_embedding_idx ON battle_submission_embeddings USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100); -- 3. Store embedding (generated via OpenAI API) INSERT INTO battle_submission_embeddings (submission_id, bars_text, embedding) VALUES ( 'submission-uuid', 'Your bars here...', '[0.123, -0.456, ...]'::vector -- From OpenAI embeddings API ); -- 4. Find similar bars SELECT s.bars_text, e.embedding <=> $1::vector AS similarity_score FROM battle_submission_embeddings e JOIN battle_submissions s ON e.submission_id = s.id ORDER BY similarity_score LIMIT 10;
Scheduled Database Jobs
Job Ideas for WorldBridge One
Weekly Airdrop Distribution
Every Monday at 00:00 UTC
SELECT cron.schedule( 'weekly-airdrops', '0 0 * * 1', $$SELECT activate_weekly_airdrops();$$ );
Battle Timeout Checker
Every hour, forfeit overdue submissions
SELECT cron.schedule( 'battle-timeouts', '0 * * * *', $$SELECT check_battle_timeouts();$$ );
Impact Metrics Update
Daily at 01:00 UTC
SELECT cron.schedule( 'daily-impact-calc', '0 1 * * *', $$SELECT calculate_daily_impact();$$ );
Notification Cleanup
Weekly, delete old read notifications
SELECT cron.schedule(
'notification-cleanup',
'0 2 * * 0',
$$DELETE FROM notifications
WHERE is_read = true
AND created_at < NOW() - INTERVAL '30 days';$$
); Manage Jobs
-- List all scheduled jobs
SELECT * FROM cron.job;
-- Unschedule a job
SELECT cron.unschedule('weekly-airdrops');
-- View job run history
SELECT * FROM cron.job_run_details
ORDER BY start_time DESC
LIMIT 10;
Geographic Data (PostGIS)
Use Cases
- Garden Locations - Store and query community garden coordinates
- Event Venues - Find nearby events based on location
- Impact Mapping - Visualize Kakuma camp projects on a map
- Resource Distribution - Optimize delivery routes
Implementation
-- Add location column to gardens ALTER TABLE gardens ADD COLUMN location GEOGRAPHY(POINT, 4326); -- Create spatial index CREATE INDEX gardens_location_idx ON gardens USING GIST (location); -- Insert garden with coordinates (Kakuma Camp) UPDATE gardens SET location = ST_SetSRID(ST_MakePoint(34.813, 3.121), 4326) WHERE name = 'Kakuma Victory Garden'; -- Find gardens within 5km of a point SELECT name, ST_Distance(location, ST_SetSRID(ST_MakePoint(34.8, 3.1), 4326)) / 1000 AS distance_km FROM gardens WHERE ST_DWithin( location, ST_SetSRID(ST_MakePoint(34.8, 3.1), 4326), 5000 -- 5km in meters ) ORDER BY distance_km; -- Find nearest garden to a location SELECT name, location FROM gardens ORDER BY location <-> ST_SetSRID(ST_MakePoint(34.813, 3.121), 4326) LIMIT 1;
🚀 Getting Started with Nile
1. Sign up for Nile
Visit thenile.dev and create an account
2. Create Database
Create a new Nile database from the dashboard
3. Get Connection String
postgresql://user:password@db.thenile.dev:5432/your_db
4. Add to Environment
# .env
NILE_POSTGRES_URL=your_connection_string_here
NILE_API_KEY=your_api_key_here
5. Install Extensions
-- Run in Nile SQL console
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS pg_cron;
CREATE EXTENSION IF NOT EXISTS postgis;
6. Test Connection
Use this admin panel to verify connection and run queries