97 lines
3.9 KiB
JavaScript
97 lines
3.9 KiB
JavaScript
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))
|
|
const latestSchemaVersion = Math.max(...migrationNames.map(name => Number(name.slice(0, 4))))
|
|
|
|
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;
|
|
if to_regprocedure('public.stage_four_create_character(uuid,uuid,text,text,text,jsonb,integer,integer,integer,integer,jsonb,jsonb,jsonb)') is null then
|
|
raise exception 'D&G bootstrap verification failed: character creation RPC is missing';
|
|
end if;
|
|
if public.dng_schema_version() <> ${latestSchemaVersion} then
|
|
raise exception 'D&G bootstrap verification failed: unexpected schema version';
|
|
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.`)
|