Skip to content

database

Database initialization and admin bootstrap for Supabase PostgreSQL.

Handles: - Schema creation (4 tables: users, refresh_tokens, sessions, messages) - Admin user bootstrap - Legacy session migration from markdown files to PostgreSQL - Async query helpers for FastAPI endpoints

All queries use supabase-py → PostgREST, which provides parameterized query binding and is immune to SQL injection through the normal API. The only raw SQL vector is _db_execute_sql(), which is private and accepts only static trusted input (supabase_schema.sql contents). Table names are validated against an allowlist in all query helpers.

db_delete(table, **filters) async

DELETE rows matching filters. PostgREST parameterizes — safe from injection.

db_fetch_all(table, columns='*', order=None, ascending=True, limit=100, **filters) async

SELECT from a table and return all matching rows.

PostgREST parameterizes all filters — immune to SQL injection. List-valued filters become IN clauses; order may be a single column name or a list of (column, ascending) tuples for deterministic multi-column ordering.

db_fetch_one(table, columns='*', **filters) async

SELECT from a table and return the first matching row, or None.

PostgREST parameterizes all filters — immune to SQL injection.

db_insert(table, data) async

INSERT a row. PostgREST parameterizes values — safe from injection.

db_update(table, data, **filters) async

UPDATE rows matching filters. PostgREST parameterizes — safe from injection.

ensure_admin() async

Create the admin user if it doesn't already exist.

get_supabase()

Get or create the singleton Supabase client (sync).

Uses the service_role key for full database access. Thread-safe for use with asyncio.to_thread() in async endpoints.

init_db() async

Initialize the database schema idempotently.

Tries to create tables via exec_sql if they don't exist yet. Safe to call multiple times.

migrate_legacy_sessions() async

Migrate legacy markdown sessions to Supabase. Returns count migrated.