Skip to content

feat(pgpm): unified routing profile with workspace portability attach point - #1528

Merged
pyramation merged 1 commit into
mainfrom
feat/unified-routing-profile
Jul 30, 2026
Merged

feat(pgpm): unified routing profile with workspace portability attach point#1528
pyramation merged 1 commit into
mainfrom
feat/unified-routing-profile

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Consolidates pgpm's portability config from three vocabularies to two: module self-description (extensions.json provides/consumes + .control requires, unchanged) and one routing profile shape attachable at two scopes — workspace and per-import.

New shared type in @pgpmjs/types (pgpm/types/src/routing.ts), no transform deps:

interface PgpmRoutingProfile {
  schemas?: Record<string, string>;
  route?: PgpmRouteEntry[];            // { fromSchema, kind, name, toSchema }
  extensions?: PgpmExtensionsRouting;  // { toSchema | routes, only?, from?, serverVersion? }
  roles?: PgpmRolesRouting;            // source role -> target role
}
mergeRoutingProfiles(...profiles)      // per-key, last defined wins whole (no deep merge)

The apply-spec types are now aliases of the shared shape (no duplicated definitions):

-export interface ApplyRouteEntry { ... }        // pgpm/core/src/apply/types.ts
-export interface ApplyExtensionsSpec { ... }
-export type ApplyRolesSpec = Record<string, string>;
-export interface PgpmApplySpec { schemas?; route?; extensions?; roles?; ... }
+export type ApplyRouteEntry = PgpmRouteEntry;
+export type ApplyExtensionsSpec = PgpmExtensionsRouting;
+export type ApplyRolesSpec = PgpmRolesRouting;
+export interface PgpmApplySpec extends PgpmRoutingProfile { ... }

Workspace attach point: PgpmWorkspaceConfig.portability?: PgpmRoutingProfile in pgpm.json, read via the existing @pgpmjs/env loadConfigSyncFromDir (no new config mechanism). Wired into the one deploy-path seam:

// pgpm/core/src/apply/profile.ts (new)
loadWorkspaceRoutingProfile(workspacePath)          // pgpm.json portability, or undefined
resolveEffectiveApplySpec(spec, workspaceProfile)   // defaults -> workspace -> spec, per key

// pgpm/core/src/apply/materialize.ts::resolveEffectiveModulePath
-const spec = readApplySpec(modulePath);
+const spec = resolveEffectiveApplySpec(readApplySpec(modulePath),
+                                       loadWorkspaceRoutingProfile(workspacePath));

Precedence is lexical: a proxy that only overrides roles still inherits the workspace extensions mapping; an overriding key replaces its whole value.

Fully additive/backward compatible: existing pgpm.apply.json files behave identically; no workspace profile ⇒ no behavior change. A proxy must still declare at least one routing key of its own (spec validation unchanged). migrate/clean.ts untouched.

Docs: new .agents/skills/pgpm/references/routing-profile.md documenting the two-surface model with examples; pointers added in the pgpm skill index, extensions.md, and the pgpm-migration-bundle skill.

Tests

  • pgpm/types: 6 new mergeRoutingProfiles unit tests (neither/workspace-only/proxy-only/both/whole-key replace/multi-scope) — 6/6 pass.
  • pgpm/core: new __tests__/apply/apply-workspace-profile.test.tsresolveEffectiveApplySpec precedence, loadWorkspaceRoutingProfile, and a PG-backed e2e (__fixtures__/apply/workspace-profile) where the workspace profile routes extensions/roles and one proxy overrides only roles.
  • Full local runs: pgpm/core 71 suites / 446 tests pass; pgpm/types 1 suite / 6 tests; pgpm/env 2 suites / 26 tests. npx tsc --noEmit clean in pgpm/types, pgpm/env, pgpm/core.

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

@pyramation pyramation self-assigned this Jul 30, 2026
@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, CI, and merge conflict monitoring

@pyramation
pyramation merged commit 0ee6605 into main Jul 30, 2026
16 checks passed
@pyramation
pyramation deleted the feat/unified-routing-profile branch July 30, 2026 09:21
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