diff --git a/apps/backend/prisma/migrations/20260630010000_drop_bulldozer_timefold_worker/migration.sql b/apps/backend/prisma/migrations/20260630010000_drop_bulldozer_timefold_worker/migration.sql deleted file mode 100644 index 5afaf45e1..000000000 --- a/apps/backend/prisma/migrations/20260630010000_drop_bulldozer_timefold_worker/migration.sql +++ /dev/null @@ -1,37 +0,0 @@ --- Retire the SQL bulldozer timefold worker. --- --- The live payments path now runs on bulldozer-js (an in-process 1-second tick --- loop drives timefolds), so the Postgres pg_cron job and its worker function --- are dead code. We unschedule the cron job and drop the function in a single --- transaction so there is never a window where the scheduled job exists but the --- function it calls does not. --- --- We only swallow the two benign "pg_cron isn't really here" cases: the cron --- extension being absent entirely, and the cron.job table being missing. We do --- NOT swallow unschedule failures such as insufficient_privilege — if pg_cron is --- present and we cannot prove the job is gone, we must abort (rolling back the --- DROP FUNCTION below) rather than leave a scheduled job calling a function we --- just deleted, which would error every second. A human must then resolve the --- privilege issue and re-run. The backing tables are dropped in the following --- migration, after this commit guarantees nothing calls the function anymore. --- SPLIT_STATEMENT_SENTINEL --- SINGLE_STATEMENT_SENTINEL -DO $$ -BEGIN - IF to_regnamespace('cron') IS NULL THEN - RETURN; - END IF; - - BEGIN - PERFORM cron.unschedule("jobid") - FROM cron.job - WHERE "jobname" = 'bulldozer-timefold-worker'; - EXCEPTION - WHEN undefined_table THEN - NULL; - END; -END -$$; --- SPLIT_STATEMENT_SENTINEL --- SINGLE_STATEMENT_SENTINEL -DROP FUNCTION IF EXISTS public.bulldozer_timefold_process_queue(); diff --git a/apps/backend/prisma/migrations/20260630010000_drop_bulldozer_timefold_worker/tests/worker-and-function-dropped.ts b/apps/backend/prisma/migrations/20260630010000_drop_bulldozer_timefold_worker/tests/worker-and-function-dropped.ts deleted file mode 100644 index 411c120e2..000000000 --- a/apps/backend/prisma/migrations/20260630010000_drop_bulldozer_timefold_worker/tests/worker-and-function-dropped.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { Sql } from "postgres"; -import { expect } from "vitest"; - -const functionExists = async (sql: Sql): Promise => { - const rows = await sql` - SELECT 1 - FROM pg_proc p - JOIN pg_namespace n ON n.oid = p.pronamespace - WHERE n.nspname = 'public' - AND p.proname = 'bulldozer_timefold_process_queue' - `; - return rows.length > 0; -}; - -const cronPresent = async (sql: Sql): Promise => { - const rows = await sql`SELECT to_regnamespace('cron') IS NOT NULL AS present`; - return Boolean(rows[0].present); -}; - -export const preMigration = async (sql: Sql) => { - // Sanity: the worker function must exist before this migration runs, otherwise - // the test isn't actually exercising the drop. - expect(await functionExists(sql)).toBe(true); -}; - -export const postMigration = async (sql: Sql) => { - // The worker function is gone. - expect(await functionExists(sql)).toBe(false); - - // If pg_cron is installed (it is in dev/CI Postgres), the worker job is gone - // too. Guarded so the test still passes on a Postgres without pg_cron, - // mirroring the best-effort guard in the migration itself. - if (await cronPresent(sql)) { - const jobs = await sql` - SELECT 1 FROM cron.job WHERE "jobname" = 'bulldozer-timefold-worker' - `; - expect(jobs).toHaveLength(0); - } - - // Idempotency: re-running the teardown statements must be a no-op (the - // migration uses DROP ... IF EXISTS and a guarded unschedule), not an error. - await sql`DROP FUNCTION IF EXISTS public.bulldozer_timefold_process_queue()`; - if (await cronPresent(sql)) { - await sql`SELECT cron.unschedule("jobid") FROM cron.job WHERE "jobname" = 'bulldozer-timefold-worker'`; - } - expect(await functionExists(sql)).toBe(false); -};