Skip to content

fix: export metaschema_public.function in services migration + defensive null fallback#1131

Merged
pyramation merged 2 commits intomainfrom
feat/fix-rls-settings-null-fallback
May 11, 2026
Merged

fix: export metaschema_public.function in services migration + defensive null fallback#1131
pyramation merged 2 commits intomainfrom
feat/fix-rls-settings-null-fallback

Conversation

@pyramation
Copy link
Copy Markdown
Contributor

Summary

Two fixes for auth function discovery breaking in the GraphQL server:

1. Export pipeline: add metaschema_public.function to services migration export

rls_settings (6 FK columns) and pubkey_settings (4 FK columns) both reference metaschema_public.function, but the @pgpmjs/export pipeline was not including this table in the constructive-services migration output. Since all constructive-services migrations deploy with session_replication_role=replica (disabling triggers), the insert_rls_module trigger never fires to create the function rows. The result: dangling UUID references in rls_settings, the RLS_SETTINGS_SQL LEFT JOINs resolve NULL for every function name, the auth middleware sees authenticate=none, skips authentication, and all RLS policies deny access.

Changes in pgpm/export/src/:

  • export-utils.ts: Add function to META_TABLE_CONFIG (schema + fields) and META_TABLE_ORDER (placed after schema, before table to satisfy FK deps)
  • export-meta.ts: Add queryAndParse for metaschema_public.function
  • export-graphql-meta.ts: Add queryAndParse for function in the parallel batch

After merging, re-running pnpm run generate:constructive in constructive-db will produce a function.sql migration in constructive-services.

2. Defensive fallback in toRlsModuleFromSettings

toRlsModuleFromSettings was returning a truthy RlsModule object with null fields when function rows were missing. This prevented queryRlsModule from falling back to the working legacy api_modules lookup. Added a guard: if authenticate or authenticate_schema are null, return undefined to trigger the fallback.

Review & Testing Checklist for Human

  • Verify META_TABLE_ORDER places function after schema (FK dep) and before rls_settings/pubkey_settings (FK refs)
  • After merging, run pnpm run generate:constructive in constructive-db and confirm services/constructive-services/deploy/migrate/function.sql is generated with the 6 auth function rows
  • Deploy to a fresh database and verify SELECT count(*) FROM metaschema_public.function shows the expected rows
  • Verify the GraphQL server resolves non-NULL function names from RLS_SETTINGS_SQL
  • Test end-to-end authentication (Bearer token → authenticate() → JWT claims → RLS access)

Notes

database_extension is also queried in export-meta.ts but not in META_TABLE_ORDER — this may be another gap worth investigating separately."

Link to Devin session: https://app.devin.ai/sessions/45d6930943ec467496290581d22cb3a9
Requested by: @pyramation

…on names

When metaschema_public.function rows are missing (e.g. the
insert_rls_module trigger was skipped during migration),
the RLS_SETTINGS_SQL LEFT JOINs resolve NULL for function names.
toRlsModuleFromSettings was returning an RlsModule with null fields,
preventing fallback to the working legacy api_modules lookup.

Add a guard to return undefined when critical fields (authenticate,
authenticate_schema) are null, allowing queryRlsModule to fall back
to queryRlsModuleLegacy.
The export pipeline was not including metaschema_public.function in
the constructive-services migration output. This table is referenced
by rls_settings (6 FK columns) and pubkey_settings (4 FK columns).

Since all constructive-services migrations deploy with
session_replication_role=replica (disabling triggers), the
insert_rls_module trigger never fires to create these function rows.
The result is dangling UUID references in rls_settings, causing the
GraphQL server to resolve NULL function names and skip authentication.

Changes:
- Add function to META_TABLE_CONFIG with schema/fields definition
- Add function to META_TABLE_ORDER (after schema, before table)
- Add queryAndParse for metaschema_public.function in export-meta.ts
- Add queryAndParse for function in export-graphql-meta.ts

After this fix, running generate:constructive will produce a new
function.sql migration file in constructive-services containing
the INSERT statements for all registered functions.
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@pyramation pyramation merged commit 19be696 into main May 11, 2026
54 checks passed
@pyramation pyramation deleted the feat/fix-rls-settings-null-fallback branch May 11, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant