From 6b7b24ab2de679f65d9b4a4317c4cb5c0ab74be8 Mon Sep 17 00:00:00 2001 From: zetazzz Date: Mon, 5 Jan 2026 18:17:41 +0700 Subject: [PATCH 1/2] comply schema and tables renaming --- __fixtures__/output/index.ts | 8 ++--- ...cts_private.ts => object_store_private.ts} | 0 .../{txs_public.ts => object_tree_public.ts} | 0 .../output/schemas/services_public.ts | 8 ++--- docker-compose.jobs.yml | 2 +- graphile/graphile-settings/README.md | 2 +- .../README.md | 6 ++-- .../src/index.ts | 2 +- graphql/env/README.md | 2 +- .../__snapshots__/merge.test.ts.snap | 5 +-- graphql/env/__tests__/merge.test.ts | 9 ++--- jobs/DEVELOPMENT_JOBS.md | 8 ++--- .../__snapshots__/export.test.ts.snap | 34 +++++++++++++----- packages/csv-to-pg/__tests__/export.test.ts | 8 ++--- .../core/__tests__/export/export-meta.test.ts | 2 +- .../projects/stage-workspace.test.ts | 32 ++++++++--------- pgpm/core/src/export/export-migrations.ts | 35 ++++++++++--------- pgpm/core/src/modules/modules.ts | 1 + plan.md | 20 +++++------ postgres/pg-codegen/src/index.ts | 4 +-- 20 files changed, 105 insertions(+), 83 deletions(-) rename __fixtures__/output/schemas/{objects_private.ts => object_store_private.ts} (100%) rename __fixtures__/output/schemas/{txs_public.ts => object_tree_public.ts} (100%) diff --git a/__fixtures__/output/index.ts b/__fixtures__/output/index.ts index a88792338..d4e9e6e27 100644 --- a/__fixtures__/output/index.ts +++ b/__fixtures__/output/index.ts @@ -6,10 +6,10 @@ import * as sqitch from "./schemas/sqitch"; export { sqitch }; import * as inflection from "./schemas/inflection"; export { inflection }; -import * as objects_private from "./schemas/objects_private"; -export { objects_private }; -import * as txs_public from "./schemas/txs_public"; -export { txs_public }; +import * as object_store_private from "./schemas/object_store_private"; +export { object_store_private }; +import * as object_tree_public from "./schemas/object_tree_public"; +export { object_tree_public }; import * as migrations_public from "./schemas/migrations_public"; export { migrations_public }; import * as db_migrate from "./schemas/db_migrate"; diff --git a/__fixtures__/output/schemas/objects_private.ts b/__fixtures__/output/schemas/object_store_private.ts similarity index 100% rename from __fixtures__/output/schemas/objects_private.ts rename to __fixtures__/output/schemas/object_store_private.ts diff --git a/__fixtures__/output/schemas/txs_public.ts b/__fixtures__/output/schemas/object_tree_public.ts similarity index 100% rename from __fixtures__/output/schemas/txs_public.ts rename to __fixtures__/output/schemas/object_tree_public.ts diff --git a/__fixtures__/output/schemas/services_public.ts b/__fixtures__/output/schemas/services_public.ts index 713b5c0b2..b377608df 100644 --- a/__fixtures__/output/schemas/services_public.ts +++ b/__fixtures__/output/schemas/services_public.ts @@ -605,7 +605,7 @@ export interface memberships_module { default_limits_table_id: UUID; permissions_table_id: UUID; default_permissions_table_id: UUID; - acl_table_id: UUID; + sprt_table_id: UUID; admin_grants_table_id: UUID; admin_grants_table_name: string; owner_grants_table_id: UUID; @@ -638,7 +638,7 @@ export class memberships_module implements memberships_module { default_limits_table_id: UUID; permissions_table_id: UUID; default_permissions_table_id: UUID; - acl_table_id: UUID; + sprt_table_id: UUID; admin_grants_table_id: UUID; admin_grants_table_name: string; owner_grants_table_id: UUID; @@ -670,7 +670,7 @@ export class memberships_module implements memberships_module { this.default_limits_table_id = data.default_limits_table_id; this.permissions_table_id = data.permissions_table_id; this.default_permissions_table_id = data.default_permissions_table_id; - this.acl_table_id = data.acl_table_id; + this.sprt_table_id = data.sprt_table_id; this.admin_grants_table_id = data.admin_grants_table_id; this.admin_grants_table_name = data.admin_grants_table_name; this.owner_grants_table_id = data.owner_grants_table_id; @@ -1081,4 +1081,4 @@ export class uuid_module implements uuid_module { this.uuid_function = data.uuid_function; this.uuid_seed = data.uuid_seed; } -} \ No newline at end of file +} diff --git a/docker-compose.jobs.yml b/docker-compose.jobs.yml index d900f0ba3..e5dbc2106 100644 --- a/docker-compose.jobs.yml +++ b/docker-compose.jobs.yml @@ -25,7 +25,7 @@ services: PGDATABASE: launchql # API meta configuration (static mode for dev) API_ENABLE_META: "true" - API_EXPOSED_SCHEMAS: "collections_public,meta_public" + API_EXPOSED_SCHEMAS: "metaschema_public,services_public" API_ANON_ROLE: "administrator" API_ROLE_NAME: "administrator" API_DEFAULT_DATABASE_ID: "dbe" diff --git a/graphile/graphile-settings/README.md b/graphile/graphile-settings/README.md index cb7869ddf..e3b82db05 100644 --- a/graphile/graphile-settings/README.md +++ b/graphile/graphile-settings/README.md @@ -57,7 +57,7 @@ const settings = getGraphileSettings({ }, graphile: { schema: ['app_public'], - metaSchemas: ['meta_public'], + metaSchemas: ['metaschema_public', 'services_public', 'metaschema_modules_public'], }, features: { postgis: true, diff --git a/graphile/graphile-sql-expression-validator/README.md b/graphile/graphile-sql-expression-validator/README.md index ffeb4f78e..cb1276d59 100644 --- a/graphile/graphile-sql-expression-validator/README.md +++ b/graphile/graphile-sql-expression-validator/README.md @@ -15,7 +15,7 @@ npm install graphile-sql-expression-validator Tag columns that contain SQL expressions with `@sqlExpression`: ```sql -COMMENT ON COLUMN collections_public.field.default_value IS E'@sqlExpression'; +COMMENT ON COLUMN metaschema_public.field.default_value IS E'@sqlExpression'; ``` The plugin will automatically look for a companion `*_ast` column (e.g., `default_value_ast`) to store the parsed AST. @@ -26,7 +26,7 @@ By default, the plugin looks for a companion column named `_ast`. You ca ```sql -- Use a custom AST column name -COMMENT ON COLUMN collections_public.field.default_value IS E'@sqlExpression\n@rawSqlAstField my_custom_ast_column'; +COMMENT ON COLUMN metaschema_public.field.default_value IS E'@sqlExpression\n@rawSqlAstField my_custom_ast_column'; ``` If `@rawSqlAstField` points to a non-existent column, the plugin will throw an error. If not specified, it falls back to the `_ast` convention (and silently skips AST storage if that column doesn't exist). @@ -47,7 +47,7 @@ const postgraphileOptions = { // Optional: Maximum expression length (default: 10000) maxExpressionLength: 5000, // Optional: Auto-allow schemas owned by the current database - // Queries: SELECT schema_name FROM collections_public.schema + // Queries: SELECT schema_name FROM metaschema_public.schema // WHERE database_id = jwt_private.current_database_id() allowOwnedSchemas: true, // Optional: Custom hook for dynamic schema resolution diff --git a/graphile/graphile-sql-expression-validator/src/index.ts b/graphile/graphile-sql-expression-validator/src/index.ts index cad25785f..c3f0db934 100644 --- a/graphile/graphile-sql-expression-validator/src/index.ts +++ b/graphile/graphile-sql-expression-validator/src/index.ts @@ -275,7 +275,7 @@ async function resolveEffectiveOptions( if (!ownedSchemas) { try { const result = await gqlContext.pgClient.query( - `SELECT schema_name FROM collections_public.schema WHERE database_id = jwt_private.current_database_id()` + `SELECT schema_name FROM metaschema_public.schema WHERE database_id = jwt_private.current_database_id()` ); ownedSchemas = result.rows.map((row: { schema_name: string }) => row.schema_name); gqlContext[OWNED_SCHEMAS_CACHE_KEY] = ownedSchemas; diff --git a/graphql/env/README.md b/graphql/env/README.md index fcca3a71a..9e4f89c22 100644 --- a/graphql/env/README.md +++ b/graphql/env/README.md @@ -65,7 +65,7 @@ GraphQL defaults are provided by `@constructive-io/graphql-types`: roleName: 'administrator', defaultDatabaseId: 'hard-coded', isPublic: true, - metaSchemas: ['collections_public', 'meta_public'] + metaSchemas: ['services_public', 'metaschema_public', 'metaschema_modules_public'] } } ``` diff --git a/graphql/env/__tests__/__snapshots__/merge.test.ts.snap b/graphql/env/__tests__/__snapshots__/merge.test.ts.snap index 25b7dd53a..e95e27738 100644 --- a/graphql/env/__tests__/__snapshots__/merge.test.ts.snap +++ b/graphql/env/__tests__/__snapshots__/merge.test.ts.snap @@ -13,8 +13,9 @@ exports[`getEnvOptions merges pgpm defaults, graphql defaults, config, env, and "isPublic": true, "metaSchemas": [ "config_meta", - "collections_public", - "meta_public", + "services_public", + "metaschema_public", + "metaschema_modules_public", "env_meta1", "env_meta2", ], diff --git a/graphql/env/__tests__/merge.test.ts b/graphql/env/__tests__/merge.test.ts index d1edcd7e2..1fa1786e8 100644 --- a/graphql/env/__tests__/merge.test.ts +++ b/graphql/env/__tests__/merge.test.ts @@ -92,14 +92,14 @@ describe('getEnvOptions', () => { }, api: { exposedSchemas: ['public', 'shared'], - metaSchemas: ['collections_public', 'meta_public', 'config_meta'] + metaSchemas: ['metaschema_public', 'services_public', 'config_meta'] } }); const testEnv: NodeJS.ProcessEnv = { GRAPHILE_SCHEMA: 'shared_schema,env_schema', API_EXPOSED_SCHEMAS: 'shared,env_schema', - API_META_SCHEMAS: 'meta_public,env_meta' + API_META_SCHEMAS: 'services_public,env_meta' }; const result = getEnvOptions( @@ -129,9 +129,10 @@ describe('getEnvOptions', () => { 'override_schema' ]); expect(result.api?.metaSchemas).toEqual([ - 'collections_public', - 'meta_public', + 'metaschema_public', + 'services_public', 'config_meta', + 'metaschema_modules_public', 'env_meta', 'override_meta' ]); diff --git a/jobs/DEVELOPMENT_JOBS.md b/jobs/DEVELOPMENT_JOBS.md index 66e8b628f..bde1801fc 100644 --- a/jobs/DEVELOPMENT_JOBS.md +++ b/jobs/DEVELOPMENT_JOBS.md @@ -76,7 +76,7 @@ From the `constructive-db/` directory (with `pgenv` applied): ```sh pgpm deploy --yes --database "$PGDATABASE" --package app-svc-local - pgpm deploy --yes --database "$PGDATABASE" --package db-meta + pgpm deploy --yes --database "$PGDATABASE" --package metaschema pgpm deploy --yes --database "$PGDATABASE" --package pgpm-database-jobs ``` @@ -126,7 +126,7 @@ In dry-run mode: ## 5. Ensure GraphQL host routing works for `send-email-link` -Constructive selects the API by the HTTP `Host` header using rows in `meta_public.domains`. +Constructive selects the API by the HTTP `Host` header using rows in `services_public.domains`. For local development, `app-svc-local` seeds `admin.localhost` as the admin API domain. `docker-compose.jobs.yml` adds a Docker network alias so other containers can resolve `admin.localhost` to the `constructive-server` container, and `send-email-link` uses: @@ -152,7 +152,7 @@ With the jobs stack running, you can enqueue a test job from your host into the First, grab a real `database_id` (required by `send-email-link`, optional for `simple-email`): ```sh -DBID="$(docker exec -i postgres psql -U postgres -d launchql -Atc 'SELECT id FROM collections_public.database ORDER BY created_at LIMIT 1;')" +DBID="$(docker exec -i postgres psql -U postgres -d launchql -Atc 'SELECT id FROM metaschema_public.database ORDER BY created_at LIMIT 1;')" echo "$DBID" ``` @@ -179,7 +179,7 @@ You should then see the job picked up by `knative-job-service` and the email pay `send-email-link` queries GraphQL for site/database metadata, so it requires: -- The app/meta packages deployed in step 3 (`app-svc-local`, `db-meta`) +- The app/meta packages deployed in step 3 (`app-svc-local`, `metaschema-schema`, `services`, `metaschema-modules`) - A real `database_id` (use `$DBID` above) - A GraphQL hostname that matches a seeded domain route (step 5) - For localhost development, the site/domain metadata usually resolves to `localhost`. diff --git a/packages/csv-to-pg/__tests__/__snapshots__/export.test.ts.snap b/packages/csv-to-pg/__tests__/__snapshots__/export.test.ts.snap index b18eca9b7..364bfd12a 100644 --- a/packages/csv-to-pg/__tests__/__snapshots__/export.test.ts.snap +++ b/packages/csv-to-pg/__tests__/__snapshots__/export.test.ts.snap @@ -1,41 +1,59 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`test case arrays 1`] = ` -"INSERT INTO collections_public.field ( +"INSERT INTO metaschema_public.field ( id, schemas ) VALUES - ('450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', '{a,b}');" +( + '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', + '{a,b}' +);" `; exports[`test case image/attachment 1`] = ` -"INSERT INTO collections_public.field ( +"INSERT INTO metaschema_public.field ( id, name, image, upload ) VALUES - ('450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', 'name here', '{"url":"http://path/to/image.jpg"}', '{"url":"http://path/to/image.jpg"}');" +( + '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', + 'name here', + '{"url":"http://path/to/image.jpg"}', + '{"url":"http://path/to/image.jpg"}' +);" `; exports[`test case jsonb/json 1`] = ` -"INSERT INTO collections_public.field ( +"INSERT INTO metaschema_public.field ( id, name, data ) VALUES - ('450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', 'name here', '{"a":1}');" +( + '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', + 'name here', + '{"a":1}' +);" `; exports[`test case test case 1`] = `Promise {}`; exports[`test case test case parser 1`] = ` -"INSERT INTO collections_public.field ( +"INSERT INTO metaschema_public.field ( id, database_id, table_id, name, description ) VALUES - ('450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', 'name here', 'description');" +( + '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', + '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', + '450e3b3b-b68d-4abc-990c-65cb8a1dcdb4', + 'name here', + 'description' +);" `; diff --git a/packages/csv-to-pg/__tests__/export.test.ts b/packages/csv-to-pg/__tests__/export.test.ts index ab7912d34..29a0031b1 100644 --- a/packages/csv-to-pg/__tests__/export.test.ts +++ b/packages/csv-to-pg/__tests__/export.test.ts @@ -9,7 +9,7 @@ import { Parser } from '../src/parser'; const testCase = resolve(__dirname + '/../__fixtures__/test-case.csv'); const config = { - schema: 'collections_public', + schema: 'metaschema_public', singleStmts: true, table: 'field', headers: [ @@ -76,7 +76,7 @@ it('test case parser', async () => { it('jsonb/json', async () => { const parser = new Parser({ - schema: 'collections_public', + schema: 'metaschema_public', singleStmts: true, table: 'field', fields: { @@ -101,7 +101,7 @@ it('jsonb/json', async () => { it('image/attachment', async () => { const parser = new Parser({ - schema: 'collections_public', + schema: 'metaschema_public', singleStmts: true, table: 'field', fields: { @@ -130,7 +130,7 @@ it('image/attachment', async () => { it('arrays', async () => { const parser = new Parser({ - schema: 'collections_public', + schema: 'metaschema_public', singleStmts: true, table: 'field', fields: { diff --git a/pgpm/core/__tests__/export/export-meta.test.ts b/pgpm/core/__tests__/export/export-meta.test.ts index 0eb16fecb..5126a732f 100644 --- a/pgpm/core/__tests__/export/export-meta.test.ts +++ b/pgpm/core/__tests__/export/export-meta.test.ts @@ -155,7 +155,7 @@ describe('Export Meta Config Drift Detection', () => { // BUG DOCUMENTATION: // In export-meta.ts, line 26, the config defines: // table: 'database_extensions' (plural) - // But the actual table in db-meta-schema is: + // But the actual table in metaschema-schema is: // metaschema_public.database_extension (singular) // // This causes the Parser to generate INSERT statements with the wrong table name, diff --git a/pgpm/core/__tests__/projects/stage-workspace.test.ts b/pgpm/core/__tests__/projects/stage-workspace.test.ts index 37f287bb3..3cb970c5d 100644 --- a/pgpm/core/__tests__/projects/stage-workspace.test.ts +++ b/pgpm/core/__tests__/projects/stage-workspace.test.ts @@ -33,7 +33,7 @@ describe('Staging Fixture Tests', () => { const modules = await project.getModules(); expect(Array.isArray(modules)).toBe(true); expect(modules.length).toBeGreaterThan(0); - + const moduleNames = modules.map(m => m.getModuleName()); expect(moduleNames).toContain('unique-names'); expect(moduleNames.some(name => name.includes('pgpm-uuid'))).toBe(true); @@ -44,7 +44,7 @@ describe('Staging Fixture Tests', () => { it('returns available modules from both extensions and packages', async () => { const cwd = fixture.getFixturePath(); const project = new PgpmPackage(cwd); - + const availableModules = await project.getAvailableModules(); expect(Array.isArray(availableModules)).toBe(true); expect(availableModules.length).toBeGreaterThan(0); @@ -66,7 +66,7 @@ describe('Staging Fixture Tests', () => { expect(moduleNames.some(name => name.includes('pgpm-uuid'))).toBe(true); expect(moduleNames.some(name => name.includes('pgpm-base32'))).toBe(true); - expect(moduleNames.some(name => name.includes('db-meta'))).toBe(true); + expect(moduleNames.some(name => name.includes('metaschema'))).toBe(true); modules.forEach(mod => { expect(mod.isInModule()).toBe(true); @@ -80,12 +80,12 @@ describe('Staging Fixture Tests', () => { const modules = await project.getModules(); const moduleMap = project.getModuleMap(); - + expect(Object.keys(moduleMap).length).toBeGreaterThan(0); - + expect(moduleMap['unique-names']).toBeDefined(); expect(moduleMap['unique-names'].path).toContain('packages/unique-names'); - + modules.forEach(mod => { const moduleName = mod.getModuleName(); const moduleInfo = moduleMap[moduleName]; @@ -120,7 +120,7 @@ describe('Staging Fixture Tests', () => { expect(project.getContext()).toBe(PackageContext.ModuleInsideWorkspace); expect(project.isInModule()).toBe(true); - + const name = project.getModuleName(); expect(name).toBe('pgpm-uuid'); }); @@ -159,7 +159,7 @@ describe('Staging Fixture Tests', () => { it('gets dependency changes with versions for internal modules', async () => { const cwd = fixture.getFixturePath(); const project = new PgpmPackage(cwd); - + const result = await project.getModuleDependencyChanges('unique-names'); expect(result).toHaveProperty('native'); expect(result).toHaveProperty('modules'); @@ -186,7 +186,7 @@ describe('Staging Fixture Tests', () => { const uuidDeps = project.getModuleDependencies('pgpm-uuid'); expect(uuidDeps.modules).toBeDefined(); expect(Array.isArray(uuidDeps.modules)).toBe(true); - + const result = await project.getModuleDependencyChanges('pgpm-uuid'); expect(result.modules).toBeDefined(); expect(Array.isArray(result.modules)).toBe(true); @@ -197,12 +197,12 @@ describe('Staging Fixture Tests', () => { const project = new PgpmPackage(cwd); const result = await project.getModuleDependencyChanges('unique-names'); - + expect(result.modules.length).toBeGreaterThan(0); - + const dependencyNames = result.modules.map(dep => dep.name); expect(dependencyNames.some(name => name.includes('pgpm-defaults'))).toBe(true); - + result.modules.forEach(dep => { expect(dep).toHaveProperty('name'); expect(dep).toHaveProperty('latest'); @@ -218,13 +218,13 @@ describe('Staging Fixture Tests', () => { const project = new PgpmPackage(cwd); const { native, modules: deps } = project.getModuleDependencies('unique-names'); - + const dependencyChanges = await project.getModuleDependencyChanges('unique-names'); const defaultsDep = dependencyChanges.modules.find(dep => dep.name.includes('pgpm-defaults') ); - + if (defaultsDep) { expect(defaultsDep.name).toBeTruthy(); expect(defaultsDep.latest).toBeTruthy(); @@ -238,9 +238,9 @@ describe('Staging Fixture Tests', () => { const moduleMap = project.getModuleMap(); const moduleNames = Object.keys(moduleMap); - + expect(moduleNames.length).toBeGreaterThan(1); - + for (const moduleName of moduleNames) { const deps = project.getModuleDependencies(moduleName); expect(deps).toHaveProperty('native'); diff --git a/pgpm/core/src/export/export-migrations.ts b/pgpm/core/src/export/export-migrations.ts index 659d13cff..f9b7b1fa8 100644 --- a/pgpm/core/src/export/export-migrations.ts +++ b/pgpm/core/src/export/export-migrations.ts @@ -42,7 +42,8 @@ const DB_REQUIRED_EXTENSIONS = [ const SERVICE_REQUIRED_EXTENSIONS = [ 'plpgsql', 'metaschema-schema', - 'metaschema-modules' + 'metaschema-modules', + 'services' ] as const; /** @@ -64,10 +65,10 @@ interface MissingModulesResult { /** * Checks which pgpm modules from the extensions list are missing from the workspace * and prompts the user if they want to install them. - * + * * This function only does detection and prompting - it does NOT install. * Use installMissingModules() after the module is created to do the actual installation. - * + * * @param project - The PgpmPackage instance (only needs workspace context) * @param extensions - List of extension names (control file names) * @param prompter - Optional prompter for interactive confirmation @@ -81,14 +82,14 @@ const detectMissingModules = async ( // Use workspace-level check - doesn't require being inside a module const installed = project.getWorkspaceInstalledModules(); const missingModules = getMissingInstallableModules(extensions, installed); - + if (missingModules.length === 0) { return { missingModules: [], shouldInstall: false }; } - + const missingNames = missingModules.map(m => m.npmName); console.log(`\nMissing pgpm modules detected: ${missingNames.join(', ')}`); - + if (prompter) { const { install } = await prompter.prompt({}, [ { @@ -98,17 +99,17 @@ const detectMissingModules = async ( default: true } ]); - + return { missingModules, shouldInstall: install }; } - + return { missingModules, shouldInstall: false }; }; /** * Installs missing modules into a specific module directory. * Must be called after the module has been created. - * + * * @param moduleDir - The directory of the module to install into * @param missingModules - Array of missing modules to install */ @@ -119,14 +120,14 @@ const installMissingModules = async ( if (missingModules.length === 0) { return; } - + const missingNames = missingModules.map(m => m.npmName); console.log('Installing missing modules...'); - + // Create a new PgpmPackage instance pointing to the module directory const moduleProject = new PgpmPackage(moduleDir); await moduleProject.installModules(...missingNames); - + console.log('Modules installed successfully.'); }; @@ -150,7 +151,7 @@ interface ExportMigrationsToDiskOptions { username?: string; /** Output directory for service/meta module. Defaults to outdir if not provided. */ serviceOutdir?: string; - /** + /** * Skip schema name replacement for infrastructure schemas. * When true, schema names like metaschema_public, services_public will not be renamed. * Useful for self-referential introspection where you want to apply policies to real schemas. @@ -180,7 +181,7 @@ interface ExportOptions { username?: string; /** Output directory for service/meta module. Defaults to outdir if not provided. */ serviceOutdir?: string; - /** + /** * Skip schema name replacement for infrastructure schemas. * When true, schema names like metaschema_public, services_public will not be renamed. * Useful for self-referential introspection where you want to apply policies to real schemas. @@ -348,7 +349,7 @@ GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public to public; DO $LQLMIGRATION$ DECLARE BEGIN - + EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), 'app_user'); EXECUTE format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), 'app_admin'); @@ -457,7 +458,7 @@ interface ReplacerResult { /** * Creates a PGPM package directory or resets the deploy/revert/verify directories if it exists. * If the module already exists and a prompter is provided, prompts the user for confirmation. - * + * * @returns The absolute path to the created/prepared module directory */ const preparePackage = async ({ @@ -479,7 +480,7 @@ const preparePackage = async ({ const plan = glob(path.join(pgpmDir, 'pgpm.plan')); if (!plan.length) { const { fullName, email } = parseAuthor(author); - + await project.initModule({ name, description, diff --git a/pgpm/core/src/modules/modules.ts b/pgpm/core/src/modules/modules.ts index eeeac1207..0a266f314 100644 --- a/pgpm/core/src/modules/modules.ts +++ b/pgpm/core/src/modules/modules.ts @@ -13,6 +13,7 @@ export const PGPM_MODULE_MAP: Record = { 'pgpm-database-jobs': '@pgpm/database-jobs', 'metaschema-modules': '@pgpm/metaschema-modules', 'metaschema-schema': '@pgpm/metaschema-schema', + 'services': '@pgpm/services', 'pgpm-inflection': '@pgpm/inflection', 'pgpm-jwt-claims': '@pgpm/jwt-claims', 'pgpm-stamps': '@pgpm/stamps', diff --git a/plan.md b/plan.md index 33f837ba1..2c7ac233d 100644 --- a/plan.md +++ b/plan.md @@ -2,7 +2,7 @@ ## Problem Statement -The `pgpm export` command's `meta_public` schema export is broken. The export functionality in `pgpm/core/src/export/export-meta.ts` has several issues that cause the generated SQL to fail when replayed. +The `pgpm export` command's `services_public` schema export is broken. The export functionality in `pgpm/core/src/export/export-meta.ts` has several issues that cause the generated SQL to fail when replayed. ## Issues Identified @@ -11,7 +11,7 @@ The `pgpm export` command's `meta_public` schema export is broken. The export fu 1. **Table name mismatch (`database_extension`)** - Location: `pgpm/core/src/export/export-meta.ts` line 26-27 - Config defines: `table: 'database_extensions'` (plural) - - Actual table: `collections_public.database_extension` (singular) + - Actual table: `metaschema_public.database_extension` (singular) - Impact: Generated INSERT statements target non-existent table 2. **Missing columns in `user_auth_module` config** @@ -28,7 +28,7 @@ The `pgpm export` command's `meta_public` schema export is broken. The export fu - Impact: Field data is never exported 4. **Missing `site_metadata` table** - - Table exists in `meta_public` schema but not in export config + - Table exists in `services_public` schema but not in export config - Impact: Site metadata is never exported ### Secondary Issues @@ -40,16 +40,16 @@ The `pgpm export` command's `meta_public` schema export is broken. The export fu - Impact: May fail in non-superuser environments 6. **Type mismatches** (may or may not cause issues depending on csv-to-pg handling) - - `meta_public.sites.favicon`: actual `attachment`, config says `upload` - - `meta_public.domains.subdomain/domain`: actual `hostname`, config says `text` - - `meta_public.api_modules.data`: actual `pg_catalog.json`, config says `jsonb` - - `meta_public.site_modules.data`: actual `pg_catalog.json`, config says `jsonb` + - `services_public.sites.favicon`: actual `attachment`, config says `upload` + - `services_public.domains.subdomain/domain`: actual `hostname`, config says `text` + - `services_public.api_modules.data`: actual `pg_catalog.json`, config says `jsonb` + - `services_public.site_modules.data`: actual `pg_catalog.json`, config says `jsonb` ## Proposed Solution ### Phase 1: Create Test Infrastructure -1. **Create a new test module** in `extensions/` directory +1. **Create a new test module** in `pgpm-modules/` directory - Name: `@pgpm/export-meta-test` or similar - Purpose: Test the export functionality with seed data @@ -102,13 +102,13 @@ extensions/@pgpm/export-meta-test/ ## Success Criteria 1. Export generates valid SQL that can be replayed -2. All tables in `meta_public` and `collections_public` are properly exported +2. All tables in `services_public` and `metaschema_public` are properly exported 3. FK constraints are respected (either via proper ordering or explicit handling) 4. Tests catch schema drift automatically 5. CI passes with new tests ## Questions to Resolve -1. Should this be a separate module or part of existing `db-meta-schema` tests? +1. Should this be a separate module or part of existing `metaschema-schema` tests? 2. Do we need to support non-superuser deployments (affects `session_replication_role` approach)? 3. Should we add the tests to `launchql-extensions` repo as well for parity? diff --git a/postgres/pg-codegen/src/index.ts b/postgres/pg-codegen/src/index.ts index 939016167..d783132e5 100644 --- a/postgres/pg-codegen/src/index.ts +++ b/postgres/pg-codegen/src/index.ts @@ -52,7 +52,7 @@ const writeGeneratedFiles = async ( pgLegacyFunctionsOnly: false, pgIgnoreRBAC: true, }, - namespacesToIntrospect: ['collections_public'], + namespacesToIntrospect: ['metaschema_public'], includeExtensions: false, }; @@ -83,4 +83,4 @@ const writeGeneratedFiles = async ( } catch (error) { log.error('Failed to fetch introspection rows or generate code:', error); } -})(); \ No newline at end of file +})(); From 98abca1f6e23239893ac19605b33febc4195b02f Mon Sep 17 00:00:00 2001 From: zetazzz Date: Mon, 5 Jan 2026 18:41:16 +0700 Subject: [PATCH 2/2] fix tests --- .../stage/extensions/@pgpm/metaschema-modules/Makefile | 4 ++-- .../@pgpm/metaschema-modules/db-meta-modules.control | 8 -------- .../@pgpm/metaschema-modules/metaschema-modules.control | 7 +++++++ .../stage/extensions/@pgpm/metaschema-modules/pgpm.plan | 4 ++-- ...modules--0.14.0.sql => metaschema-modules--0.14.0.sql} | 0 .../stage/extensions/@pgpm/metaschema-schema/Makefile | 4 ++-- .../{db-meta-schema.control => metaschema-schema.control} | 7 +++---- .../stage/extensions/@pgpm/metaschema-schema/pgpm.plan | 4 ++-- ...a-schema--0.14.0.sql => metaschema-schema--0.14.0.sql} | 0 9 files changed, 18 insertions(+), 20 deletions(-) delete mode 100644 __fixtures__/stage/extensions/@pgpm/metaschema-modules/db-meta-modules.control create mode 100644 __fixtures__/stage/extensions/@pgpm/metaschema-modules/metaschema-modules.control rename __fixtures__/stage/extensions/@pgpm/metaschema-modules/sql/{db-meta-modules--0.14.0.sql => metaschema-modules--0.14.0.sql} (100%) rename __fixtures__/stage/extensions/@pgpm/metaschema-schema/{db-meta-schema.control => metaschema-schema.control} (61%) rename __fixtures__/stage/extensions/@pgpm/metaschema-schema/sql/{db-meta-schema--0.14.0.sql => metaschema-schema--0.14.0.sql} (100%) diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/Makefile b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/Makefile index 04ec7e134..217794a6f 100644 --- a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/Makefile +++ b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/Makefile @@ -1,5 +1,5 @@ -EXTENSION = db-meta-modules -DATA = sql/db-meta-modules--0.14.0.sql +EXTENSION = metaschema-modules +DATA = sql/metaschema-modules--0.14.0.sql PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/db-meta-modules.control b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/db-meta-modules.control deleted file mode 100644 index 0ec58ee06..000000000 --- a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/db-meta-modules.control +++ /dev/null @@ -1,8 +0,0 @@ -# db-meta-modules extension -comment = 'db-meta-modules extension' -default_version = '0.14.0' -module_pathname = '$libdir/db-meta-modules' -requires = 'plpgsql,db-meta-schema,pgpm-verify' -relocatable = false -superuser = false - diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/metaschema-modules.control b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/metaschema-modules.control new file mode 100644 index 000000000..a2b057b63 --- /dev/null +++ b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/metaschema-modules.control @@ -0,0 +1,7 @@ +# metaschema-modules extension +comment = 'metaschema-modules extension' +default_version = '0.14.0' +module_pathname = '$libdir/metaschema-modules' +requires = 'plpgsql,metaschema-schema,pgpm-verify' +relocatable = false +superuser = false diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/pgpm.plan b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/pgpm.plan index 473c96f6a..bc046a705 100644 --- a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/pgpm.plan +++ b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/pgpm.plan @@ -1,6 +1,6 @@ %syntax-version=1.0.0 -%project=db-meta-modules -%uri=db-meta-modules +%project=metaschema-modules +%uri=metaschema-modules schemas/meta_private/schema [db-meta-schema:schemas/meta_public/tables/site_themes/table] 2017-08-11T08:11:51Z skitch # add schemas/meta_private/schema schemas/meta_public/schema 2017-08-11T08:11:51Z skitch # add schemas/meta_public/schema diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-modules/sql/db-meta-modules--0.14.0.sql b/__fixtures__/stage/extensions/@pgpm/metaschema-modules/sql/metaschema-modules--0.14.0.sql similarity index 100% rename from __fixtures__/stage/extensions/@pgpm/metaschema-modules/sql/db-meta-modules--0.14.0.sql rename to __fixtures__/stage/extensions/@pgpm/metaschema-modules/sql/metaschema-modules--0.14.0.sql diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-schema/Makefile b/__fixtures__/stage/extensions/@pgpm/metaschema-schema/Makefile index fff4074f0..2533bd65e 100644 --- a/__fixtures__/stage/extensions/@pgpm/metaschema-schema/Makefile +++ b/__fixtures__/stage/extensions/@pgpm/metaschema-schema/Makefile @@ -1,5 +1,5 @@ -EXTENSION = db-meta-schema -DATA = sql/db-meta-schema--0.14.0.sql +EXTENSION = metaschema-schema +DATA = sql/metaschema-schema--0.14.0.sql PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-schema/db-meta-schema.control b/__fixtures__/stage/extensions/@pgpm/metaschema-schema/metaschema-schema.control similarity index 61% rename from __fixtures__/stage/extensions/@pgpm/metaschema-schema/db-meta-schema.control rename to __fixtures__/stage/extensions/@pgpm/metaschema-schema/metaschema-schema.control index 5f36f1618..ac9b37a2a 100644 --- a/__fixtures__/stage/extensions/@pgpm/metaschema-schema/db-meta-schema.control +++ b/__fixtures__/stage/extensions/@pgpm/metaschema-schema/metaschema-schema.control @@ -1,8 +1,7 @@ -# db-meta-schema extension -comment = 'db-meta-schema extension' +# metaschema-schema extension +comment = 'metaschema-schema extension' default_version = '0.14.0' -module_pathname = '$libdir/db-meta-schema' +module_pathname = '$libdir/metaschema-schema' requires = 'citext,hstore,pgpm-inflection,pgpm-database-jobs,pgpm-types,pgcrypto,plpgsql,postgis,uuid-ossp,pgpm-verify' relocatable = false superuser = false - diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-schema/pgpm.plan b/__fixtures__/stage/extensions/@pgpm/metaschema-schema/pgpm.plan index c4d642c5b..1728cd889 100644 --- a/__fixtures__/stage/extensions/@pgpm/metaschema-schema/pgpm.plan +++ b/__fixtures__/stage/extensions/@pgpm/metaschema-schema/pgpm.plan @@ -1,6 +1,6 @@ %syntax-version=1.0.0 -%project=db-meta-schema -%uri=db-meta-schema +%project=metaschema-schema +%uri=metaschema-schema schemas/collections_private/schema [pgpm-inflection:schemas/inflection/tables/inflection_rules/indexes/inflection_rules_type_idx pgpm-database-jobs:schemas/app_jobs/triggers/tg_add_job_with_row pgpm-types:schemas/public/domains/url] 2017-08-11T08:11:51Z skitch # add schemas/collections_private/schema schemas/collections_public/schema 2017-08-11T08:11:51Z skitch # add schemas/collections_public/schema diff --git a/__fixtures__/stage/extensions/@pgpm/metaschema-schema/sql/db-meta-schema--0.14.0.sql b/__fixtures__/stage/extensions/@pgpm/metaschema-schema/sql/metaschema-schema--0.14.0.sql similarity index 100% rename from __fixtures__/stage/extensions/@pgpm/metaschema-schema/sql/db-meta-schema--0.14.0.sql rename to __fixtures__/stage/extensions/@pgpm/metaschema-schema/sql/metaschema-schema--0.14.0.sql