Spaces:
Sleeping
db/ β Schema, seeds, and migration runner
This folder owns everything database-related for CyberArena:
db/
βββ schema/ β numbered, idempotent SQL migrations (run in order)
βββ seed/ β per-type example JSON (the real seeds live in app/generators/)
βββ apply.py β run every schema/*.sql against Supabase
βββ README.md (this file)
Schema files
Numbered with a 3-digit prefix so a directory listing shows the run order:
000_extensions.sql β pgcrypto
001_users.sql β users + leaderboard view
002_encryption_challenges.sql β crypto (red+blue)
003_(removed) β was web exploitation
004_code_fixing_challenges.sql β code-fixing (blue)
005_log_analysis_challenges.sql β log-analysis (blue) + storage bucket
006_vulnerability_hunter_challenges.sql β vulnerability-hunter (blue)
007_onevone.sql β 1v1 mode (4 tables + claim_win RPC)
008_certificates.sql β certificate table + RLS
009_user_completions.sql β per-category completion counter
Each file is idempotent:
CREATE TABLE IF NOT EXISTS β¦DROP POLICY IF EXISTS β¦followed byCREATE POLICY β¦CREATE OR REPLACE FUNCTION β¦for the one RPC
Re-running db/apply.py after the schema is already in place is a
no-op.
Running the migrations
# Dry-run (list the files in order, do not run)
python db/apply.py --dry-run
# Apply to Supabase (requires SUPABASE_SERVICE_KEY in .env)
python db/apply.py
The script POSTs every file's contents to the
/rest/v1/rpc/exec_sql endpoint. If the exec_sql RPC is not yet
defined in your project, create it once via the Supabase SQL editor:
CREATE OR REPLACE FUNCTION public.exec_sql(query text)
RETURNS void LANGUAGE plpgsql AS $$
BEGIN EXECUTE query; END $$;
GRANT EXECUTE ON FUNCTION public.exec_sql(text) TO service_role;
The
service_rolekey is required because DDL bypasses RLS.
Seeds
The actual curated seeds (Tier 4 safety net in the AI fallback chain)
live in the Python generator modules under app/generators/. The
files in db/seed/ are templates β one example per challenge
type that documents the JSON shape the corresponding Supabase table
expects. Use them as a starting point if you want to manually insert
a custom challenge.
Checking live state
python scripts/check_state.py # one-page health report
python scripts/seed_pools.py --check
check_state.py reports row counts for every challenge table, the
1v1 tables, certificates, and user_completions (per category).