Skip to content

feat(portability): committed materialized (ejected) vendor modules, both directions - #33

Merged
pyramation merged 1 commit into
mainfrom
feat/materialize-vendor-modules
Jul 31, 2026
Merged

feat(portability): committed materialized (ejected) vendor modules, both directions#33
pyramation merged 1 commit into
mainfrom
feat/materialize-vendor-modules

Conversation

@pyramation

Copy link
Copy Markdown
Collaborator

Summary

Bumps @pgpmjs/* + supabase-test to the freshly published versions (core 7.20.0, portability 0.3.0, supabase-test 3.9.0, …) and adds persistent, committed materialized ("ejected") vendor modules in both directions, kept in a separate portability/materialized/ tree so they don't clutter the source fixtures in portability/packages/.

Until now the transform only ran at deploy time (seed.apply) — nothing landed on disk to review. This ejects the apply proxies into ordinary pgpm modules (deploy/ revert/ verify/ pgpm.plan / *.control, no pgpm.apply.json) with the transforms baked into the SQL, so they deploy like any hand-written module. Every transform is derived from the supabase vendor shape (fromVendorProfile / toVendorProfile), not hand-written routing.

portability/
├── packages/                     # source fixtures + apply proxies (recipes)
└── materialized/packages/        # committed ejected output (build artifact)
    ├── vendor-app-materialized/          # Supabase → pgpm
    └── vendor-app-native-materialized/   # pgpm → Supabase

What each direction bakes in:

Module requires FK RLS predicate uuid_generate_v4
vendor-app-materialized (fwd) plpgsql, uuid-ossp, auth-provider app_auth.users app_auth.current_user_id() de-qualified (bare)
vendor-app-native-materialized (rev) plpgsql auth.users auth.uid() re-qualified extensions.uuid_generate_v4()

Tests added (run serially):

  • materialized-drift.test.ts — the drift gate on plain PostgreSQL: re-materializes into a temp dir and asserts byte-identical output vs. what's committed (both directions), plus asserts each module is a plain pgpm module (no pgpm.apply.json).
  • materialized-forward.test.ts — deploys the committed forward module on plain PostgreSQL (PgpmPackage.deploy resolves auth-provider + uuid-ossp first) and asserts auth/extensions schemas are absent, the FK/RLS are rebound onto the generic provider, and RLS is enforced through app_auth.current_user_id().
  • materialized-reverse.test.ts — deploys Supabase's native supabase fixture, then the committed reverse module on top, asserting the FK/RLS rebind back onto auth.users / auth.uid(). Gated behind VENDOR_STACK=1 (the vendor workflow) because the native subsystem needs Supabase-only extensions (pg_graphql, supabase_vault) unavailable on plain postgres-plus; the ejected SQL and its determinism for this direction are still verified on plain PG by the drift gate.

src/materialize-fixtures.ts is the committed generator (materializeApplyModule over the vendor-shape specs) used both to regenerate the artifacts and by the drift test. It also finalizes the ejected .control requires (forward adds auth-provider, keeps uuid-ossp; reverse drops both — the stack owns auth and the extensions schema natively), since materializeApplyModule does not yet fold apply-spec requires into the emitted control.

portability/pgpm.json now globs materialized/packages/* so the ejected modules are discoverable for plain deployment.

Local: on postgres-plus:18, 20 tests pass + 4 skipped (the vendor-stack reverse/deploy suites gate off without VENDOR_STACK).

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

…oth directions

Bump @pgpmjs/* + supabase-test to the freshly published versions (core 7.20.0, portability 0.3.0, supabase-test 3.9.0) and add persistent ejected modules under portability/materialized/, separate from the source fixtures in packages/. Forward (Supabase -> pgpm) deploys + tests on plain PG; reverse (pgpm -> Supabase) deploys on the vendor stack; both directions covered by a deterministic byte-identical drift gate.
@pyramation pyramation self-assigned this Jul 31, 2026
@devin-ai-integration

Copy link
Copy Markdown

🤖 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, CI, and merge conflict monitoring

@pyramation
pyramation merged commit d78c0af into main Jul 31, 2026
11 checks passed
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