TML-2760: default un-namespaced Postgres models to the public namespace#662
Conversation
📝 WalkthroughWalkthroughSwitches Postgres default namespace from the prior unbound sentinel to ChangesPostgres public namespace default and contract regeneration
Estimated code review effort: Possibly related PRs:
Suggested reviewers:
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
@prisma-next/extension-author-tools
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@prisma-next/extension-arktype-json
@prisma-next/middleware-cache
@prisma-next/mongo
@prisma-next/extension-paradedb
@prisma-next/extension-pgvector
@prisma-next/extension-postgis
@prisma-next/postgres
@prisma-next/sql-orm-client
@prisma-next/sqlite
@prisma-next/target-mongo
@prisma-next/adapter-mongo
@prisma-next/driver-mongo
@prisma-next/contract
@prisma-next/utils
@prisma-next/config
@prisma-next/errors
@prisma-next/framework-components
@prisma-next/operations
@prisma-next/ts-render
@prisma-next/contract-authoring
@prisma-next/ids
@prisma-next/psl-parser
@prisma-next/psl-printer
@prisma-next/cli
@prisma-next/cli-telemetry
@prisma-next/emitter
@prisma-next/migration-tools
prisma-next
@prisma-next/vite-plugin-contract-emit
@prisma-next/mongo-codec
@prisma-next/mongo-contract
@prisma-next/mongo-value
@prisma-next/mongo-contract-psl
@prisma-next/mongo-contract-ts
@prisma-next/mongo-emitter
@prisma-next/mongo-schema-ir
@prisma-next/mongo-query-ast
@prisma-next/mongo-orm
@prisma-next/mongo-query-builder
@prisma-next/mongo-lowering
@prisma-next/mongo-wire
@prisma-next/sql-contract
@prisma-next/sql-errors
@prisma-next/sql-operations
@prisma-next/sql-schema-ir
@prisma-next/sql-contract-psl
@prisma-next/sql-contract-ts
@prisma-next/sql-contract-emitter
@prisma-next/sql-lane-query-builder
@prisma-next/sql-relational-core
@prisma-next/sql-builder
@prisma-next/target-postgres
@prisma-next/target-sqlite
@prisma-next/adapter-postgres
@prisma-next/adapter-sqlite
@prisma-next/driver-postgres
@prisma-next/driver-sqlite
commit: |
size-limit report 📦
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/2-sql/2-authoring/contract-psl/src/interpreter.ts (1)
232-245: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy liftMove the default-namespace switch behind a target adapter.
This adds another
targetId === 'postgres'branch in the shared interpreter, so Postgres namespace policy is now encoded here instead of coming from a target-specific adapter/contribution. That keeps target behavior scattered across authoring code and makes future namespace changes easier to drift.As per coding guidelines, "Don't branch on target; use adapters per
.agents/rules/no-target-branches.mdc."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/2-sql/2-authoring/contract-psl/src/interpreter.ts` around lines 232 - 245, The shared interpreter currently branches on targetId (checks for targetId === 'postgres') inside defaultSqlNamespaceIdForTarget and resolveNamespaceIdForSqlTarget which embeds Postgres-specific namespace policy; remove those target-specific branches and instead delegate namespace resolution to the target adapter API (i.e., call into the per-target adapter to obtain the default/unspecified namespace). Specifically, eliminate the 'postgres' checks from defaultSqlNamespaceIdForTarget and resolveNamespaceIdForSqlTarget and replace them with adapter calls so the adapter (not these functions) returns UNBOUND_NAMESPACE_ID, 'public', or undefined as appropriate; continue to use UNSPECIFIED_PSL_NAMESPACE_NAME and UNBOUND_NAMESPACE_ID as inputs but move the logic into the Postgres adapter implementation.
🧹 Nitpick comments (7)
packages/3-extensions/sql-orm-client/test/helpers.ts (2)
62-63: 💤 Low valueVerify non-null assertion safety.
The non-null assertion
Object.entries(contract.domain.namespaces)[0]!will throw at runtime if the contract has no namespaces. While test fixtures should always include at least one namespace, consider adding a defensive guard or comment explaining this assumption.🛡️ Optional: Add defensive guard
const [namespaceId, namespace] = Object.entries(contract.domain.namespaces)[0]!; + if (!namespaceId) throw new Error('contract must have at least one namespace'); const models = contractModels(contract);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/3-extensions/sql-orm-client/test/helpers.ts` around lines 62 - 63, The non-null assertion on Object.entries(contract.domain.namespaces)[0]! can throw if namespaces is empty; replace it with a safe check or explicit assertion: retrieve entries via Object.entries(contract.domain.namespaces), verify entries.length > 0 (or throw a clear error mentioning contract id), then destructure into namespaceId and namespace; alternatively add a comment asserting the test fixture guarantee. Update the usage sites (the const [namespaceId, namespace] assignment in helpers.ts and any logic depending on namespace) to rely on the validated entries before calling contractModels(contract).
265-271: 💤 Low valueConsider adding early-exit comment for buildStiPolyContract.
The search across all namespaces with
Object.values(...).find(...)followed by a throw is good defensive programming. However, the variable nameusersStorageTableis assigned after the find, making the null-check slightly awkward. Consider extracting the search logic or adding a comment explaining why we search all namespaces.♻️ Optional: Simplify with early throw
const usersStorageTable = Object.values( raw.storage.namespaces as Record< string, { tables: Record<string, { columns: Record<string, unknown> }> } >, ).find((ns) => ns.tables['users'])?.tables['users']; if (!usersStorageTable) throw new Error('users table not found in any storage namespace');Could be:
+ // Search all namespaces for the users table (namespace-agnostic test setup) + const namespaceWithUsers = Object.values( + raw.storage.namespaces as Record<string, { tables: Record<string, { columns: Record<string, unknown> }> }> + ).find((ns) => ns.tables['users']); + if (!namespaceWithUsers) throw new Error('users table not found in any storage namespace'); + const usersStorageTable = namespaceWithUsers.tables['users']!;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/3-extensions/sql-orm-client/test/helpers.ts` around lines 265 - 271, The lookup for the users table across all namespaces (using Object.values(raw.storage.namespaces).find(...)) should be made clearer for future readers of buildStiPolyContract: either extract the search into a small helper (e.g., findUsersStorageTable(namespaces)) and assign its result to usersStorageTable, or add an inline comment above the current code explaining why we must search every namespace; if the helper returns undefined, immediately throw an Error('users table not found in any storage namespace') to keep the null-check simple and obvious.packages/2-sql/2-authoring/contract-psl/test/unbound-tables.ts (1)
13-17: 💤 Low valueConsider defensive handling if
publicnamespace doesn't exist.The fallback to
storage.namespaces['public']?.tables ?? {}assumes thepublicnamespace exists. While this is safe for Postgres (which defaults topublic), the function signature acceptsStorageLike | SqlStorage, which could include non-Postgres contracts. If this helper is Postgres-specific, consider adding a JSDoc comment clarifying this constraint.📝 Optional: Add JSDoc clarifying Postgres-specific usage
+/** + * Extract tables from the unbound namespace, falling back to the public + * namespace. Intended for Postgres contracts where public is the default. + */ export function unboundTables( storage: StorageLike | SqlStorage, ): Readonly<Record<string, StorageTable>> {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/2-sql/2-authoring/contract-psl/test/unbound-tables.ts` around lines 13 - 17, The helper currently assumes a 'public' namespace when falling back from UNBOUND_NAMESPACE_ID; update the logic around storage.namespaces and the fallback (the block using unbound, storage.namespaces[UNBOUND_NAMESPACE_ID]?.tables and storage.namespaces['public']?.tables ?? {}) to defensively handle a missing 'public' namespace (e.g., explicitly check storage.namespaces && storage.namespaces['public'] and return an empty object or throw a clear error), and add a brief JSDoc to the function explaining whether the helper is Postgres-specific (or that it will return an empty record when no public namespace exists) so callers understand the contract.skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts (1)
22-24: ⚡ Quick winPrefer
patheovernode:pathfor cross-platform path operations.Based on learnings, this repository prefers
patheover Node's built-innode:pathmodule for all TypeScript files, including tooling and scripts.📦 Proposed import change
import { execFile } from 'node:child_process'; import { access, copyFile, readdir, readFile, writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; +import { join } from 'pathe'; import { promisify } from 'node:util';Based on learnings: In the Prisma-next repository, prefer importing and using 'pathe' over the built-in 'node:path' module for path operations across the codebase (including CLI commands and tooling files).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts` around lines 22 - 24, Replace the Node built-in path import with pathe: change the import statement that currently reads "import { join } from 'node:path';" to import join (and any other path utilities you need) from 'pathe' and update any uses of join in regenerate-extension-public-baseline.ts accordingly so all path operations use pathe for cross-platform consistency; ensure there are no remaining references to 'node:path' in this file.skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts (1)
22-23: ⚡ Quick winPrefer
patheovernode:pathfor cross-platform path operations.Based on learnings, this repository prefers
patheover Node's built-innode:pathmodule for all TypeScript files, including tooling and scripts.📦 Proposed import change
import { readdir, readFile, writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; +import { join } from 'pathe';Based on learnings: In the Prisma-next repository, prefer importing and using 'pathe' over the built-in 'node:path' module for path operations across the codebase (including CLI commands and tooling files).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts` around lines 22 - 23, Replace the Node built-in path import with pathe: update the import that currently pulls join from 'node:path' to import join from 'pathe' (keeping readdir, readFile, writeFile from 'node:fs/promises' unchanged) so all path operations in migrate-contract-testing-imports.ts use pathe for cross-platform behavior; ensure any uses of join remain valid with the new import.skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts (1)
22-25: ⚡ Quick winPrefer
patheovernode:pathfor cross-platform path operations.Based on learnings, this repository prefers
patheover Node's built-innode:pathmodule for all TypeScript files, including tooling and scripts.📦 Proposed import change
import { execFile } from 'node:child_process'; import { access, readdir, readFile } from 'node:fs/promises'; -import { dirname, join } from 'node:path'; +import { dirname, join } from 'pathe'; import { promisify } from 'node:util';Based on learnings: In the Prisma-next repository, prefer importing and using 'pathe' over the built-in 'node:path' module for path operations across the codebase (including CLI commands and tooling files).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts` around lines 22 - 25, The file currently imports dirname and join from 'node:path'; replace those imports to use 'pathe' instead (import { dirname, join } from 'pathe') so path operations are cross-platform consistent with repo conventions; update any references to dirname and join in this file (and ensure no other node:path imports remain) and keep existing uses in functions like re-emit-postgres-public-default unchanged.skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts (1)
21-24: ⚡ Quick winPrefer
patheovernode:pathfor cross-platform path operations.Based on learnings, this repository prefers
patheover Node's built-innode:pathmodule for all TypeScript files, including tooling and scripts.📦 Proposed import change
import { execFile } from 'node:child_process'; import { access, readdir, readFile } from 'node:fs/promises'; -import { dirname, join } from 'node:path'; +import { dirname, join } from 'pathe'; import { promisify } from 'node:util';Based on learnings: In the Prisma-next repository, prefer importing and using 'pathe' over the built-in 'node:path' module for path operations across the codebase (including CLI commands and tooling files).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts` around lines 21 - 24, Replace imports of dirname and join from 'node:path' with the equivalent imports from 'pathe' (update the import statement that currently pulls dirname and join from 'node:path'); then update any usage sites in this file (functions or expressions referencing dirname and join) to use the pathe-provided functions (no API changes required). Also ensure the file's other imports (execFile, access, readdir, readFile, promisify) remain unchanged and that TypeScript types still resolve after swapping the path module to 'pathe'.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/2-sql/2-authoring/contract-psl/src/interpreter.ts`:
- Around line 232-245: The shared interpreter currently branches on targetId
(checks for targetId === 'postgres') inside defaultSqlNamespaceIdForTarget and
resolveNamespaceIdForSqlTarget which embeds Postgres-specific namespace policy;
remove those target-specific branches and instead delegate namespace resolution
to the target adapter API (i.e., call into the per-target adapter to obtain the
default/unspecified namespace). Specifically, eliminate the 'postgres' checks
from defaultSqlNamespaceIdForTarget and resolveNamespaceIdForSqlTarget and
replace them with adapter calls so the adapter (not these functions) returns
UNBOUND_NAMESPACE_ID, 'public', or undefined as appropriate; continue to use
UNSPECIFIED_PSL_NAMESPACE_NAME and UNBOUND_NAMESPACE_ID as inputs but move the
logic into the Postgres adapter implementation.
---
Nitpick comments:
In `@packages/2-sql/2-authoring/contract-psl/test/unbound-tables.ts`:
- Around line 13-17: The helper currently assumes a 'public' namespace when
falling back from UNBOUND_NAMESPACE_ID; update the logic around
storage.namespaces and the fallback (the block using unbound,
storage.namespaces[UNBOUND_NAMESPACE_ID]?.tables and
storage.namespaces['public']?.tables ?? {}) to defensively handle a missing
'public' namespace (e.g., explicitly check storage.namespaces &&
storage.namespaces['public'] and return an empty object or throw a clear error),
and add a brief JSDoc to the function explaining whether the helper is
Postgres-specific (or that it will return an empty record when no public
namespace exists) so callers understand the contract.
In `@packages/3-extensions/sql-orm-client/test/helpers.ts`:
- Around line 62-63: The non-null assertion on
Object.entries(contract.domain.namespaces)[0]! can throw if namespaces is empty;
replace it with a safe check or explicit assertion: retrieve entries via
Object.entries(contract.domain.namespaces), verify entries.length > 0 (or throw
a clear error mentioning contract id), then destructure into namespaceId and
namespace; alternatively add a comment asserting the test fixture guarantee.
Update the usage sites (the const [namespaceId, namespace] assignment in
helpers.ts and any logic depending on namespace) to rely on the validated
entries before calling contractModels(contract).
- Around line 265-271: The lookup for the users table across all namespaces
(using Object.values(raw.storage.namespaces).find(...)) should be made clearer
for future readers of buildStiPolyContract: either extract the search into a
small helper (e.g., findUsersStorageTable(namespaces)) and assign its result to
usersStorageTable, or add an inline comment above the current code explaining
why we must search every namespace; if the helper returns undefined, immediately
throw an Error('users table not found in any storage namespace') to keep the
null-check simple and obvious.
In
`@skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts`:
- Around line 22-23: Replace the Node built-in path import with pathe: update
the import that currently pulls join from 'node:path' to import join from
'pathe' (keeping readdir, readFile, writeFile from 'node:fs/promises' unchanged)
so all path operations in migrate-contract-testing-imports.ts use pathe for
cross-platform behavior; ensure any uses of join remain valid with the new
import.
In
`@skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts`:
- Around line 22-24: Replace the Node built-in path import with pathe: change
the import statement that currently reads "import { join } from 'node:path';" to
import join (and any other path utilities you need) from 'pathe' and update any
uses of join in regenerate-extension-public-baseline.ts accordingly so all path
operations use pathe for cross-platform consistency; ensure there are no
remaining references to 'node:path' in this file.
In
`@skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts`:
- Around line 21-24: Replace imports of dirname and join from 'node:path' with
the equivalent imports from 'pathe' (update the import statement that currently
pulls dirname and join from 'node:path'); then update any usage sites in this
file (functions or expressions referencing dirname and join) to use the
pathe-provided functions (no API changes required). Also ensure the file's other
imports (execFile, access, readdir, readFile, promisify) remain unchanged and
that TypeScript types still resolve after swapping the path module to 'pathe'.
In
`@skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts`:
- Around line 22-25: The file currently imports dirname and join from
'node:path'; replace those imports to use 'pathe' instead (import { dirname,
join } from 'pathe') so path operations are cross-platform consistent with repo
conventions; update any references to dirname and join in this file (and ensure
no other node:path imports remain) and keep existing uses in functions like
re-emit-postgres-public-default unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 14631e37-d3d3-4d89-a182-36b2d7d11fb0
⛔ Files ignored due to path filters (14)
examples/bundle-size/src/postgres/generated/contract.d.tsis excluded by!**/generated/**examples/bundle-size/src/postgres/generated/contract.jsonis excluded by!**/generated/**packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.jsonis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.jsonis excluded by!**/generated/**projects/target-extensible-ir-namespaces/slices/public-by-default/plan.mdis excluded by!projects/**projects/target-extensible-ir-namespaces/slices/public-by-default/spec.mdis excluded by!projects/**test/e2e/framework/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/e2e/framework/test/fixtures/generated/contract.jsonis excluded by!**/generated/**test/integration/test/sql-builder/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/integration/test/sql-builder/fixtures/generated/contract.jsonis excluded by!**/generated/**test/integration/test/sql-orm-client/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/integration/test/sql-orm-client/fixtures/generated/contract.jsonis excluded by!**/generated/**
📒 Files selected for processing (125)
apps/telemetry-backend/src/prisma/contract.d.tsapps/telemetry-backend/src/prisma/contract.jsonexamples/multi-extension-monorepo/app/src/contract.d.tsexamples/multi-extension-monorepo/app/src/contract.jsonexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.d.tsexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.jsonexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.jsonexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.tsexamples/multi-extension-monorepo/packages/audit/migrations/refs/head.jsonexamples/multi-extension-monorepo/packages/audit/src/contract.d.tsexamples/multi-extension-monorepo/packages/audit/src/contract.jsonexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.d.tsexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.jsonexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.jsonexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.tsexamples/multi-extension-monorepo/packages/feature-flags/migrations/refs/head.jsonexamples/multi-extension-monorepo/packages/feature-flags/src/contract.d.tsexamples/multi-extension-monorepo/packages/feature-flags/src/contract.jsonexamples/paradedb-demo/src/prisma/contract.d.tsexamples/paradedb-demo/src/prisma/contract.jsonexamples/prisma-next-cloudflare-worker/src/prisma/contract.d.tsexamples/prisma-next-cloudflare-worker/src/prisma/contract.jsonexamples/prisma-next-demo/src/prisma/contract.d.tsexamples/prisma-next-demo/src/prisma/contract.jsonexamples/prisma-next-demo/test/contract-authoring.test.tsexamples/prisma-next-demo/test/demo-dx.types.test.tsexamples/prisma-next-postgis-demo/src/prisma/contract.d.tsexamples/prisma-next-postgis-demo/src/prisma/contract.jsonexamples/react-router-demo/src/prisma/contract.d.tsexamples/react-router-demo/src/prisma/contract.jsonpackages/2-sql/1-core/contract/src/ir/sql-storage.tspackages/2-sql/1-core/contract/src/validators.tspackages/2-sql/1-core/contract/test/sql-storage.types.test-d.tspackages/2-sql/2-authoring/contract-psl/src/interpreter.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.defaults.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.extensions.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.polymorphism.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.relations.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.types.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.value-objects.test.tspackages/2-sql/2-authoring/contract-psl/test/provider.test.tspackages/2-sql/2-authoring/contract-psl/test/ts-psl-parity.test.tspackages/2-sql/2-authoring/contract-psl/test/unbound-tables.tspackages/2-sql/2-authoring/contract-ts/src/build-contract.tspackages/2-sql/2-authoring/contract-ts/src/contract-types.tspackages/2-sql/2-authoring/contract-ts/test/config-types.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.constraints.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.contract-definition.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.portability.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.namespaces.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.per-model-namespace.test.tspackages/2-sql/2-authoring/contract-ts/test/unbound-tables.tspackages/2-sql/9-family/src/core/ir/sql-contract-serializer-base.tspackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.d.tspackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.jsonpackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.jsonpackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.tspackages/3-extensions/paradedb/migrations/refs/head.jsonpackages/3-extensions/paradedb/src/contract.d.tspackages/3-extensions/paradedb/src/contract.jsonpackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.d.tspackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.jsonpackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.jsonpackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.tspackages/3-extensions/pgvector/migrations/refs/head.jsonpackages/3-extensions/pgvector/src/contract.d.tspackages/3-extensions/pgvector/src/contract.jsonpackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.d.tspackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.jsonpackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.jsonpackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.tspackages/3-extensions/postgis/migrations/refs/head.jsonpackages/3-extensions/postgis/src/contract.d.tspackages/3-extensions/postgis/src/contract.jsonpackages/3-extensions/sql-orm-client/src/collection-contract.tspackages/3-extensions/sql-orm-client/src/model-accessor.tspackages/3-extensions/sql-orm-client/src/query-plan-meta.tspackages/3-extensions/sql-orm-client/src/query-plan-mutations.tspackages/3-extensions/sql-orm-client/src/where-binding.tspackages/3-extensions/sql-orm-client/test/helpers.tspackages/3-extensions/sql-orm-client/test/mutation-executor.test.tspackages/3-extensions/sql-orm-client/test/unbound-tables.tspackages/3-targets/3-targets/postgres/src/core/migrations/planner-strategies.tspackages/3-targets/3-targets/postgres/src/core/migrations/planner.tspackages/3-targets/3-targets/postgres/src/core/migrations/runner.tspackages/3-targets/3-targets/postgres/src/core/migrations/verify-postgres-namespaces.tspackages/3-targets/3-targets/postgres/src/core/postgres-schema.tspackages/3-targets/3-targets/postgres/test/migrations/enum-collision.test.tspackages/3-targets/3-targets/postgres/test/postgres-schema.test.tsskills-contrib/record-upgrade-instructions/SKILL.mdskills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/instructions.mdskills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/migrate-contract-testing-imports.tsskills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.tsskills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/instructions.mdskills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.tsskills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.tstest/integration/test/authoring/paradedb-bm25-narrowing.test.tstest/integration/test/authoring/parity/callback-mode-scalars/expected.contract.jsontest/integration/test/authoring/parity/core-surface/expected.contract.jsontest/integration/test/authoring/parity/default-cuid-2/expected.contract.jsontest/integration/test/authoring/parity/default-dbgenerated/expected.contract.jsontest/integration/test/authoring/parity/default-nanoid-16/expected.contract.jsontest/integration/test/authoring/parity/default-nanoid/expected.contract.jsontest/integration/test/authoring/parity/default-pack-slugid/expected.contract.jsontest/integration/test/authoring/parity/default-ulid/expected.contract.jsontest/integration/test/authoring/parity/default-uuid-v4/expected.contract.jsontest/integration/test/authoring/parity/default-uuid-v7/expected.contract.jsontest/integration/test/authoring/parity/map-attributes/expected.contract.jsontest/integration/test/authoring/parity/pgvector-named-type/expected.contract.jsontest/integration/test/authoring/parity/relation-backrelation-list/expected.contract.jsontest/integration/test/authoring/side-by-side-contracts.test.tstest/integration/test/authoring/side-by-side/postgres/contract.jsontest/integration/test/cli.emit-cli-process.e2e.test.tstest/integration/test/contract-builder.test.tstest/integration/test/contract-builder.types.test-d.tstest/integration/test/dsl-type-inference.test-d.tstest/integration/test/family.schema-verify.dependencies.integration.test.tstest/integration/test/family.schema-verify.types.test.tstest/integration/test/fixtures/contract.d.tstest/integration/test/fixtures/contract.jsontest/integration/test/sql-orm-client/collection-mutation-defaults.test.tstest/integration/test/sql-orm-client/fixtures/contract.tstest/integration/test/sql-orm-client/upsert.test.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/integration/test/vite-plugin.hmr.e2e.test.ts (1)
19-23: ⚡ Quick winRename
unboundUserColumnsto match current namespace semantics.Line 19 still encodes the old
__unbound__concept, but the helper now reads fromPOSTGRES_DEFAULT_NAMESPACE(public). Renaming will reduce future confusion in HMR assertions.♻️ Suggested rename
-function unboundUserColumns(storage: { +function defaultNamespaceUserColumns(storage: { namespaces: Record<string, { tables: { user: { columns: Record<string, unknown> } } }>; }) { return storage.namespaces[POSTGRES_DEFAULT_NAMESPACE]!.tables.user.columns; }-expect(unboundUserColumns(initialContract.storage)).not.toHaveProperty('name'); +expect(defaultNamespaceUserColumns(initialContract.storage)).not.toHaveProperty('name');🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/integration/test/vite-plugin.hmr.e2e.test.ts` around lines 19 - 23, Rename the helper function unboundUserColumns to a name that reflects it reads from the default namespace (e.g., defaultNamespaceUserColumns or userColumnsInDefaultNamespace), update the function identifier and all call sites in the test to the new name, and keep the implementation using POSTGRES_DEFAULT_NAMESPACE as-is (the symbol POSTGRES_DEFAULT_NAMESPACE and the function unboundUserColumns should be replaced consistently to avoid confusion in HMR assertions).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@test/integration/test/vite-plugin.hmr.e2e.test.ts`:
- Around line 19-23: Rename the helper function unboundUserColumns to a name
that reflects it reads from the default namespace (e.g.,
defaultNamespaceUserColumns or userColumnsInDefaultNamespace), update the
function identifier and all call sites in the test to the new name, and keep the
implementation using POSTGRES_DEFAULT_NAMESPACE as-is (the symbol
POSTGRES_DEFAULT_NAMESPACE and the function unboundUserColumns should be
replaced consistently to avoid confusion in HMR assertions).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 416bbb03-d279-4bca-a0a2-66474e04ba7b
📒 Files selected for processing (11)
packages/1-framework/3-tooling/cli-telemetry/test/integration.test.tspackages/1-framework/3-tooling/cli/test/load-ts-contract.test.tspackages/3-extensions/postgres/test/psl-namespace-qualifier-routing.test.tstest/e2e/framework/test/ddl.test.tstest/integration/test/authoring/psl-index-type-options.integration.test.tstest/integration/test/cli.db-sign.e2e.test.tstest/integration/test/cli.emit.test.tstest/integration/test/sql-orm-client/helpers.tstest/integration/test/sql-orm-client/unbound-tables.tstest/integration/test/value-objects/value-objects.integration.test.tstest/integration/test/vite-plugin.hmr.e2e.test.ts
4510d61 to
9eb8d7d
Compare
Scope the public-by-default slice: un-namespaced Postgres models default
to the `public` namespace at the PSL interpreter; `__unbound__` stays an
explicit `namespace unbound {}` opt-in; the two hardcoded `'public'` DDL
fakes derive from the real namespace; ~53 Postgres fixtures regenerate.
Folds in the missing 0.11-to-0.12 upgrade entries for both this change
and the merged domain-plane (TML-2751) reshape, in both upgrade clusters.
Signed-off-by: Will Madden <madden@prisma.io>
PSL resolveNamespaceIdForSqlTarget and the TS build-contract path now
assign namespace id public for Postgres when no namespace block is
given; namespace unbound {} still maps to __unbound__. SQLite and Mongo
are unchanged.
Tests and the sql-orm-client integration fixture follow the new shape.
Signed-off-by: Will Madden <madden@prisma.io>
Re-emit committed contract.json and contract.d.ts artefacts after the public-by-default namespace resolution change. Signed-off-by: Will Madden <madden@prisma.io>
…ublic default Re-emit committed contract.json and contract.d.ts artefacts for Postgres apps and examples where un-namespaced models now resolve to the public namespace. Signed-off-by: Will Madden <madden@prisma.io>
…lt namespace
Update migration.ts, migration.json, end-contract.{json,d.ts}, and
refs/head.json for the three Postgres extension packs (pgvector, postgis,
paradedb) and the two multi-extension-monorepo example packages (audit,
feature-flags) after the public-by-default namespace resolution change.
Per the Path-B/A authoring loop (ADR 212):
- Updated describe().to in each migration.ts to the new storageHash
produced by prisma-next contract emit.
- Re-ran node migration.ts to regenerate ops.json + migration.json with
new to/migrationHash.
- Pinned refs/head.json.hash to match the new storageHash.
- Copied src/contract.{json,d.ts} to end-contract.{json,d.ts} (baseline
migration ends at the current contract state).
ops.json unchanged for all three standalone extension packs.
Signed-off-by: Will Madden <madden@prisma.io>
Fake 1 — `PostgresUnboundSchema.ddlSchemaName` sibling-public projection
The override that returned `'public'` when a sibling public namespace
existed was the bridge for the old world where un-namespaced models
lived in `__unbound__`. Un-namespaced models now resolve to `public`
directly; `__unbound__` is only reachable via an explicit
`namespace unbound {}` opt-in. Deleting the override restores the
base-class behaviour (`this.id` = `UNBOUND_NAMESPACE_ID`), so that
`qualifyTableName` produces correctly *unqualified* DDL for explicit-
unbound tables (search_path resolves the schema at runtime).
Fake 2 — `defaultSchema: 'public'` planner/runner config default
`PlannerConfig`/`RunnerConfig` and their `DEFAULT_*` constants are
removed entirely. `createPostgresMigrationPlanner` and
`createPostgresMigrationRunner` are never called with a config object.
Both `planSql` and `executeOnConnection` now derive the effective schema
name from the contract's storage namespaces (first non-UNBOUND_NAMESPACE_ID
entry, falling back to UNBOUND_NAMESPACE_ID for explicit-unbound-only
contracts).
Updated tests:
- postgres-schema.test.ts: unbound singleton returns UNBOUND_NAMESPACE_ID
regardless of sibling namespaces.
- enum-collision.test.ts: AlterColumnTypeCall for an unbound-namespace table
now carries UNBOUND_NAMESPACE_ID as schemaName (→ unqualified DDL).
Gates: 297/297 unit tests, typecheck clean, fixtures:check exit 0, lint:deps clean.
Signed-off-by: Will Madden <madden@prisma.io>
The public-by-default slice moves un-namespaced Postgres tables into the
'public' namespace, so a public-only contract has no '__unbound__' slot.
The brand added in TML-2727 required '__unbound__' on every SqlStorage,
causing 'Contract<SqlStorage>' to reject valid public-only contracts.
Changes:
- Drop `& { readonly __unbound__: SqlNamespace }` from SqlStorageInput.namespaces
and the SqlStorage class field; namespaces is now `Readonly<Record<string, SqlNamespace>>`.
- Add sql-storage.types.test-d.ts with positive assertions for both
public-only and __unbound__-only contracts.
- Update the phantom-__unbound__ injection in SqlContractSerializerBase and
validators.ts: keep the runtime shim but update comments and blindCast
reasons to reflect it is a compatibility convenience, not a type guarantee.
- Update contract-types.ts: introduce DefaultStorageNamespaceId<Definition>
so the builder's inferred return type uses 'public' for Postgres targets and
'__unbound__' for others, aligning type-level and runtime shapes.
- Fix sql-orm-client source files (collection-contract, model-accessor,
query-plan-meta, query-plan-mutations, where-binding): replace hardcoded
namespaces[UNBOUND_NAMESPACE_ID] table lookups with scan-across-all-namespaces
(same pattern as codecRefForStorageColumn), so table resolution works for
both __unbound__ and public namespaces.
- Fix sql-orm-client test helpers (helpers.ts, unbound-tables.ts): update
withPatchedDomainModels, unboundDomainModels, buildStiPolyContract, and
unboundTables to use the actual namespace the contract carries rather than
the hardcoded __unbound__ slot.
- Update numerous integration/demo test files: replace __unbound__ / UNBOUND_*
namespace references with 'public' where the contract now uses 'public',
and fix TS4111 dot-notation access to bracket notation.
Signed-off-by: Will Madden <madden@prisma.io>
…+ extension-baseline upgrade scope Signed-off-by: Will Madden <madden@prisma.io>
…plane backfill. Document the public default namespace flip and symmetric domain plane reshape for both user and extension-author skill clusters, with colocated re-emit and codemod scripts for the actionable migrations. Signed-off-by: Will Madden <madden@prisma.io>
… existence, not per-PR entry Signed-off-by: Will Madden <madden@prisma.io>
…mespace Update Postgres test assertions and helpers to index the `public` namespace instead of `__unbound__` for un-namespaced models, and refresh the E2E DDL inline snapshot for schema-qualified CREATE TABLE output. Also isolate Gemini CLI telemetry detection from host agent env markers. Signed-off-by: Will Madden <madden@prisma.io>
…ult namespace Signed-off-by: Will Madden <madden@prisma.io>
…oject scope explicit-dsl (TML-2550) is required for the Supabase integration (colliding auth.*/public.* names the default-namespace fallback cannot disambiguate) but is purely additive on runtime-qualification. Decouple it: the project now closes after runtime-qualification, and explicit-dsl is tracked standalone and parallelizable rather than as a deferrable in-project unit. Signed-off-by: Will Madden <madden@prisma.io>
9eb8d7d to
eccbbc0
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
packages/3-extensions/sql-orm-client/src/query-plan-mutations.ts (1)
21-24: 💤 Low valueConsider removing unnecessary cast.
The
as StorageTable | undefinedcast on line 23 might be redundant—TypeScript should infer the correct type from the optional chaining and thefindpredicate. If the cast is required due to a type-narrowing limitation, consider adding a brief comment explaining why.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/3-extensions/sql-orm-client/src/query-plan-mutations.ts` around lines 21 - 24, The function unboundTable contains an unnecessary type cast "as StorageTable | undefined"; remove this cast and let TypeScript infer the return type from the find + optional chaining (function: unboundTable, types: Contract<SqlStorage>, StorageTable). If the cast was added because of a TypeScript narrowing limitation, instead keep the cast but add a brief inline comment explaining the narrowing issue and why the cast is required (e.g., TS cannot infer through optional chaining), referencing unboundTable and the storage.namespaces lookup.skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts (1)
24-24: ⚡ Quick winPrefer
patheovernode:pathfor path operations.This codebase prefers
pathefor path operations in tooling and source files. Based on learnings, in the prisma/prisma-next repo, prefer usingpatheover Node's built-innode:pathfor any TypeScript file (including tooling).♻️ Proposed fix
-import { dirname, join } from 'node:path'; +import { dirname, join } from 'pathe';🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts` at line 24, Replace the Node built-in path import with pathe: change the import of dirname and join from 'node:path' to import them from 'pathe' (update the import statement that currently reads "import { dirname, join } from 'node:path';" to use 'pathe') so all path operations in re-emit-postgres-public-default.ts use the project's preferred pathe utilities; ensure any other references in the file still use the same symbol names (dirname, join).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@packages/3-extensions/sql-orm-client/src/query-plan-mutations.ts`:
- Around line 21-24: The function unboundTable contains an unnecessary type cast
"as StorageTable | undefined"; remove this cast and let TypeScript infer the
return type from the find + optional chaining (function: unboundTable, types:
Contract<SqlStorage>, StorageTable). If the cast was added because of a
TypeScript narrowing limitation, instead keep the cast but add a brief inline
comment explaining the narrowing issue and why the cast is required (e.g., TS
cannot infer through optional chaining), referencing unboundTable and the
storage.namespaces lookup.
In
`@skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts`:
- Line 24: Replace the Node built-in path import with pathe: change the import
of dirname and join from 'node:path' to import them from 'pathe' (update the
import statement that currently reads "import { dirname, join } from
'node:path';" to use 'pathe') so all path operations in
re-emit-postgres-public-default.ts use the project's preferred pathe utilities;
ensure any other references in the file still use the same symbol names
(dirname, join).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 51bdfeae-badd-4437-a7bb-65d62fe88d7a
⛔ Files ignored due to path filters (16)
examples/bundle-size/src/postgres/generated/contract.d.tsis excluded by!**/generated/**examples/bundle-size/src/postgres/generated/contract.jsonis excluded by!**/generated/**packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.jsonis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.jsonis excluded by!**/generated/**projects/target-extensible-ir-namespaces/plan.mdis excluded by!projects/**projects/target-extensible-ir-namespaces/slices/public-by-default/plan.mdis excluded by!projects/**projects/target-extensible-ir-namespaces/slices/public-by-default/spec.mdis excluded by!projects/**projects/target-extensible-ir-namespaces/spec.mdis excluded by!projects/**test/e2e/framework/test/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/e2e/framework/test/fixtures/generated/contract.jsonis excluded by!**/generated/**test/integration/test/sql-builder/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/integration/test/sql-builder/fixtures/generated/contract.jsonis excluded by!**/generated/**test/integration/test/sql-orm-client/fixtures/generated/contract.d.tsis excluded by!**/generated/**test/integration/test/sql-orm-client/fixtures/generated/contract.jsonis excluded by!**/generated/**
📒 Files selected for processing (138)
apps/telemetry-backend/src/prisma/contract.d.tsapps/telemetry-backend/src/prisma/contract.jsonexamples/multi-extension-monorepo/app/src/contract.d.tsexamples/multi-extension-monorepo/app/src/contract.jsonexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.d.tsexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.jsonexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.jsonexamples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.tsexamples/multi-extension-monorepo/packages/audit/migrations/refs/head.jsonexamples/multi-extension-monorepo/packages/audit/src/contract.d.tsexamples/multi-extension-monorepo/packages/audit/src/contract.jsonexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.d.tsexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.jsonexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.jsonexamples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.tsexamples/multi-extension-monorepo/packages/feature-flags/migrations/refs/head.jsonexamples/multi-extension-monorepo/packages/feature-flags/src/contract.d.tsexamples/multi-extension-monorepo/packages/feature-flags/src/contract.jsonexamples/paradedb-demo/src/prisma/contract.d.tsexamples/paradedb-demo/src/prisma/contract.jsonexamples/prisma-next-cloudflare-worker/src/prisma/contract.d.tsexamples/prisma-next-cloudflare-worker/src/prisma/contract.jsonexamples/prisma-next-demo/src/prisma/contract.d.tsexamples/prisma-next-demo/src/prisma/contract.jsonexamples/prisma-next-demo/test/contract-authoring.test.tsexamples/prisma-next-demo/test/demo-dx.types.test.tsexamples/prisma-next-postgis-demo/src/prisma/contract.d.tsexamples/prisma-next-postgis-demo/src/prisma/contract.jsonexamples/react-router-demo/src/prisma/contract.d.tsexamples/react-router-demo/src/prisma/contract.jsonexamples/react-router-demo/test/offline-emit.e2e.test.tsexamples/react-router-demo/test/react-router.smoke.e2e.test.tspackages/1-framework/3-tooling/cli-telemetry/test/integration.test.tspackages/1-framework/3-tooling/cli/test/load-ts-contract.test.tspackages/2-sql/1-core/contract/src/ir/sql-storage.tspackages/2-sql/1-core/contract/src/validators.tspackages/2-sql/1-core/contract/test/sql-storage.types.test-d.tspackages/2-sql/2-authoring/contract-psl/src/interpreter.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.defaults.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.extensions.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.polymorphism.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.relations.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.types.test.tspackages/2-sql/2-authoring/contract-psl/test/interpreter.value-objects.test.tspackages/2-sql/2-authoring/contract-psl/test/provider.test.tspackages/2-sql/2-authoring/contract-psl/test/ts-psl-parity.test.tspackages/2-sql/2-authoring/contract-psl/test/unbound-tables.tspackages/2-sql/2-authoring/contract-ts/src/build-contract.tspackages/2-sql/2-authoring/contract-ts/src/contract-types.tspackages/2-sql/2-authoring/contract-ts/test/config-types.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.constraints.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.contract-definition.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.portability.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.namespaces.test.tspackages/2-sql/2-authoring/contract-ts/test/contract-builder.per-model-namespace.test.tspackages/2-sql/2-authoring/contract-ts/test/unbound-tables.tspackages/2-sql/9-family/src/core/ir/sql-contract-serializer-base.tspackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.d.tspackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.jsonpackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.jsonpackages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.tspackages/3-extensions/paradedb/migrations/refs/head.jsonpackages/3-extensions/paradedb/src/contract.d.tspackages/3-extensions/paradedb/src/contract.jsonpackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.d.tspackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.jsonpackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.jsonpackages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.tspackages/3-extensions/pgvector/migrations/refs/head.jsonpackages/3-extensions/pgvector/src/contract.d.tspackages/3-extensions/pgvector/src/contract.jsonpackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.d.tspackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.jsonpackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.jsonpackages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.tspackages/3-extensions/postgis/migrations/refs/head.jsonpackages/3-extensions/postgis/src/contract.d.tspackages/3-extensions/postgis/src/contract.jsonpackages/3-extensions/postgres/test/psl-namespace-qualifier-routing.test.tspackages/3-extensions/sql-orm-client/src/collection-contract.tspackages/3-extensions/sql-orm-client/src/model-accessor.tspackages/3-extensions/sql-orm-client/src/query-plan-meta.tspackages/3-extensions/sql-orm-client/src/query-plan-mutations.tspackages/3-extensions/sql-orm-client/src/where-binding.tspackages/3-extensions/sql-orm-client/test/helpers.tspackages/3-extensions/sql-orm-client/test/mutation-executor.test.tspackages/3-extensions/sql-orm-client/test/unbound-tables.tspackages/3-targets/3-targets/postgres/src/core/migrations/planner-strategies.tspackages/3-targets/3-targets/postgres/src/core/migrations/planner.tspackages/3-targets/3-targets/postgres/src/core/migrations/runner.tspackages/3-targets/3-targets/postgres/src/core/migrations/verify-postgres-namespaces.tspackages/3-targets/3-targets/postgres/src/core/postgres-schema.tspackages/3-targets/3-targets/postgres/test/migrations/enum-collision.test.tspackages/3-targets/3-targets/postgres/test/postgres-schema.test.tsskills-contrib/record-upgrade-instructions/SKILL.mdskills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/instructions.mdskills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/migrate-contract-testing-imports.tsskills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.tsskills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/instructions.mdskills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.tsskills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-postgres-public-default.tstest/e2e/framework/test/ddl.test.tstest/integration/test/authoring/paradedb-bm25-narrowing.test.tstest/integration/test/authoring/parity/callback-mode-scalars/expected.contract.jsontest/integration/test/authoring/parity/core-surface/expected.contract.jsontest/integration/test/authoring/parity/default-cuid-2/expected.contract.jsontest/integration/test/authoring/parity/default-dbgenerated/expected.contract.jsontest/integration/test/authoring/parity/default-nanoid-16/expected.contract.jsontest/integration/test/authoring/parity/default-nanoid/expected.contract.jsontest/integration/test/authoring/parity/default-pack-slugid/expected.contract.jsontest/integration/test/authoring/parity/default-ulid/expected.contract.jsontest/integration/test/authoring/parity/default-uuid-v4/expected.contract.jsontest/integration/test/authoring/parity/default-uuid-v7/expected.contract.jsontest/integration/test/authoring/parity/map-attributes/expected.contract.jsontest/integration/test/authoring/parity/pgvector-named-type/expected.contract.jsontest/integration/test/authoring/parity/relation-backrelation-list/expected.contract.jsontest/integration/test/authoring/psl-index-type-options.integration.test.tstest/integration/test/authoring/side-by-side-contracts.test.tstest/integration/test/authoring/side-by-side/postgres/contract.jsontest/integration/test/cli.db-sign.e2e.test.tstest/integration/test/cli.emit-cli-process.e2e.test.tstest/integration/test/cli.emit.test.tstest/integration/test/contract-builder.test.tstest/integration/test/contract-builder.types.test-d.tstest/integration/test/dsl-type-inference.test-d.tstest/integration/test/family.schema-verify.dependencies.integration.test.tstest/integration/test/family.schema-verify.types.test.tstest/integration/test/fixtures/contract.d.tstest/integration/test/fixtures/contract.jsontest/integration/test/sql-orm-client/collection-mutation-defaults.test.tstest/integration/test/sql-orm-client/fixtures/contract.tstest/integration/test/sql-orm-client/helpers.tstest/integration/test/sql-orm-client/unbound-tables.tstest/integration/test/sql-orm-client/upsert.test.tstest/integration/test/value-objects/value-objects.integration.test.tstest/integration/test/vite-plugin.hmr.e2e.test.ts
✅ Files skipped from review due to trivial changes (45)
- packages/3-extensions/pgvector/migrations/refs/head.json
- examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.ts
- packages/3-extensions/paradedb/migrations/refs/head.json
- examples/multi-extension-monorepo/packages/feature-flags/migrations/refs/head.json
- examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.ts
- packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.json
- test/integration/test/cli.emit.test.ts
- packages/3-targets/3-targets/postgres/src/core/migrations/verify-postgres-namespaces.ts
- examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.json
- packages/3-extensions/pgvector/src/contract.json
- packages/2-sql/1-core/contract/src/validators.ts
- test/integration/test/authoring/parity/pgvector-named-type/expected.contract.json
- packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.json
- test/integration/test/authoring/parity/default-nanoid-16/expected.contract.json
- examples/paradedb-demo/src/prisma/contract.json
- test/e2e/framework/test/ddl.test.ts
- examples/multi-extension-monorepo/packages/feature-flags/src/contract.d.ts
- examples/multi-extension-monorepo/app/src/contract.json
- packages/3-extensions/postgis/src/contract.json
- examples/react-router-demo/src/prisma/contract.json
- examples/multi-extension-monorepo/packages/feature-flags/src/contract.json
- examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.json
- test/integration/test/authoring/parity/default-pack-slugid/expected.contract.json
- test/integration/test/authoring/side-by-side-contracts.test.ts
- packages/2-sql/9-family/src/core/ir/sql-contract-serializer-base.ts
- packages/3-targets/3-targets/postgres/src/core/migrations/planner-strategies.ts
- test/integration/test/authoring/psl-index-type-options.integration.test.ts
- skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/instructions.md
- test/integration/test/fixtures/contract.d.ts
- test/integration/test/authoring/parity/default-nanoid/expected.contract.json
- test/integration/test/authoring/parity/default-uuid-v4/expected.contract.json
- examples/paradedb-demo/src/prisma/contract.d.ts
- examples/multi-extension-monorepo/app/src/contract.d.ts
- test/integration/test/authoring/parity/core-surface/expected.contract.json
- test/integration/test/authoring/parity/map-attributes/expected.contract.json
- test/integration/test/authoring/parity/default-ulid/expected.contract.json
- test/integration/test/authoring/parity/default-cuid-2/expected.contract.json
- apps/telemetry-backend/src/prisma/contract.json
- examples/prisma-next-cloudflare-worker/src/prisma/contract.json
- examples/prisma-next-demo/src/prisma/contract.json
- skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/instructions.md
- packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.json
- packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.json
- examples/prisma-next-demo/src/prisma/contract.d.ts
- examples/multi-extension-monorepo/packages/audit/src/contract.d.ts
🚧 Files skipped from review as they are similar to previous changes (76)
- packages/2-sql/2-authoring/contract-psl/test/interpreter.value-objects.test.ts
- test/integration/test/authoring/paradedb-bm25-narrowing.test.ts
- packages/1-framework/3-tooling/cli-telemetry/test/integration.test.ts
- test/integration/test/sql-orm-client/collection-mutation-defaults.test.ts
- packages/3-extensions/postgis/migrations/refs/head.json
- examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.json
- packages/1-framework/3-tooling/cli/test/load-ts-contract.test.ts
- packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.ts
- packages/2-sql/2-authoring/contract-psl/test/unbound-tables.ts
- test/integration/test/sql-orm-client/unbound-tables.ts
- packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.json
- test/integration/test/family.schema-verify.types.test.ts
- packages/2-sql/1-core/contract/test/sql-storage.types.test-d.ts
- packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.ts
- examples/react-router-demo/test/react-router.smoke.e2e.test.ts
- packages/3-targets/3-targets/postgres/test/postgres-schema.test.ts
- test/integration/test/cli.db-sign.e2e.test.ts
- packages/3-extensions/sql-orm-client/src/where-binding.ts
- packages/2-sql/2-authoring/contract-psl/test/interpreter.extensions.test.ts
- packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.d.ts
- examples/react-router-demo/test/offline-emit.e2e.test.ts
- packages/3-extensions/sql-orm-client/src/collection-contract.ts
- packages/2-sql/2-authoring/contract-ts/test/contract-builder.contract-definition.test.ts
- packages/2-sql/2-authoring/contract-ts/test/config-types.test.ts
- examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.d.ts
- packages/2-sql/2-authoring/contract-ts/src/contract-types.ts
- packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.ts
- packages/3-extensions/sql-orm-client/src/query-plan-meta.ts
- examples/multi-extension-monorepo/packages/audit/src/contract.json
- test/integration/test/authoring/parity/relation-backrelation-list/expected.contract.json
- examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.d.ts
- packages/3-extensions/postgis/src/contract.d.ts
- packages/3-extensions/sql-orm-client/test/mutation-executor.test.ts
- packages/3-extensions/paradedb/src/contract.d.ts
- packages/3-extensions/pgvector/src/contract.d.ts
- packages/2-sql/2-authoring/contract-psl/test/interpreter.relations.test.ts
- packages/3-targets/3-targets/postgres/src/core/postgres-schema.ts
- packages/2-sql/2-authoring/contract-psl/test/ts-psl-parity.test.ts
- examples/prisma-next-demo/test/demo-dx.types.test.ts
- packages/2-sql/2-authoring/contract-ts/test/contract-builder.constraints.test.ts
- packages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.portability.test.ts
- packages/2-sql/1-core/contract/src/ir/sql-storage.ts
- packages/2-sql/2-authoring/contract-psl/test/interpreter.polymorphism.test.ts
- test/integration/test/authoring/side-by-side/postgres/contract.json
- test/integration/test/sql-orm-client/helpers.ts
- packages/3-extensions/sql-orm-client/test/helpers.ts
- test/integration/test/vite-plugin.hmr.e2e.test.ts
- packages/2-sql/2-authoring/contract-ts/test/contract-builder.namespaces.test.ts
- packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.d.ts
- examples/multi-extension-monorepo/packages/audit/migrations/refs/head.json
- packages/2-sql/2-authoring/contract-psl/test/provider.test.ts
- packages/2-sql/2-authoring/contract-psl/test/interpreter.types.test.ts
- packages/2-sql/2-authoring/contract-ts/test/unbound-tables.ts
- packages/3-extensions/postgres/test/psl-namespace-qualifier-routing.test.ts
- examples/prisma-next-postgis-demo/src/prisma/contract.d.ts
- apps/telemetry-backend/src/prisma/contract.d.ts
- examples/react-router-demo/src/prisma/contract.d.ts
- skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts
- packages/2-sql/2-authoring/contract-psl/test/interpreter.test.ts
- test/integration/test/contract-builder.types.test-d.ts
- test/integration/test/value-objects/value-objects.integration.test.ts
- packages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.test.ts
- test/integration/test/authoring/parity/default-uuid-v7/expected.contract.json
- packages/2-sql/2-authoring/contract-psl/test/interpreter.defaults.test.ts
- packages/3-extensions/sql-orm-client/test/unbound-tables.ts
- skills/upgrade/prisma-next-upgrade/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts
- packages/2-sql/2-authoring/contract-psl/src/interpreter.ts
- packages/3-extensions/paradedb/src/contract.json
- test/integration/test/family.schema-verify.dependencies.integration.test.ts
- packages/3-extensions/sql-orm-client/src/model-accessor.ts
- test/integration/test/authoring/parity/callback-mode-scalars/expected.contract.json
- packages/3-targets/3-targets/postgres/src/core/migrations/runner.ts
- packages/3-targets/3-targets/postgres/src/core/migrations/planner.ts
- packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.json
- test/integration/test/contract-builder.test.ts
- skills/extension-author/prisma-next-extension-upgrade/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts
Linked issue
Refs TML-2760. Unblocks TML-2605 (runtime-qualification). Backfills the upgrade entry that TML-2751 (domain-plane, merged in #653) shipped without. Follow-up TML-2764 hardens the coverage gate that let that miss through.
At a glance
An un-namespaced Postgres model used to fall through to the
__unbound__sentinel. It now resolves to a realpublicnamespace, end-to-end — domain plane, storage plane, and the storagekind:"roots": { - "user": { "model": "User", "namespace": "__unbound__" } + "user": { "model": "User", "namespace": "public" } }, "domain": { "namespaces": { - "__unbound__": { "models": { "User": { … } } } + "public": { "models": { "User": { … } } } "storage": { "namespaces": { - "__unbound__": { "id": "__unbound__", "kind": "postgres-unbound-schema", … } + "public": { "id": "public", "kind": "postgres-schema", … }__unbound__doesn't disappear — it's now reachable only through an explicitnamespace unbound { … }PSL block. SQLite and Mongo are untouched; they keep__unbound__as their default.Decision
This slice makes
publica real Postgres namespace at authoring/DDL time, so the next slice can render honest"public"."user"qualification instead of a faked string prefix. It carries five pieces:public(was:undefined→__unbound__). The PSL interpreter and the TS contract builder move in lockstep — a parity test pins that they agree.__unbound__becomes an explicit opt-in. Onlynamespace unbound { … }lands a Postgres model in__unbound__. No diagnostic on the opt-in — the block is self-documenting (per the explicit-opt-in-over-diagnostics rule).'public'DDL fakes. Withpublica real namespace id, the planner'sdefaultSchema: 'public'andPostgresUnboundSchema.ddlSchemaNameprojection are removed; the schema name now derives from the namespace.SqlStorage__unbound__brand (discovered mid-slice). TheSqlStoragetype required__unbound__as a mandatory namespace key — a stale assertion that made apublic-only contract failContract<SqlStorage>and broke the postgis demo typecheck. The brand is relaxed to optional; it was never runtime-load-bearing (all production reads already use?./??).0.11-to-0.12entries for public-by-default and the domain-plane reshape that #653 shipped without one.How it fits together
contract-psl/src/interpreter.ts):resolveNamespaceIdForSqlTargetreturnspublicfor the un-namespaced Postgres case; the explicitunboundbranch is unchanged.contract-ts/src/build-contract.ts): aDefaultStorageNamespaceId<Definition>helper makes the inferred return type usepublicfor Postgres and__unbound__elsewhere, so type-level and runtime shapes agree and the parity test stays green.postgres/src/core/postgres-schema.ts,…/migrations/planner.ts,…/runner.ts): effective schema is derived fromcontract.storage.namespacesrather than a hardcoded string.sql/1-core/contract/src/ir/sql-storage.ts): drop the& { readonly __unbound__: SqlNamespace }intersection;sql-orm-clienttable lookups switch from indexingnamespaces['__unbound__']to scanning all namespaces.telemetry-backendapp contracts, and the pgvector/postgis/paradedb install migration baselines (theirstorageHash/head-ref shifted with the namespace key).Reviewer notes
Contract<SqlStorage>. I investigated whether the required__unbound__key was load-bearing: it was a stale type assertion from TML-2727, not a runtime invariant (every production read path already uses optional access). Relaxing it here was the minimal unblock; the query-builder's own__unbound__dependency (UnboundTables<C>) is deliberately left to TML-2605. Thesql-orm-client"scan all namespaces" change is the same story — a regression introduced by the default flip, fixed in place.main(TML-2751: wire symmetric domain plane (domain.namespaces) #653), so its substrate diff vsorigin/mainis empty; the entries were authored from the TML-2751: wire symmetric domain plane (domain.namespaces) #653 diff per the skill's skipped-publishes guidance. The two public-by-default entries were validated by execution (re-emit onprisma-next-demo, baseline regen on the three extensions).check:upgrade-coverageonly asserts the transition directory exists, not that this PR has a matching entry. That gap is exactly how TML-2751: wire symmetric domain plane (domain.namespaces) #653 shipped undocumented. I corrected therecord-upgrade-instructionsskill body to flag the limit for reviewers and filed TML-2764 to harden the gate.side-by-side-contracts.test.tsandcontract-builder.test.tspin the new default.Verification
Run on the final HEAD:
pnpm typecheck— green (incl. the previously-broken postgis demo)pnpm fixtures:check— green (0 Postgres default models left under__unbound__)pnpm test—target-postgres(297),sql-orm-client(505, 3 skip), contract package type tests greenpnpm lint:deps— cleanpnpm check:upgrade-coverage— greenFollow-ups
"public"."user"on the query path) and eliminating the transitional projection helpers. This slice deliberately stops at authoring/DDL.Alternatives considered
__unbound__as the default and project topublicat query time. Rejected: it keeps the faked-prefix smell alive and pushes the honesty problem into the runtime layer. Makingpublicreal at the source is the root fix.__unbound__vianamespace unbound {}. Rejected per the explicit-opt-in-over-diagnostics rule — the block already encodes the intent at the call site; a diagnostic on a deliberate path is noise.Skill update
0.11-to-0.12upgrade entries authored in bothskills/upgrade/prisma-next-upgrade/(user) andskills/extension-author/prisma-next-extension-upgrade/(extension-author), with colocated re-emit/regen/codemod scripts.record-upgrade-instructionsskill body corrected to document the coverage-gate limitation.Checklist
git commit -s) per the DCO.TML-NNNN: <sentence-case title>form.Summary by CodeRabbit
Chores
New Features
Tests
Documentation