From f0659a79039c65fd057d0727002526914cbd1147 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Fri, 10 Jul 2026 02:09:54 +0000 Subject: [PATCH] chore: remove pgpm-cron module and scheduled_cron table Maintenance scheduling moved to app_jobs.scheduled_jobs (constructive-db#2012); the pg_cron sync module and its registry table are dead code. --- MODULES.md | 1 - .../tables/scheduled_cron/table.sql | 31 ----------- packages/metaschema-schema/pgpm.plan | 1 - .../tables/scheduled_cron/table.sql | 7 --- .../sql/metaschema-schema--0.15.5.sql | 21 +------- .../tables/scheduled_cron/table.sql | 7 --- packages/pgpm-cron/.npmignore | 2 - packages/pgpm-cron/LICENSE | 22 -------- packages/pgpm-cron/Makefile | 6 --- packages/pgpm-cron/README.md | 52 ------------------- .../procedures/sync_scheduled_cron.sql | 44 ---------------- .../deploy/schemas/pgpm_cron/schema.sql | 7 --- packages/pgpm-cron/jest.config.js | 15 ------ packages/pgpm-cron/package.json | 35 ------------- packages/pgpm-cron/pgpm-cron.control | 7 --- packages/pgpm-cron/pgpm.plan | 6 --- .../procedures/sync_scheduled_cron.sql | 7 --- .../revert/schemas/pgpm_cron/schema.sql | 7 --- packages/pgpm-cron/sql/pgpm-cron--0.0.1.sql | 26 ---------- .../procedures/sync_scheduled_cron.sql | 7 --- .../verify/schemas/pgpm_cron/schema.sql | 7 --- 21 files changed, 1 insertion(+), 317 deletions(-) delete mode 100644 packages/metaschema-schema/deploy/schemas/metaschema_public/tables/scheduled_cron/table.sql delete mode 100644 packages/metaschema-schema/revert/schemas/metaschema_public/tables/scheduled_cron/table.sql delete mode 100644 packages/metaschema-schema/verify/schemas/metaschema_public/tables/scheduled_cron/table.sql delete mode 100644 packages/pgpm-cron/.npmignore delete mode 100644 packages/pgpm-cron/LICENSE delete mode 100644 packages/pgpm-cron/Makefile delete mode 100644 packages/pgpm-cron/README.md delete mode 100644 packages/pgpm-cron/deploy/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql delete mode 100644 packages/pgpm-cron/deploy/schemas/pgpm_cron/schema.sql delete mode 100644 packages/pgpm-cron/jest.config.js delete mode 100644 packages/pgpm-cron/package.json delete mode 100644 packages/pgpm-cron/pgpm-cron.control delete mode 100644 packages/pgpm-cron/pgpm.plan delete mode 100644 packages/pgpm-cron/revert/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql delete mode 100644 packages/pgpm-cron/revert/schemas/pgpm_cron/schema.sql delete mode 100644 packages/pgpm-cron/sql/pgpm-cron--0.0.1.sql delete mode 100644 packages/pgpm-cron/verify/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql delete mode 100644 packages/pgpm-cron/verify/schemas/pgpm_cron/schema.sql diff --git a/MODULES.md b/MODULES.md index 29495ce2f..bc99eb85c 100644 --- a/MODULES.md +++ b/MODULES.md @@ -31,7 +31,6 @@ ### Job Management - [ ] `packages/jobs/jobs` - Core job system - [ ] `packages/jobs/database-jobs` - Database-specific job handling -- [ ] `packages/pgpm-cron` - pg_cron sync for the scheduled_cron registry ## Meta & Database Introspection diff --git a/packages/metaschema-schema/deploy/schemas/metaschema_public/tables/scheduled_cron/table.sql b/packages/metaschema-schema/deploy/schemas/metaschema_public/tables/scheduled_cron/table.sql deleted file mode 100644 index b19323a01..000000000 --- a/packages/metaschema-schema/deploy/schemas/metaschema_public/tables/scheduled_cron/table.sql +++ /dev/null @@ -1,31 +0,0 @@ --- Deploy schemas/metaschema_public/tables/scheduled_cron/table to pg - --- requires: schemas/metaschema_public/schema --- requires: schemas/metaschema_public/tables/database/table - -BEGIN; - -CREATE TABLE metaschema_public.scheduled_cron ( - id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), - database_id uuid NOT NULL, - name text NOT NULL, - schedule text NOT NULL, - command text NOT NULL, - is_enabled boolean NOT NULL DEFAULT true, - - created_at timestamptz DEFAULT now(), - updated_at timestamptz DEFAULT now(), - - CONSTRAINT scheduled_cron_database_fkey - FOREIGN KEY (database_id) - REFERENCES metaschema_public.database (id) - ON DELETE CASCADE, - - CONSTRAINT scheduled_cron_database_name_unique - UNIQUE (database_id, name) -); - -CREATE INDEX scheduled_cron_database_id_idx - ON metaschema_public.scheduled_cron (database_id); - -COMMIT; diff --git a/packages/metaschema-schema/pgpm.plan b/packages/metaschema-schema/pgpm.plan index aeaff8e36..d5da66f68 100644 --- a/packages/metaschema-schema/pgpm.plan +++ b/packages/metaschema-schema/pgpm.plan @@ -38,4 +38,3 @@ schemas/metaschema_public/tables/function/table [schemas/metaschema_public/schem schemas/metaschema_public/tables/partition/table [schemas/metaschema_public/schema schemas/metaschema_public/tables/database/table schemas/metaschema_public/tables/table/table schemas/metaschema_public/tables/field/table] 2026-05-26T00:00:00Z Constructive # add metaschema_public.partition table for pg_partman lifecycle config schemas/metaschema_public/tables/composite_type/table [schemas/metaschema_public/schema schemas/metaschema_public/tables/database/table schemas/metaschema_public/tables/schema/table schemas/metaschema_public/types/object_category] 2026-05-29T00:00:00Z devin # add metaschema_public.composite_type table for generated composite types schemas/metaschema_public/tables/schema/triggers/enforce_api_exposure_ratchet [schemas/metaschema_public/tables/schema/table] 2026-06-18T00:00:03Z devin # enforce one-way ratchet on api_exposure (never_expose is permanent) -schemas/metaschema_public/tables/scheduled_cron/table [schemas/metaschema_public/schema schemas/metaschema_public/tables/database/table] 2026-07-08T00:00:00Z devin # add metaschema_public.scheduled_cron table for declarative pg_cron job tracking diff --git a/packages/metaschema-schema/revert/schemas/metaschema_public/tables/scheduled_cron/table.sql b/packages/metaschema-schema/revert/schemas/metaschema_public/tables/scheduled_cron/table.sql deleted file mode 100644 index a0245d7d2..000000000 --- a/packages/metaschema-schema/revert/schemas/metaschema_public/tables/scheduled_cron/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/metaschema_public/tables/scheduled_cron/table from pg - -BEGIN; - -DROP TABLE metaschema_public.scheduled_cron; - -COMMIT; diff --git a/packages/metaschema-schema/sql/metaschema-schema--0.15.5.sql b/packages/metaschema-schema/sql/metaschema-schema--0.15.5.sql index 36c7f2c61..79a4487dc 100644 --- a/packages/metaschema-schema/sql/metaschema-schema--0.15.5.sql +++ b/packages/metaschema-schema/sql/metaschema-schema--0.15.5.sql @@ -868,23 +868,4 @@ CREATE TRIGGER _000003_enforce_api_exposure_ratchet ON metaschema_public.schema FOR EACH ROW WHEN (new.api_exposure IS DISTINCT FROM old.api_exposure) - EXECUTE PROCEDURE metaschema_public.tg_enforce_api_exposure_ratchet(); - -CREATE TABLE metaschema_public.scheduled_cron ( - id uuid PRIMARY KEY DEFAULT uuid_generate_v4(), - database_id uuid NOT NULL, - name text NOT NULL, - schedule text NOT NULL, - command text NOT NULL, - is_enabled boolean NOT NULL DEFAULT true, - created_at timestamptz DEFAULT now(), - updated_at timestamptz DEFAULT now(), - CONSTRAINT scheduled_cron_database_fkey - FOREIGN KEY(database_id) - REFERENCES metaschema_public.database (id) - ON DELETE CASCADE, - CONSTRAINT scheduled_cron_database_name_unique - UNIQUE (database_id, name) -); - -CREATE INDEX scheduled_cron_database_id_idx ON metaschema_public.scheduled_cron (database_id); \ No newline at end of file + EXECUTE PROCEDURE metaschema_public.tg_enforce_api_exposure_ratchet(); \ No newline at end of file diff --git a/packages/metaschema-schema/verify/schemas/metaschema_public/tables/scheduled_cron/table.sql b/packages/metaschema-schema/verify/schemas/metaschema_public/tables/scheduled_cron/table.sql deleted file mode 100644 index 4370c796a..000000000 --- a/packages/metaschema-schema/verify/schemas/metaschema_public/tables/scheduled_cron/table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/metaschema_public/tables/scheduled_cron/table on pg - -BEGIN; - -SELECT verify_table ('metaschema_public.scheduled_cron'); - -ROLLBACK; diff --git a/packages/pgpm-cron/.npmignore b/packages/pgpm-cron/.npmignore deleted file mode 100644 index cf8a45548..000000000 --- a/packages/pgpm-cron/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -__tests__ -jest.config.js diff --git a/packages/pgpm-cron/LICENSE b/packages/pgpm-cron/LICENSE deleted file mode 100644 index 7b18c9183..000000000 --- a/packages/pgpm-cron/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2025 Dan Lynch -Copyright (c) 2025 Constructive - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/pgpm-cron/Makefile b/packages/pgpm-cron/Makefile deleted file mode 100644 index dc21436fd..000000000 --- a/packages/pgpm-cron/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -EXTENSION = pgpm-cron -DATA = sql/pgpm-cron--0.0.1.sql - -PG_CONFIG = pg_config -PGXS := $(shell $(PG_CONFIG) --pgxs) -include $(PGXS) diff --git a/packages/pgpm-cron/README.md b/packages/pgpm-cron/README.md deleted file mode 100644 index 32a8967b7..000000000 --- a/packages/pgpm-cron/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# @pgpm/cron - -Open-code pg_cron sync for the `metaschema_public.scheduled_cron` registry. - -## Overview - -`metaschema_public.scheduled_cron` is the declarative source of truth for which -recurring jobs should exist for a database (populated automatically by metaschema -triggers — e.g. registering `maintenance:partman` when a partitioned table is -parented). This module contains the **open-code** mechanism that reconciles that -registry into [pg_cron](https://github.com/citusdata/pg_cron), so it is safe to -ship to exported/consumer databases without any platform-proprietary code. - -It targets the **local, single-database** deployment shape, where `pg_cron` is -installed in the same database that holds the `scheduled_cron` rows. The platform -cross-database case (one `pg_cron` in `postgres` fanning out to many app/tenant -databases via `cron.schedule_in_database()`) is handled separately by the -platform deploy flow, not by this module. - -## pg_cron placement (important) - -`pg_cron` is installed **once per cluster** — in a single database (the "cron -database", `postgres` by default), which is the only place `CREATE EXTENSION -pg_cron` and the `cron.job` table exist. It also requires -`shared_preload_libraries = 'pg_cron'` + a restart. So `pg_cron` is **not** -present in the platform database or in tenant/app databases, and it cannot be a -hard `requires` in this module's control file. - -- **Local single-DB dev:** app, registry, and `pg_cron` are all one database, so - `sync_scheduled_cron()` uses `cron.schedule()` directly (this module). -- **Platform:** the registry lives in the platform DB but scheduling must run - from the cron DB via `cron.schedule_in_database(..., target => platform_db)`. - That cross-database fan-out is handled by the platform deploy flow, not here. - -## What it does - -`pgpm_cron.sync_scheduled_cron()`: - -- Silently no-ops when `pg_cron` is not installed — the table remains the source - of truth for an external scheduler. -- Schedules every `is_enabled` row via `cron.schedule(name, schedule, command)`. -- Unschedules rows that are present but disabled. - -`database_id` on `scheduled_cron` is operational metadata (which database a job -targets / cascade cleanup) and is intentionally ignored here: in the local -single-database shape every row belongs to the one database that runs the sync. - -## Notes - -- Removal of a job when its `scheduled_cron` row is deleted is expected to be - driven by a delete-side sync in the platform metadatabase; this reconcile - function only handles enabled/disabled state for rows that still exist. diff --git a/packages/pgpm-cron/deploy/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql b/packages/pgpm-cron/deploy/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql deleted file mode 100644 index 3999463ca..000000000 --- a/packages/pgpm-cron/deploy/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql +++ /dev/null @@ -1,44 +0,0 @@ --- Deploy schemas/pgpm_cron/procedures/sync_scheduled_cron to pg - --- requires: schemas/pgpm_cron/schema --- requires: metaschema-schema:schemas/metaschema_public/tables/scheduled_cron/table - -BEGIN; - --- Reconcile the declarative metaschema_public.scheduled_cron registry into --- pg_cron for the local (single-database) deployment shape, where pg_cron lives --- in the same database that owns the scheduled_cron rows. Open-code only: safe --- to ship to exported/consumer databases. The platform cross-database case --- (one pg_cron fanning out via cron.schedule_in_database) is handled by the --- platform deploy flow, not here. --- --- database_id is intentionally not consulted: in the local shape every row --- belongs to the one database running the sync. -CREATE FUNCTION pgpm_cron.sync_scheduled_cron() - RETURNS void - AS $$ -DECLARE - v_row record; -BEGIN - -- pg_cron lives in one database per cluster (the cron database), so it is - -- absent in most databases this module ships to. Where absent, the registry - -- is still the source of truth for an external scheduler; nothing to do here. - IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_cron') THEN - RETURN; - END IF; - - FOR v_row IN - SELECT name, schedule, command, is_enabled - FROM metaschema_public.scheduled_cron - LOOP - IF v_row.is_enabled THEN - PERFORM cron.schedule(v_row.name, v_row.schedule, v_row.command); - ELSIF EXISTS (SELECT 1 FROM cron.job WHERE jobname = v_row.name) THEN - PERFORM cron.unschedule(v_row.name); - END IF; - END LOOP; -END; -$$ -LANGUAGE 'plpgsql' VOLATILE; - -COMMIT; diff --git a/packages/pgpm-cron/deploy/schemas/pgpm_cron/schema.sql b/packages/pgpm-cron/deploy/schemas/pgpm_cron/schema.sql deleted file mode 100644 index 6e3d7643b..000000000 --- a/packages/pgpm-cron/deploy/schemas/pgpm_cron/schema.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Deploy schemas/pgpm_cron/schema to pg - -BEGIN; - -CREATE SCHEMA pgpm_cron; - -COMMIT; diff --git a/packages/pgpm-cron/jest.config.js b/packages/pgpm-cron/jest.config.js deleted file mode 100644 index e20e7efb5..000000000 --- a/packages/pgpm-cron/jest.config.js +++ /dev/null @@ -1,15 +0,0 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - - // Match both __tests__ and colocated test files - testMatch: ['**/?(*.)+(test|spec).{ts,tsx,js,jsx}'], - - // Ignore build artifacts and type declarations - testPathIgnorePatterns: ['/dist/', '\\.d\\.ts$'], - modulePathIgnorePatterns: ['/dist/'], - watchPathIgnorePatterns: ['/dist/'], - - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], -}; diff --git a/packages/pgpm-cron/package.json b/packages/pgpm-cron/package.json deleted file mode 100644 index 1975ccac2..000000000 --- a/packages/pgpm-cron/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@pgpm/cron", - "version": "0.30.0", - "description": "open-code pg_cron sync for the scheduled_cron registry", - "author": "Dan Lynch ", - "contributors": [ - "Constructive " - ], - "keywords": [ - "postgresql", - "pgpm", - "cron", - "pg_cron", - "scheduler" - ], - "publishConfig": { - "access": "public" - }, - "scripts": { - "bundle": "pgpm package", - "test": "jest", - "test:watch": "jest --watch" - }, - "devDependencies": { - "pgpm": "^4.28.7" - }, - "repository": { - "type": "git", - "url": "https://github.com/constructive-io/pgpm-modules" - }, - "homepage": "https://github.com/constructive-io/pgpm-modules", - "bugs": { - "url": "https://github.com/constructive-io/pgpm-modules/issues" - } -} diff --git a/packages/pgpm-cron/pgpm-cron.control b/packages/pgpm-cron/pgpm-cron.control deleted file mode 100644 index 07c284d63..000000000 --- a/packages/pgpm-cron/pgpm-cron.control +++ /dev/null @@ -1,7 +0,0 @@ -# pgpm-cron extension -comment = 'open-code pg_cron sync for the scheduled_cron registry' -default_version = '0.0.1' -module_pathname = '$libdir/pgpm-cron' -requires = 'plpgsql,metaschema-schema' -relocatable = false -superuser = false diff --git a/packages/pgpm-cron/pgpm.plan b/packages/pgpm-cron/pgpm.plan deleted file mode 100644 index 2085400a6..000000000 --- a/packages/pgpm-cron/pgpm.plan +++ /dev/null @@ -1,6 +0,0 @@ -%syntax-version=1.0.0 -%project=pgpm-cron -%uri=pgpm-cron - -schemas/pgpm_cron/schema 2026-07-08T00:00:00Z devin # add pgpm_cron schema -schemas/pgpm_cron/procedures/sync_scheduled_cron [schemas/pgpm_cron/schema metaschema-schema:schemas/metaschema_public/tables/scheduled_cron/table] 2026-07-08T00:00:01Z devin # sync scheduled_cron registry rows into pg_cron (local single-database deployments) diff --git a/packages/pgpm-cron/revert/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql b/packages/pgpm-cron/revert/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql deleted file mode 100644 index 97bbfdf47..000000000 --- a/packages/pgpm-cron/revert/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/pgpm_cron/procedures/sync_scheduled_cron from pg - -BEGIN; - -DROP FUNCTION pgpm_cron.sync_scheduled_cron(); - -COMMIT; diff --git a/packages/pgpm-cron/revert/schemas/pgpm_cron/schema.sql b/packages/pgpm-cron/revert/schemas/pgpm_cron/schema.sql deleted file mode 100644 index e9b37bc8a..000000000 --- a/packages/pgpm-cron/revert/schemas/pgpm_cron/schema.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Revert schemas/pgpm_cron/schema from pg - -BEGIN; - -DROP SCHEMA pgpm_cron; - -COMMIT; diff --git a/packages/pgpm-cron/sql/pgpm-cron--0.0.1.sql b/packages/pgpm-cron/sql/pgpm-cron--0.0.1.sql deleted file mode 100644 index edfc74ca0..000000000 --- a/packages/pgpm-cron/sql/pgpm-cron--0.0.1.sql +++ /dev/null @@ -1,26 +0,0 @@ -\echo Use "CREATE EXTENSION pgpm-cron" to load this file. \quit -CREATE SCHEMA pgpm_cron; - -CREATE FUNCTION pgpm_cron.sync_scheduled_cron() RETURNS void AS $EOFCODE$ -DECLARE - v_row record; -BEGIN - -- pg_cron lives in one database per cluster (the cron database), so it is - -- absent in most databases this module ships to. Where absent, the registry - -- is still the source of truth for an external scheduler; nothing to do here. - IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_cron') THEN - RETURN; - END IF; - - FOR v_row IN - SELECT name, schedule, command, is_enabled - FROM metaschema_public.scheduled_cron - LOOP - IF v_row.is_enabled THEN - PERFORM cron.schedule(v_row.name, v_row.schedule, v_row.command); - ELSIF EXISTS (SELECT 1 FROM cron.job WHERE jobname = v_row.name) THEN - PERFORM cron.unschedule(v_row.name); - END IF; - END LOOP; -END; -$EOFCODE$ LANGUAGE plpgsql VOLATILE; \ No newline at end of file diff --git a/packages/pgpm-cron/verify/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql b/packages/pgpm-cron/verify/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql deleted file mode 100644 index 941f389f8..000000000 --- a/packages/pgpm-cron/verify/schemas/pgpm_cron/procedures/sync_scheduled_cron.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/pgpm_cron/procedures/sync_scheduled_cron on pg - -BEGIN; - -SELECT has_function_privilege('pgpm_cron.sync_scheduled_cron()', 'execute'); - -ROLLBACK; diff --git a/packages/pgpm-cron/verify/schemas/pgpm_cron/schema.sql b/packages/pgpm-cron/verify/schemas/pgpm_cron/schema.sql deleted file mode 100644 index ec3bf0073..000000000 --- a/packages/pgpm-cron/verify/schemas/pgpm_cron/schema.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Verify schemas/pgpm_cron/schema on pg - -BEGIN; - -SELECT 1/count(*) FROM pg_catalog.pg_namespace WHERE nspname = 'pgpm_cron'; - -ROLLBACK;