From a573041958095d6a4615eeefd25ecff01e715484 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 8 Jun 2026 09:15:23 +0000 Subject: [PATCH 1/3] fix: standalone compat for platform_secrets ON CONFLICT The slicer-generated platform_secrets_set() does ON CONFLICT (namespace_id, name) but the table's unique constraint is (database_id, namespace_id, name). In the monolith this evolved across migrations; the slicer extracted the final table state but the function from the earlier schema. This seed patch bridges the gap for standalone mode: 1. DEFAULT on database_id from jwt_private.current_database_id() 2. Unique index on (namespace_id, name) matching the ON CONFLICT clause --- .../fixtures/standalone_compat.sql | 31 +++++++++++++++++++ pgpm/constructive-infra-seed/pgpm.plan | 1 + .../fixtures/standalone_compat.sql | 11 +++++++ .../fixtures/standalone_compat.sql | 11 +++++++ 4 files changed, 54 insertions(+) create mode 100644 pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql create mode 100644 pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql create mode 100644 pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql diff --git a/pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql b/pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql new file mode 100644 index 0000000..18b706b --- /dev/null +++ b/pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql @@ -0,0 +1,31 @@ +-- Deploy: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat +-- made with <3 @ constructive.io +-- +-- Standalone compatibility patch for platform_secrets. +-- +-- In the monolith, database_id is set by provisioning triggers and the unique +-- constraint evolves across migrations. The slicer extracts the final table +-- state (UNIQUE on database_id, namespace_id, name) but the functions were +-- generated for the earlier schema (UNIQUE on namespace_id, name only). +-- +-- This patch bridges the gap for standalone mode: +-- 1. DEFAULT on database_id → filled from jwt_private.current_database_id() +-- so INSERT without explicit database_id still populates it. +-- 2. Unique index on (namespace_id, name) → matches the ON CONFLICT clause +-- in the generated platform_secrets_set() function. +-- +-- Safe for standalone (single database_id). The upstream AST builders will +-- eventually generate entity-aware functions that include database_id directly. + +BEGIN; + +-- 1. Set DEFAULT on database_id so INSERTs without it use the JWT claim +ALTER TABLE constructive_store_private.platform_secrets + ALTER COLUMN database_id SET DEFAULT jwt_private.current_database_id(); + +-- 2. Create unique index matching the ON CONFLICT (namespace_id, name) clause +-- in the generated platform_secrets_set/del functions +CREATE UNIQUE INDEX IF NOT EXISTS platform_secrets_namespace_id_name_idx + ON constructive_store_private.platform_secrets (namespace_id, name); + +COMMIT; diff --git a/pgpm/constructive-infra-seed/pgpm.plan b/pgpm/constructive-infra-seed/pgpm.plan index 7ec9bd3..c5e05a9 100644 --- a/pgpm/constructive-infra-seed/pgpm.plan +++ b/pgpm/constructive-infra-seed/pgpm.plan @@ -5,3 +5,4 @@ schemas/constructive_infra_public/partitions/create_default_partitions 2017-08-11T08:11:51Z Constructive # create default partitions for range-partitioned tables schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace [schemas/constructive_infra_public/partitions/create_default_partitions] 2017-08-11T08:11:51Z Constructive # seed default platform namespace schemas/constructive_infra_public/tables/platform_function_definitions/fixtures/seed_built_in_functions [schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2017-08-11T08:11:51Z Constructive # seed built-in platform functions with required_secrets and namespace +schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat [schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2017-08-11T08:11:51Z Constructive # standalone compat: DEFAULT database_id from JWT + unique index for ON CONFLICT diff --git a/pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql b/pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql new file mode 100644 index 0000000..80f73e4 --- /dev/null +++ b/pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql @@ -0,0 +1,11 @@ +-- Revert: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat +-- made with <3 @ constructive.io + +BEGIN; + +DROP INDEX IF EXISTS constructive_store_private.platform_secrets_namespace_id_name_idx; + +ALTER TABLE constructive_store_private.platform_secrets + ALTER COLUMN database_id DROP DEFAULT; + +COMMIT; diff --git a/pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql b/pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql new file mode 100644 index 0000000..6aa1b65 --- /dev/null +++ b/pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql @@ -0,0 +1,11 @@ +-- Verify: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat +-- made with <3 @ constructive.io + +BEGIN; + +SELECT 1 FROM pg_catalog.pg_indexes +WHERE schemaname = 'constructive_store_private' + AND tablename = 'platform_secrets' + AND indexname = 'platform_secrets_namespace_id_name_idx'; + +ROLLBACK; From 6353e5a2ddc0813bdc6444f41928d60c74e6476a Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 8 Jun 2026 21:21:24 +0000 Subject: [PATCH 2/3] refactor: move standalone compat patch to its own pgpm package Hand-written SQL must live in a separate package from generated code so re-slicing never clobbers it. Moved the platform_secrets compat patch (DEFAULT database_id + unique index) from constructive-infra-seed into the new pgpm/standalone-patches/ package. --- pgpm/constructive-infra-seed/pgpm.plan | 1 - .../deploy/platform_secrets_compat.sql} | 2 +- pgpm/standalone-patches/pgpm.plan | 5 +++++ .../revert/platform_secrets_compat.sql} | 2 +- pgpm/standalone-patches/standalone-patches.control | 7 +++++++ .../verify/platform_secrets_compat.sql} | 2 +- scripts/setup-platform-db.sh | 4 ++++ scripts/up.sh | 11 +++++++++++ 8 files changed, 30 insertions(+), 4 deletions(-) rename pgpm/{constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql => standalone-patches/deploy/platform_secrets_compat.sql} (93%) create mode 100644 pgpm/standalone-patches/pgpm.plan rename pgpm/{constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql => standalone-patches/revert/platform_secrets_compat.sql} (71%) create mode 100644 pgpm/standalone-patches/standalone-patches.control rename pgpm/{constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql => standalone-patches/verify/platform_secrets_compat.sql} (70%) diff --git a/pgpm/constructive-infra-seed/pgpm.plan b/pgpm/constructive-infra-seed/pgpm.plan index c5e05a9..7ec9bd3 100644 --- a/pgpm/constructive-infra-seed/pgpm.plan +++ b/pgpm/constructive-infra-seed/pgpm.plan @@ -5,4 +5,3 @@ schemas/constructive_infra_public/partitions/create_default_partitions 2017-08-11T08:11:51Z Constructive # create default partitions for range-partitioned tables schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace [schemas/constructive_infra_public/partitions/create_default_partitions] 2017-08-11T08:11:51Z Constructive # seed default platform namespace schemas/constructive_infra_public/tables/platform_function_definitions/fixtures/seed_built_in_functions [schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2017-08-11T08:11:51Z Constructive # seed built-in platform functions with required_secrets and namespace -schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat [schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2017-08-11T08:11:51Z Constructive # standalone compat: DEFAULT database_id from JWT + unique index for ON CONFLICT diff --git a/pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql b/pgpm/standalone-patches/deploy/platform_secrets_compat.sql similarity index 93% rename from pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql rename to pgpm/standalone-patches/deploy/platform_secrets_compat.sql index 18b706b..ba4dbaf 100644 --- a/pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql +++ b/pgpm/standalone-patches/deploy/platform_secrets_compat.sql @@ -1,4 +1,4 @@ --- Deploy: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat +-- Deploy: platform_secrets_compat -- made with <3 @ constructive.io -- -- Standalone compatibility patch for platform_secrets. diff --git a/pgpm/standalone-patches/pgpm.plan b/pgpm/standalone-patches/pgpm.plan new file mode 100644 index 0000000..2de62fe --- /dev/null +++ b/pgpm/standalone-patches/pgpm.plan @@ -0,0 +1,5 @@ +%syntax-version=1.0.0 +%project=standalone-patches +%uri=standalone-patches + +platform_secrets_compat [constructive-infra-seed:schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2026-06-08T00:00:00Z Constructive # standalone compat: DEFAULT database_id from JWT + unique index for ON CONFLICT diff --git a/pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql b/pgpm/standalone-patches/revert/platform_secrets_compat.sql similarity index 71% rename from pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql rename to pgpm/standalone-patches/revert/platform_secrets_compat.sql index 80f73e4..29333b7 100644 --- a/pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql +++ b/pgpm/standalone-patches/revert/platform_secrets_compat.sql @@ -1,4 +1,4 @@ --- Revert: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat +-- Revert: platform_secrets_compat -- made with <3 @ constructive.io BEGIN; diff --git a/pgpm/standalone-patches/standalone-patches.control b/pgpm/standalone-patches/standalone-patches.control new file mode 100644 index 0000000..3bb2dea --- /dev/null +++ b/pgpm/standalone-patches/standalone-patches.control @@ -0,0 +1,7 @@ +# standalone-patches extension +comment = 'Hand-written patches for standalone mode compatibility' +default_version = '0.0.1' +module_pathname = '$libdir/standalone-patches' +requires = 'constructive-infra-seed' +relocatable = false +superuser = false diff --git a/pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql b/pgpm/standalone-patches/verify/platform_secrets_compat.sql similarity index 70% rename from pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql rename to pgpm/standalone-patches/verify/platform_secrets_compat.sql index 6aa1b65..4593601 100644 --- a/pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql +++ b/pgpm/standalone-patches/verify/platform_secrets_compat.sql @@ -1,4 +1,4 @@ --- Verify: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat +-- Verify: platform_secrets_compat -- made with <3 @ constructive.io BEGIN; diff --git a/scripts/setup-platform-db.sh b/scripts/setup-platform-db.sh index 029283d..096ae45 100755 --- a/scripts/setup-platform-db.sh +++ b/scripts/setup-platform-db.sh @@ -40,6 +40,10 @@ pgpm deploy --yes --database "$DB_NAME" --package constructive-infra echo "→ Deploying constructive-infra-seed..." pgpm deploy --yes --database "$DB_NAME" --package constructive-infra-seed +# --- Deploy standalone-patches (hand-written compat patches) --- +echo "→ Deploying standalone-patches..." +pgpm deploy --yes --database "$DB_NAME" --package standalone-patches + # --- Verify --- echo "" echo "→ Verifying..." diff --git a/scripts/up.sh b/scripts/up.sh index 8314863..92e808e 100755 --- a/scripts/up.sh +++ b/scripts/up.sh @@ -158,6 +158,17 @@ else fi rm -f "$DEPLOY_LOG" +# Deploy standalone-patches (hand-written compat patches, separate from generated code) +PATCH_RC=0 +pgpm deploy --yes --database "$DB_NAME" --package standalone-patches > "$DEPLOY_LOG" 2>&1 || PATCH_RC=$? +if [ $PATCH_RC -eq 0 ]; then + ok "standalone-patches deployed" +else + fail "standalone-patches — deploy output:" + sed 's/^/ /' "$DEPLOY_LOG" +fi +rm -f "$DEPLOY_LOG" + cd "$ROOT_DIR" # ─── Step 6: Start MinIO ──────────────────────────────────────────────────── From 0d5f0953221348ef8db6bfdc0e489c597f604da5 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 8 Jun 2026 21:28:35 +0000 Subject: [PATCH 3/3] refactor: combine standalone compat patch into constructive-infra-seed The seed package is already hand-written, so no need for a separate package. Dropped pgpm/standalone-patches/ and moved the patch back into constructive-infra-seed alongside the other seed migrations. --- .../platform_secrets/fixtures/standalone_compat.sql} | 2 +- pgpm/constructive-infra-seed/pgpm.plan | 1 + .../platform_secrets/fixtures/standalone_compat.sql} | 2 +- .../platform_secrets/fixtures/standalone_compat.sql} | 2 +- pgpm/standalone-patches/pgpm.plan | 5 ----- pgpm/standalone-patches/standalone-patches.control | 7 ------- scripts/setup-platform-db.sh | 6 +----- scripts/up.sh | 11 ----------- 8 files changed, 5 insertions(+), 31 deletions(-) rename pgpm/{standalone-patches/deploy/platform_secrets_compat.sql => constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql} (93%) rename pgpm/{standalone-patches/revert/platform_secrets_compat.sql => constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql} (71%) rename pgpm/{standalone-patches/verify/platform_secrets_compat.sql => constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql} (70%) delete mode 100644 pgpm/standalone-patches/pgpm.plan delete mode 100644 pgpm/standalone-patches/standalone-patches.control diff --git a/pgpm/standalone-patches/deploy/platform_secrets_compat.sql b/pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql similarity index 93% rename from pgpm/standalone-patches/deploy/platform_secrets_compat.sql rename to pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql index ba4dbaf..18b706b 100644 --- a/pgpm/standalone-patches/deploy/platform_secrets_compat.sql +++ b/pgpm/constructive-infra-seed/deploy/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql @@ -1,4 +1,4 @@ --- Deploy: platform_secrets_compat +-- Deploy: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat -- made with <3 @ constructive.io -- -- Standalone compatibility patch for platform_secrets. diff --git a/pgpm/constructive-infra-seed/pgpm.plan b/pgpm/constructive-infra-seed/pgpm.plan index 7ec9bd3..c5e05a9 100644 --- a/pgpm/constructive-infra-seed/pgpm.plan +++ b/pgpm/constructive-infra-seed/pgpm.plan @@ -5,3 +5,4 @@ schemas/constructive_infra_public/partitions/create_default_partitions 2017-08-11T08:11:51Z Constructive # create default partitions for range-partitioned tables schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace [schemas/constructive_infra_public/partitions/create_default_partitions] 2017-08-11T08:11:51Z Constructive # seed default platform namespace schemas/constructive_infra_public/tables/platform_function_definitions/fixtures/seed_built_in_functions [schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2017-08-11T08:11:51Z Constructive # seed built-in platform functions with required_secrets and namespace +schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat [schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2017-08-11T08:11:51Z Constructive # standalone compat: DEFAULT database_id from JWT + unique index for ON CONFLICT diff --git a/pgpm/standalone-patches/revert/platform_secrets_compat.sql b/pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql similarity index 71% rename from pgpm/standalone-patches/revert/platform_secrets_compat.sql rename to pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql index 29333b7..80f73e4 100644 --- a/pgpm/standalone-patches/revert/platform_secrets_compat.sql +++ b/pgpm/constructive-infra-seed/revert/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql @@ -1,4 +1,4 @@ --- Revert: platform_secrets_compat +-- Revert: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat -- made with <3 @ constructive.io BEGIN; diff --git a/pgpm/standalone-patches/verify/platform_secrets_compat.sql b/pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql similarity index 70% rename from pgpm/standalone-patches/verify/platform_secrets_compat.sql rename to pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql index 4593601..6aa1b65 100644 --- a/pgpm/standalone-patches/verify/platform_secrets_compat.sql +++ b/pgpm/constructive-infra-seed/verify/schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat.sql @@ -1,4 +1,4 @@ --- Verify: platform_secrets_compat +-- Verify: schemas/constructive_store_private/tables/platform_secrets/fixtures/standalone_compat -- made with <3 @ constructive.io BEGIN; diff --git a/pgpm/standalone-patches/pgpm.plan b/pgpm/standalone-patches/pgpm.plan deleted file mode 100644 index 2de62fe..0000000 --- a/pgpm/standalone-patches/pgpm.plan +++ /dev/null @@ -1,5 +0,0 @@ -%syntax-version=1.0.0 -%project=standalone-patches -%uri=standalone-patches - -platform_secrets_compat [constructive-infra-seed:schemas/constructive_infra_public/tables/platform_namespaces/fixtures/seed_default_namespace] 2026-06-08T00:00:00Z Constructive # standalone compat: DEFAULT database_id from JWT + unique index for ON CONFLICT diff --git a/pgpm/standalone-patches/standalone-patches.control b/pgpm/standalone-patches/standalone-patches.control deleted file mode 100644 index 3bb2dea..0000000 --- a/pgpm/standalone-patches/standalone-patches.control +++ /dev/null @@ -1,7 +0,0 @@ -# standalone-patches extension -comment = 'Hand-written patches for standalone mode compatibility' -default_version = '0.0.1' -module_pathname = '$libdir/standalone-patches' -requires = 'constructive-infra-seed' -relocatable = false -superuser = false diff --git a/scripts/setup-platform-db.sh b/scripts/setup-platform-db.sh index 096ae45..0141e23 100755 --- a/scripts/setup-platform-db.sh +++ b/scripts/setup-platform-db.sh @@ -36,14 +36,10 @@ echo "→ Deploying constructive-infra..." cd "$ROOT_DIR/pgpm" pgpm deploy --yes --database "$DB_NAME" --package constructive-infra -# --- Deploy constructive-infra-seed (built-in function definitions) --- +# --- Deploy constructive-infra-seed (built-in function definitions + compat patches) --- echo "→ Deploying constructive-infra-seed..." pgpm deploy --yes --database "$DB_NAME" --package constructive-infra-seed -# --- Deploy standalone-patches (hand-written compat patches) --- -echo "→ Deploying standalone-patches..." -pgpm deploy --yes --database "$DB_NAME" --package standalone-patches - # --- Verify --- echo "" echo "→ Verifying..." diff --git a/scripts/up.sh b/scripts/up.sh index 92e808e..8314863 100755 --- a/scripts/up.sh +++ b/scripts/up.sh @@ -158,17 +158,6 @@ else fi rm -f "$DEPLOY_LOG" -# Deploy standalone-patches (hand-written compat patches, separate from generated code) -PATCH_RC=0 -pgpm deploy --yes --database "$DB_NAME" --package standalone-patches > "$DEPLOY_LOG" 2>&1 || PATCH_RC=$? -if [ $PATCH_RC -eq 0 ]; then - ok "standalone-patches deployed" -else - fail "standalone-patches — deploy output:" - sed 's/^/ /' "$DEPLOY_LOG" -fi -rm -f "$DEPLOY_LOG" - cd "$ROOT_DIR" # ─── Step 6: Start MinIO ────────────────────────────────────────────────────