From e4639001fb15abab6f01a984197dc651cdb49924 Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 11 May 2026 19:33:04 +0000 Subject: [PATCH 1/3] feat(pgpm/export): add 19 missing module tables to export config Add all missing metaschema_modules_public tables: - billing_module, billing_provider_module, devices_module - entity_type_provision, identity_providers_module - notifications_module, plans_module, realtime_module - session_secrets_module, webauthn_auth_module, webauthn_credentials_module - blueprint, blueprint_construction, blueprint_template - rate_limits_module, relation_provision, storage_module Add missing metaschema_public tables: - node_type_registry, spatial_relation Fix stale secure_table_provision config (node_type/node_data -> nodes). Add database_extension to META_TABLE_ORDER (was in config but missing from order, causing it to be excluded from migration file output). Update all three export paths: - META_TABLE_CONFIG + META_TABLE_ORDER in export-utils.ts - SQL flow queryAndParse calls in export-meta.ts - GraphQL flow queryAndParse calls in export-graphql-meta.ts Update tests to accommodate node_type_registry (no uuid id) and blueprint_template (no database_id). --- pgpm/export/__tests__/export-utils.test.ts | 16 +- pgpm/export/src/export-graphql-meta.ts | 21 +- pgpm/export/src/export-meta.ts | 19 + pgpm/export/src/export-utils.ts | 410 ++++++++++++++++++++- 4 files changed, 455 insertions(+), 11 deletions(-) diff --git a/pgpm/export/__tests__/export-utils.test.ts b/pgpm/export/__tests__/export-utils.test.ts index b64a2fd0d..3914b2014 100644 --- a/pgpm/export/__tests__/export-utils.test.ts +++ b/pgpm/export/__tests__/export-utils.test.ts @@ -50,10 +50,7 @@ describe('META_TABLE_CONFIG and META_TABLE_ORDER consistency', () => { } } - // database_extension is in config but intentionally not in META_TABLE_ORDER - // (it's queried but not included in the meta package output) - // If there are other exceptions, document them here. - const knownExceptions = ['database_extension']; + const knownExceptions: string[] = []; const unexpectedMissing = missingFromOrder.filter(k => !knownExceptions.includes(k)); expect(unexpectedMissing).toEqual([]); @@ -83,16 +80,21 @@ describe('META_TABLE_CONFIG and META_TABLE_ORDER consistency', () => { } }); - it('every config entry should have an id field of type uuid', () => { + it('every config entry should have an id field of type uuid (except node_type_registry)', () => { + // node_type_registry uses name (text) as its primary key instead of uuid id + const noIdExceptions = ['node_type_registry']; for (const [key, config] of Object.entries(META_TABLE_CONFIG)) { + if (noIdExceptions.includes(key)) continue; expect(config.fields).toHaveProperty('id'); expect(config.fields.id).toBe('uuid'); } }); - it('every config entry (except database) should have a database_id field', () => { + it('every config entry (except known exceptions) should have a database_id field', () => { + // database: uses id instead; node_type_registry: global table; blueprint_template: uses owner_id + const noDatabaseIdExceptions = ['database', 'node_type_registry', 'blueprint_template']; for (const [key, config] of Object.entries(META_TABLE_CONFIG)) { - if (key === 'database') continue; + if (noDatabaseIdExceptions.includes(key)) continue; expect(config.fields).toHaveProperty('database_id'); expect(config.fields.database_id).toBe('uuid'); } diff --git a/pgpm/export/src/export-graphql-meta.ts b/pgpm/export/src/export-graphql-meta.ts index cef0239f8..ac88381ad 100644 --- a/pgpm/export/src/export-graphql-meta.ts +++ b/pgpm/export/src/export-graphql-meta.ts @@ -125,6 +125,8 @@ export const exportGraphQLMeta = async ({ queryAndParse('database_extension'), queryAndParse('schema'), queryAndParse('function'), + queryAndParse('node_type_registry'), + queryAndParse('spatial_relation'), queryAndParse('table'), queryAndParse('field'), queryAndParse('policy'), @@ -189,7 +191,24 @@ export const exportGraphQLMeta = async ({ queryAndParse('secure_table_provision'), queryAndParse('uuid_module'), queryAndParse('default_ids_module'), - queryAndParse('denormalized_table_field') + queryAndParse('denormalized_table_field'), + queryAndParse('relation_provision'), + queryAndParse('blueprint_template'), + queryAndParse('blueprint'), + queryAndParse('blueprint_construction'), + queryAndParse('entity_type_provision'), + queryAndParse('rate_limits_module'), + queryAndParse('storage_module'), + queryAndParse('billing_module'), + queryAndParse('billing_provider_module'), + queryAndParse('devices_module'), + queryAndParse('identity_providers_module'), + queryAndParse('notifications_module'), + queryAndParse('plans_module'), + queryAndParse('realtime_module'), + queryAndParse('session_secrets_module'), + queryAndParse('webauthn_auth_module'), + queryAndParse('webauthn_credentials_module') ]); return sql; diff --git a/pgpm/export/src/export-meta.ts b/pgpm/export/src/export-meta.ts index 9e4203b5b..c6207436f 100644 --- a/pgpm/export/src/export-meta.ts +++ b/pgpm/export/src/export-meta.ts @@ -133,6 +133,8 @@ export const exportMeta = async ({ opts, dbname, database_id }: ExportMetaParams await queryAndParse('database_extension', `SELECT * FROM metaschema_public.database_extension WHERE database_id = $1 ORDER BY id`); await queryAndParse('schema', `SELECT * FROM metaschema_public.schema WHERE database_id = $1 ORDER BY id`); await queryAndParse('function', `SELECT * FROM metaschema_public.function WHERE database_id = $1 ORDER BY id`); + await queryAndParse('node_type_registry', `SELECT * FROM metaschema_public.node_type_registry ORDER BY name`); + await queryAndParse('spatial_relation', `SELECT * FROM metaschema_public.spatial_relation WHERE database_id = $1 ORDER BY id`); await queryAndParse('table', `SELECT * FROM metaschema_public.table WHERE database_id = $1 ORDER BY id`); await queryAndParse('field', `SELECT * FROM metaschema_public.field WHERE database_id = $1 ORDER BY id`); await queryAndParse('policy', `SELECT * FROM metaschema_public.policy WHERE database_id = $1 ORDER BY id`); @@ -198,6 +200,23 @@ export const exportMeta = async ({ opts, dbname, database_id }: ExportMetaParams await queryAndParse('uuid_module', `SELECT * FROM metaschema_modules_public.uuid_module WHERE database_id = $1 ORDER BY id`); await queryAndParse('default_ids_module', `SELECT * FROM metaschema_modules_public.default_ids_module WHERE database_id = $1 ORDER BY id`); await queryAndParse('denormalized_table_field', `SELECT * FROM metaschema_modules_public.denormalized_table_field WHERE database_id = $1 ORDER BY id`); + await queryAndParse('relation_provision', `SELECT * FROM metaschema_modules_public.relation_provision WHERE database_id = $1 ORDER BY id`); + await queryAndParse('blueprint_template', `SELECT * FROM metaschema_modules_public.blueprint_template ORDER BY id`); + await queryAndParse('blueprint', `SELECT * FROM metaschema_modules_public.blueprint WHERE database_id = $1 ORDER BY id`); + await queryAndParse('blueprint_construction', `SELECT * FROM metaschema_modules_public.blueprint_construction WHERE database_id = $1 ORDER BY id`); + await queryAndParse('entity_type_provision', `SELECT * FROM metaschema_modules_public.entity_type_provision WHERE database_id = $1 ORDER BY id`); + await queryAndParse('rate_limits_module', `SELECT * FROM metaschema_modules_public.rate_limits_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('storage_module', `SELECT * FROM metaschema_modules_public.storage_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('billing_module', `SELECT * FROM metaschema_modules_public.billing_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('billing_provider_module', `SELECT * FROM metaschema_modules_public.billing_provider_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('devices_module', `SELECT * FROM metaschema_modules_public.devices_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('identity_providers_module', `SELECT * FROM metaschema_modules_public.identity_providers_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('notifications_module', `SELECT * FROM metaschema_modules_public.notifications_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('plans_module', `SELECT * FROM metaschema_modules_public.plans_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('realtime_module', `SELECT * FROM metaschema_modules_public.realtime_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('session_secrets_module', `SELECT * FROM metaschema_modules_public.session_secrets_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('webauthn_auth_module', `SELECT * FROM metaschema_modules_public.webauthn_auth_module WHERE database_id = $1 ORDER BY id`); + await queryAndParse('webauthn_credentials_module', `SELECT * FROM metaschema_modules_public.webauthn_credentials_module WHERE database_id = $1 ORDER BY id`); return sql; }; diff --git a/pgpm/export/src/export-utils.ts b/pgpm/export/src/export-utils.ts index 58cc66b7f..34ceebaf8 100644 --- a/pgpm/export/src/export-utils.ts +++ b/pgpm/export/src/export-utils.ts @@ -123,8 +123,11 @@ SET session_replication_role TO DEFAULT;`; */ export const META_TABLE_ORDER = [ 'database', + 'database_extension', 'schema', 'function', + 'node_type_registry', + 'spatial_relation', 'table', 'field', 'policy', @@ -181,7 +184,24 @@ export const META_TABLE_ORDER = [ 'uuid_module', 'default_ids_module', 'denormalized_table_field', - 'table_template_module' + 'table_template_module', + 'relation_provision', + 'blueprint_template', + 'blueprint', + 'blueprint_construction', + 'entity_type_provision', + 'rate_limits_module', + 'storage_module', + 'billing_module', + 'billing_provider_module', + 'devices_module', + 'identity_providers_module', + 'notifications_module', + 'plans_module', + 'realtime_module', + 'session_secrets_module', + 'webauthn_auth_module', + 'webauthn_credentials_module' ] as const; // ============================================================================= @@ -1103,9 +1123,8 @@ export const META_TABLE_CONFIG: Record = { schema_id: 'uuid', table_id: 'uuid', table_name: 'text', - node_type: 'text', + nodes: 'jsonb', use_rls: 'boolean', - node_data: 'jsonb', fields: 'jsonb[]', grants: 'jsonb', policies: 'jsonb', @@ -1148,6 +1167,391 @@ export const META_TABLE_CONFIG: Record = { func_name: 'text', func_order: 'int' } + }, + relation_provision: { + schema: 'metaschema_modules_public', + table: 'relation_provision', + fields: { + id: 'uuid', + database_id: 'uuid', + relation_type: 'text', + source_table_id: 'uuid', + target_table_id: 'uuid', + field_name: 'text', + delete_action: 'text', + is_required: 'boolean', + api_required: 'boolean', + junction_table_id: 'uuid', + junction_table_name: 'text', + junction_schema_id: 'uuid', + source_field_name: 'text', + target_field_name: 'text', + use_composite_key: 'boolean', + create_index: 'boolean', + expose_in_api: 'boolean', + nodes: 'jsonb', + grants: 'jsonb', + policies: 'jsonb', + out_field_id: 'uuid', + out_junction_table_id: 'uuid', + out_source_field_id: 'uuid', + out_target_field_id: 'uuid' + } + }, + blueprint: { + schema: 'metaschema_modules_public', + table: 'blueprint', + fields: { + id: 'uuid', + owner_id: 'uuid', + database_id: 'uuid', + name: 'text', + display_name: 'text', + description: 'text', + definition: 'jsonb', + template_id: 'uuid', + definition_hash: 'uuid', + table_hashes: 'jsonb', + created_at: 'timestamptz', + updated_at: 'timestamptz' + } + }, + blueprint_construction: { + schema: 'metaschema_modules_public', + table: 'blueprint_construction', + fields: { + id: 'uuid', + blueprint_id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + status: 'text', + error_details: 'text', + table_map: 'jsonb', + constructed_definition: 'jsonb', + constructed_at: 'timestamptz', + created_at: 'timestamptz', + updated_at: 'timestamptz' + } + }, + blueprint_template: { + schema: 'metaschema_modules_public', + table: 'blueprint_template', + fields: { + id: 'uuid', + name: 'text', + version: 'text', + display_name: 'text', + description: 'text', + owner_id: 'uuid', + visibility: 'text', + categories: 'text[]', + tags: 'text[]', + definition: 'jsonb', + definition_schema_version: 'text', + source: 'text', + complexity: 'text', + copy_count: 'int', + fork_count: 'int', + forked_from_id: 'uuid', + definition_hash: 'uuid', + table_hashes: 'jsonb', + created_at: 'timestamptz', + updated_at: 'timestamptz' + } + }, + rate_limits_module: { + schema: 'metaschema_modules_public', + table: 'rate_limits_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + rate_limit_settings_table_id: 'uuid', + ip_rate_limits_table_id: 'uuid', + rate_limits_table_id: 'uuid', + rate_limit_settings_table: 'text', + ip_rate_limits_table: 'text', + rate_limits_table: 'text' + } + }, + storage_module: { + schema: 'metaschema_modules_public', + table: 'storage_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + buckets_table_id: 'uuid', + files_table_id: 'uuid', + buckets_table_name: 'text', + files_table_name: 'text', + membership_type: 'int', + policies: 'jsonb', + skip_default_policy_tables: 'text[]', + entity_table_id: 'uuid', + endpoint: 'text', + public_url_prefix: 'text', + provider: 'text', + allowed_origins: 'text[]', + restrict_reads: 'boolean', + has_path_shares: 'boolean', + path_shares_table_id: 'uuid', + upload_url_expiry_seconds: 'int', + download_url_expiry_seconds: 'int', + max_filename_length: 'int', + cache_ttl_seconds: 'int', + max_bulk_files: 'int', + has_versioning: 'boolean', + has_content_hash: 'boolean', + has_custom_keys: 'boolean', + has_audit_log: 'boolean', + file_events_table_id: 'uuid' + } + }, + entity_type_provision: { + schema: 'metaschema_modules_public', + table: 'entity_type_provision', + fields: { + id: 'uuid', + database_id: 'uuid', + name: 'text', + prefix: 'text', + description: 'text', + parent_entity: 'text', + table_name: 'text', + is_visible: 'boolean', + has_limits: 'boolean', + has_profiles: 'boolean', + has_levels: 'boolean', + has_storage: 'boolean', + has_invites: 'boolean', + storage_config: 'jsonb', + skip_entity_policies: 'boolean', + table_provision: 'jsonb', + out_membership_type: 'int', + out_entity_table_id: 'uuid', + out_entity_table_name: 'text', + out_installed_modules: 'text[]', + out_storage_module_id: 'uuid', + out_buckets_table_id: 'uuid', + out_files_table_id: 'uuid', + out_path_shares_table_id: 'uuid', + out_invites_module_id: 'uuid' + } + }, + billing_module: { + schema: 'metaschema_modules_public', + table: 'billing_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + meters_table_id: 'uuid', + meters_table_name: 'text', + plan_subscriptions_table_id: 'uuid', + plan_subscriptions_table_name: 'text', + ledger_table_id: 'uuid', + ledger_table_name: 'text', + balances_table_id: 'uuid', + balances_table_name: 'text', + record_usage_function: 'text', + prefix: 'text' + } + }, + billing_provider_module: { + schema: 'metaschema_modules_public', + table: 'billing_provider_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + provider: 'text', + products_table_id: 'uuid', + prices_table_id: 'uuid', + subscriptions_table_id: 'uuid', + billing_customers_table_id: 'uuid', + billing_customers_table_name: 'text', + billing_products_table_id: 'uuid', + billing_products_table_name: 'text', + billing_prices_table_id: 'uuid', + billing_prices_table_name: 'text', + billing_subscriptions_table_id: 'uuid', + billing_subscriptions_table_name: 'text', + billing_webhook_events_table_id: 'uuid', + billing_webhook_events_table_name: 'text', + process_billing_event_function: 'text', + prefix: 'text' + } + }, + devices_module: { + schema: 'metaschema_modules_public', + table: 'devices_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + user_devices_table_id: 'uuid', + device_settings_table_id: 'uuid', + user_devices_table: 'text', + device_settings_table: 'text' + } + }, + identity_providers_module: { + schema: 'metaschema_modules_public', + table: 'identity_providers_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + table_id: 'uuid', + table_name: 'text' + } + }, + notifications_module: { + schema: 'metaschema_modules_public', + table: 'notifications_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + notifications_table_id: 'uuid', + read_state_table_id: 'uuid', + preferences_table_id: 'uuid', + channels_table_id: 'uuid', + delivery_log_table_id: 'uuid', + owner_table_id: 'uuid', + user_settings_table_id: 'uuid', + organization_settings_table_id: 'uuid', + has_channels: 'boolean', + has_preferences: 'boolean', + has_settings_extension: 'boolean', + has_digest_metadata: 'boolean', + has_subscriptions: 'boolean' + } + }, + plans_module: { + schema: 'metaschema_modules_public', + table: 'plans_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + plans_table_id: 'uuid', + plans_table_name: 'text', + plan_limits_table_id: 'uuid', + plan_limits_table_name: 'text', + plan_pricing_table_id: 'uuid', + plan_overrides_table_id: 'uuid', + apply_plan_function: 'text', + apply_plan_aggregate_function: 'text', + prefix: 'text' + } + }, + realtime_module: { + schema: 'metaschema_modules_public', + table: 'realtime_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + subscriptions_schema_id: 'uuid', + change_log_table_id: 'uuid', + listener_node_table_id: 'uuid', + source_registry_table_id: 'uuid', + retention_hours: 'int', + lookahead_hours: 'int', + partition_interval: 'text', + notify_channel: 'text' + } + }, + session_secrets_module: { + schema: 'metaschema_modules_public', + table: 'session_secrets_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + table_id: 'uuid', + table_name: 'text', + sessions_table_id: 'uuid' + } + }, + webauthn_auth_module: { + schema: 'metaschema_modules_public', + table: 'webauthn_auth_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + users_table_id: 'uuid', + credentials_table_id: 'uuid', + sessions_table_id: 'uuid', + session_credentials_table_id: 'uuid', + session_secrets_table_id: 'uuid', + auth_settings_table_id: 'uuid', + rp_id: 'text', + rp_name: 'text', + origin_allowlist: 'text[]', + attestation_type: 'text', + require_user_verification: 'boolean', + resident_key: 'text', + challenge_expiry: 'interval' + } + }, + webauthn_credentials_module: { + schema: 'metaschema_modules_public', + table: 'webauthn_credentials_module', + fields: { + id: 'uuid', + database_id: 'uuid', + schema_id: 'uuid', + private_schema_id: 'uuid', + table_id: 'uuid', + owner_table_id: 'uuid', + table_name: 'text' + } + }, + // ============================================================================= + // metaschema_public tables (new) + // ============================================================================= + node_type_registry: { + schema: 'metaschema_public', + table: 'node_type_registry', + fields: { + name: 'text', + slug: 'text', + category: 'text', + display_name: 'text', + description: 'text', + parameter_schema: 'jsonb', + tags: 'text[]' + } + }, + spatial_relation: { + schema: 'metaschema_public', + table: 'spatial_relation', + fields: { + id: 'uuid', + database_id: 'uuid', + table_id: 'uuid', + field_id: 'uuid', + ref_table_id: 'uuid', + ref_field_id: 'uuid', + name: 'text', + operator: 'text', + param_name: 'text', + category: 'text', + module: 'text', + scope: 'int', + tags: 'text[]' + } } }; From 9184cac6aba85bb54ff3a016a4f2083faf42240c Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 11 May 2026 19:50:32 +0000 Subject: [PATCH 2/3] fix: scope export to modules and provisions only Remove non-module tables that were incorrectly added: - node_type_registry, spatial_relation (metaschema_public) - blueprint, blueprint_construction, blueprint_template - database_extension from META_TABLE_ORDER Keep only modules (*_module) and provisions (*_provision) needed to run applications. --- pgpm/export/__tests__/export-utils.test.ts | 16 ++-- pgpm/export/src/export-graphql-meta.ts | 5 - pgpm/export/src/export-meta.ts | 5 - pgpm/export/src/export-utils.ts | 102 --------------------- 4 files changed, 7 insertions(+), 121 deletions(-) diff --git a/pgpm/export/__tests__/export-utils.test.ts b/pgpm/export/__tests__/export-utils.test.ts index 3914b2014..b64a2fd0d 100644 --- a/pgpm/export/__tests__/export-utils.test.ts +++ b/pgpm/export/__tests__/export-utils.test.ts @@ -50,7 +50,10 @@ describe('META_TABLE_CONFIG and META_TABLE_ORDER consistency', () => { } } - const knownExceptions: string[] = []; + // database_extension is in config but intentionally not in META_TABLE_ORDER + // (it's queried but not included in the meta package output) + // If there are other exceptions, document them here. + const knownExceptions = ['database_extension']; const unexpectedMissing = missingFromOrder.filter(k => !knownExceptions.includes(k)); expect(unexpectedMissing).toEqual([]); @@ -80,21 +83,16 @@ describe('META_TABLE_CONFIG and META_TABLE_ORDER consistency', () => { } }); - it('every config entry should have an id field of type uuid (except node_type_registry)', () => { - // node_type_registry uses name (text) as its primary key instead of uuid id - const noIdExceptions = ['node_type_registry']; + it('every config entry should have an id field of type uuid', () => { for (const [key, config] of Object.entries(META_TABLE_CONFIG)) { - if (noIdExceptions.includes(key)) continue; expect(config.fields).toHaveProperty('id'); expect(config.fields.id).toBe('uuid'); } }); - it('every config entry (except known exceptions) should have a database_id field', () => { - // database: uses id instead; node_type_registry: global table; blueprint_template: uses owner_id - const noDatabaseIdExceptions = ['database', 'node_type_registry', 'blueprint_template']; + it('every config entry (except database) should have a database_id field', () => { for (const [key, config] of Object.entries(META_TABLE_CONFIG)) { - if (noDatabaseIdExceptions.includes(key)) continue; + if (key === 'database') continue; expect(config.fields).toHaveProperty('database_id'); expect(config.fields.database_id).toBe('uuid'); } diff --git a/pgpm/export/src/export-graphql-meta.ts b/pgpm/export/src/export-graphql-meta.ts index ac88381ad..35b61d53a 100644 --- a/pgpm/export/src/export-graphql-meta.ts +++ b/pgpm/export/src/export-graphql-meta.ts @@ -125,8 +125,6 @@ export const exportGraphQLMeta = async ({ queryAndParse('database_extension'), queryAndParse('schema'), queryAndParse('function'), - queryAndParse('node_type_registry'), - queryAndParse('spatial_relation'), queryAndParse('table'), queryAndParse('field'), queryAndParse('policy'), @@ -193,9 +191,6 @@ export const exportGraphQLMeta = async ({ queryAndParse('default_ids_module'), queryAndParse('denormalized_table_field'), queryAndParse('relation_provision'), - queryAndParse('blueprint_template'), - queryAndParse('blueprint'), - queryAndParse('blueprint_construction'), queryAndParse('entity_type_provision'), queryAndParse('rate_limits_module'), queryAndParse('storage_module'), diff --git a/pgpm/export/src/export-meta.ts b/pgpm/export/src/export-meta.ts index c6207436f..2a31ee4fa 100644 --- a/pgpm/export/src/export-meta.ts +++ b/pgpm/export/src/export-meta.ts @@ -133,8 +133,6 @@ export const exportMeta = async ({ opts, dbname, database_id }: ExportMetaParams await queryAndParse('database_extension', `SELECT * FROM metaschema_public.database_extension WHERE database_id = $1 ORDER BY id`); await queryAndParse('schema', `SELECT * FROM metaschema_public.schema WHERE database_id = $1 ORDER BY id`); await queryAndParse('function', `SELECT * FROM metaschema_public.function WHERE database_id = $1 ORDER BY id`); - await queryAndParse('node_type_registry', `SELECT * FROM metaschema_public.node_type_registry ORDER BY name`); - await queryAndParse('spatial_relation', `SELECT * FROM metaschema_public.spatial_relation WHERE database_id = $1 ORDER BY id`); await queryAndParse('table', `SELECT * FROM metaschema_public.table WHERE database_id = $1 ORDER BY id`); await queryAndParse('field', `SELECT * FROM metaschema_public.field WHERE database_id = $1 ORDER BY id`); await queryAndParse('policy', `SELECT * FROM metaschema_public.policy WHERE database_id = $1 ORDER BY id`); @@ -201,9 +199,6 @@ export const exportMeta = async ({ opts, dbname, database_id }: ExportMetaParams await queryAndParse('default_ids_module', `SELECT * FROM metaschema_modules_public.default_ids_module WHERE database_id = $1 ORDER BY id`); await queryAndParse('denormalized_table_field', `SELECT * FROM metaschema_modules_public.denormalized_table_field WHERE database_id = $1 ORDER BY id`); await queryAndParse('relation_provision', `SELECT * FROM metaschema_modules_public.relation_provision WHERE database_id = $1 ORDER BY id`); - await queryAndParse('blueprint_template', `SELECT * FROM metaschema_modules_public.blueprint_template ORDER BY id`); - await queryAndParse('blueprint', `SELECT * FROM metaschema_modules_public.blueprint WHERE database_id = $1 ORDER BY id`); - await queryAndParse('blueprint_construction', `SELECT * FROM metaschema_modules_public.blueprint_construction WHERE database_id = $1 ORDER BY id`); await queryAndParse('entity_type_provision', `SELECT * FROM metaschema_modules_public.entity_type_provision WHERE database_id = $1 ORDER BY id`); await queryAndParse('rate_limits_module', `SELECT * FROM metaschema_modules_public.rate_limits_module WHERE database_id = $1 ORDER BY id`); await queryAndParse('storage_module', `SELECT * FROM metaschema_modules_public.storage_module WHERE database_id = $1 ORDER BY id`); diff --git a/pgpm/export/src/export-utils.ts b/pgpm/export/src/export-utils.ts index 34ceebaf8..41974a632 100644 --- a/pgpm/export/src/export-utils.ts +++ b/pgpm/export/src/export-utils.ts @@ -123,11 +123,8 @@ SET session_replication_role TO DEFAULT;`; */ export const META_TABLE_ORDER = [ 'database', - 'database_extension', 'schema', 'function', - 'node_type_registry', - 'spatial_relation', 'table', 'field', 'policy', @@ -186,9 +183,6 @@ export const META_TABLE_ORDER = [ 'denormalized_table_field', 'table_template_module', 'relation_provision', - 'blueprint_template', - 'blueprint', - 'blueprint_construction', 'entity_type_provision', 'rate_limits_module', 'storage_module', @@ -1198,67 +1192,6 @@ export const META_TABLE_CONFIG: Record = { out_target_field_id: 'uuid' } }, - blueprint: { - schema: 'metaschema_modules_public', - table: 'blueprint', - fields: { - id: 'uuid', - owner_id: 'uuid', - database_id: 'uuid', - name: 'text', - display_name: 'text', - description: 'text', - definition: 'jsonb', - template_id: 'uuid', - definition_hash: 'uuid', - table_hashes: 'jsonb', - created_at: 'timestamptz', - updated_at: 'timestamptz' - } - }, - blueprint_construction: { - schema: 'metaschema_modules_public', - table: 'blueprint_construction', - fields: { - id: 'uuid', - blueprint_id: 'uuid', - database_id: 'uuid', - schema_id: 'uuid', - status: 'text', - error_details: 'text', - table_map: 'jsonb', - constructed_definition: 'jsonb', - constructed_at: 'timestamptz', - created_at: 'timestamptz', - updated_at: 'timestamptz' - } - }, - blueprint_template: { - schema: 'metaschema_modules_public', - table: 'blueprint_template', - fields: { - id: 'uuid', - name: 'text', - version: 'text', - display_name: 'text', - description: 'text', - owner_id: 'uuid', - visibility: 'text', - categories: 'text[]', - tags: 'text[]', - definition: 'jsonb', - definition_schema_version: 'text', - source: 'text', - complexity: 'text', - copy_count: 'int', - fork_count: 'int', - forked_from_id: 'uuid', - definition_hash: 'uuid', - table_hashes: 'jsonb', - created_at: 'timestamptz', - updated_at: 'timestamptz' - } - }, rate_limits_module: { schema: 'metaschema_modules_public', table: 'rate_limits_module', @@ -1517,41 +1450,6 @@ export const META_TABLE_CONFIG: Record = { owner_table_id: 'uuid', table_name: 'text' } - }, - // ============================================================================= - // metaschema_public tables (new) - // ============================================================================= - node_type_registry: { - schema: 'metaschema_public', - table: 'node_type_registry', - fields: { - name: 'text', - slug: 'text', - category: 'text', - display_name: 'text', - description: 'text', - parameter_schema: 'jsonb', - tags: 'text[]' - } - }, - spatial_relation: { - schema: 'metaschema_public', - table: 'spatial_relation', - fields: { - id: 'uuid', - database_id: 'uuid', - table_id: 'uuid', - field_id: 'uuid', - ref_table_id: 'uuid', - ref_field_id: 'uuid', - name: 'text', - operator: 'text', - param_name: 'text', - category: 'text', - module: 'text', - scope: 'int', - tags: 'text[]' - } } }; From d29061d0b68d2896a97648b5fc02c70d51a3879d Mon Sep 17 00:00:00 2001 From: Dan Lynch Date: Mon, 11 May 2026 21:25:45 +0000 Subject: [PATCH 3/3] feat(pgpm/export): add spatial_relation to export config Add spatial_relation table (metaschema_public) to META_TABLE_ORDER, META_TABLE_CONFIG, and both SQL/GraphQL export flows. This table tracks PostGIS spatial relationships between tables for the graphile-postgis plugin. --- pgpm/export/src/export-graphql-meta.ts | 1 + pgpm/export/src/export-meta.ts | 1 + pgpm/export/src/export-utils.ts | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/pgpm/export/src/export-graphql-meta.ts b/pgpm/export/src/export-graphql-meta.ts index 35b61d53a..554395032 100644 --- a/pgpm/export/src/export-graphql-meta.ts +++ b/pgpm/export/src/export-graphql-meta.ts @@ -125,6 +125,7 @@ export const exportGraphQLMeta = async ({ queryAndParse('database_extension'), queryAndParse('schema'), queryAndParse('function'), + queryAndParse('spatial_relation'), queryAndParse('table'), queryAndParse('field'), queryAndParse('policy'), diff --git a/pgpm/export/src/export-meta.ts b/pgpm/export/src/export-meta.ts index 2a31ee4fa..7f98609f7 100644 --- a/pgpm/export/src/export-meta.ts +++ b/pgpm/export/src/export-meta.ts @@ -133,6 +133,7 @@ export const exportMeta = async ({ opts, dbname, database_id }: ExportMetaParams await queryAndParse('database_extension', `SELECT * FROM metaschema_public.database_extension WHERE database_id = $1 ORDER BY id`); await queryAndParse('schema', `SELECT * FROM metaschema_public.schema WHERE database_id = $1 ORDER BY id`); await queryAndParse('function', `SELECT * FROM metaschema_public.function WHERE database_id = $1 ORDER BY id`); + await queryAndParse('spatial_relation', `SELECT * FROM metaschema_public.spatial_relation WHERE database_id = $1 ORDER BY id`); await queryAndParse('table', `SELECT * FROM metaschema_public.table WHERE database_id = $1 ORDER BY id`); await queryAndParse('field', `SELECT * FROM metaschema_public.field WHERE database_id = $1 ORDER BY id`); await queryAndParse('policy', `SELECT * FROM metaschema_public.policy WHERE database_id = $1 ORDER BY id`); diff --git a/pgpm/export/src/export-utils.ts b/pgpm/export/src/export-utils.ts index 41974a632..921f6f6a9 100644 --- a/pgpm/export/src/export-utils.ts +++ b/pgpm/export/src/export-utils.ts @@ -127,6 +127,7 @@ export const META_TABLE_ORDER = [ 'function', 'table', 'field', + 'spatial_relation', 'policy', 'index', 'trigger', @@ -1450,6 +1451,25 @@ export const META_TABLE_CONFIG: Record = { owner_table_id: 'uuid', table_name: 'text' } + }, + spatial_relation: { + schema: 'metaschema_public', + table: 'spatial_relation', + fields: { + id: 'uuid', + database_id: 'uuid', + table_id: 'uuid', + field_id: 'uuid', + ref_table_id: 'uuid', + ref_field_id: 'uuid', + name: 'text', + operator: 'text', + param_name: 'text', + category: 'text', + module: 'text', + scope: 'int', + tags: 'text[]' + } } };