import { readdir, readFile, writeFile } from 'node:fs/promises' import { dirname, join, resolve } from 'node:path' import { fileURLToPath } from 'node:url' const root = resolve(dirname(fileURLToPath(import.meta.url)), '..') const migrationsDirectory = join(root, 'supabase', 'migrations') const outputPath = join(root, 'supabase', 'bootstrap.sql') const migrationNames = (await readdir(migrationsDirectory)) .filter(name => /^\d+_.+\.sql$/.test(name)) .sort((left, right) => left.localeCompare(right)) if (migrationNames.length === 0) throw new Error('No Supabase migrations were found.') const sections = await Promise.all(migrationNames.map(async (name) => { const sql = await readFile(join(migrationsDirectory, name), 'utf8') return `\n-- ============================================================================\n-- ${name}\n-- ============================================================================\n\n${sql.trim()}\n` })) const preflight = ` do $$ begin if to_regclass('auth.users') is null then raise exception 'D&G bootstrap preflight failed: auth.users is missing'; end if; if not exists ( select 1 from information_schema.columns where table_schema = 'auth' and table_name = 'users' and column_name = 'is_anonymous' ) then raise exception 'D&G bootstrap preflight failed: auth.users.is_anonymous is missing'; end if; if to_regclass('public.profiles') is not null or to_regclass('public.ai_jobs') is not null or to_regtype('public.member_role') is not null or to_regprocedure('public.claim_ai_job(text)') is not null then raise exception 'D&G bootstrap preflight failed: a partial/existing D&G schema was found. Do not run the fresh bootstrap over it.'; end if; end; $$; ` const verification = ` do $$ begin if to_regclass('public.profiles') is null then raise exception 'D&G bootstrap verification failed: public.profiles is missing'; end if; if to_regclass('public.ai_jobs') is null then raise exception 'D&G bootstrap verification failed: public.ai_jobs is missing'; end if; if to_regprocedure('public.claim_ai_job(text)') is null then raise exception 'D&G bootstrap verification failed: public.claim_ai_job(text) is missing'; end if; if to_regprocedure('public.stage_two_create_campaign(uuid,uuid,text)') is null then raise exception 'D&G bootstrap verification failed: stage-two RPCs are missing'; end if; if to_regprocedure('public.stage_two_retry_failed_round(uuid,uuid)') is null then raise exception 'D&G bootstrap verification failed: failed-round recovery RPC is missing'; end if; if to_regprocedure('public.dng_schema_version()') is null then raise exception 'D&G bootstrap verification failed: schema version RPC is missing'; end if; end; $$; notify pgrst, 'reload schema'; commit; select 'Dungeons & Ground database is ready' as result, to_regclass('public.profiles') as profiles, to_regclass('public.ai_jobs') as ai_jobs, to_regprocedure('public.claim_ai_job(text)') as worker_rpc; ` const output = `-- GENERATED FILE. Rebuild with: pnpm db:bundle -- Paste this entire file into a new Supabase SQL Editor query and click Run. -- It is intended for a fresh Dungeons & Ground project. The explicit -- transaction ensures a failure cannot leave a half-created schema. begin; ${preflight} ${sections.join('')} ${verification}` await writeFile(outputPath, output) console.log(`Wrote ${outputPath} from ${migrationNames.length} migrations.`)