Skip to main content

Database Schema

Village Data uses PostgreSQL with the prototype schema for all application tables.

Core Tables

Users & Auth

TablePurpose
auth.usersSupabase-managed user accounts
profileExtended user profile data
user_roleUser-to-role assignments
roleRole definitions (admin, user, etc.)

Datasets

TablePurpose
datasetDataset metadata (name, description, owner)
dataset_versionVersion tracking with file references

Chatbots

TablePurpose
chatbotChatbot configuration
chatbot_datasetMany-to-many: chatbots to datasets
chatbot_usagePer-message analytics

Content & Discovery

TablePurpose
content_usageUsage tracking for Library
content_bookmarkUser bookmarks
content_listCustom lists

Key Relationships

profile (1) ──── (n) dataset

└── (n) chatbot ──── (n) chatbot_dataset ──── (n) dataset

└── (n) chatbot_usage

Schema: prototype

All application tables live in the prototype schema:

-- Example: Query datasets
SELECT * FROM prototype.dataset WHERE owner_id = auth.uid();

Important: The prototype schema must be exposed in Supabase API settings for REST access.

Row Level Security

All tables use RLS policies. Common patterns:

-- Owner can read their own data
CREATE POLICY "Users can view own datasets"
ON prototype.dataset FOR SELECT
USING (owner_id = auth.uid());

-- Published content is public
CREATE POLICY "Published datasets are public"
ON prototype.dataset FOR SELECT
USING (status = 'published');

Migrations

Migrations are in supabase/migrations/ and follow the naming convention:

001_initial_schema.sql
002_add_chatbots.sql
003_add_content_usage.sql
...

Run migrations:

# Local
supabase db reset

# Production
supabase db push