TML-2853: enum becomes the domain concept — delete the native machinery#817
Conversation
|
Important Review skippedToo many files! This PR contains 214 files, which is 64 over the limit of 150. To get a review, narrow the scope: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (10)
📒 Files selected for processing (214)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
@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/extension-supabase
@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 📦
|
997dd1c to
f67fe59
Compare
…n concept) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Will Madden <madden@prisma.io> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
PSL `enum Name { @@type(...) member = "value" }` now routes through the
generic extension-block grammar instead of the dedicated native enum parse
path. The sql-family block descriptor + factory key are respelled from
`enum2` to `enum`; `keyword: 'enum2'` becomes `keyword: 'enum'`.
Unreferenced (deletion lands in D2): the dedicated native enum parse in
psl-parser, the `PslEnum`/`PslEnumValue` AST nodes, `namespace.enums`
accessor, and the printer's `serializeEnum`. The `parser-enum2` and
`interpreter.enum2` test files are renamed to `parser-enum` and
`interpreter.enum`.
The postgres target's `postgresAuthoringEntityTypes.enum` key is renamed
to `enumEntity` to avoid shadowing the sql-family `enum` key after the
respelling.
Demo + cloudflare-worker schemas converted from native `enum` / `enum2`
to the new extension-block form. Migration chain artifacts regenerated to
match. Parity fixtures (`core-surface`, `emit-command`) updated to use
`enumType` + `member` in the TS authoring path with enums in the `enums`
field (not `types`).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Will Madden <madden@prisma.io>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…xy (D1-R1-1) renderDistinctPrefix used renderExpr (bare identifier rendering) while renderOrderByExpr rewrites value-set identifier-refs to array_position(ARRAY[...]::text[], col). The mismatch caused Postgres to reject queries with DISTINCT ON + ORDER BY over enum-backed columns. Fix: compute sourcesByRef before renderDistinctPrefix and pass it in; renderDistinctPrefix now calls renderOrderByExpr so both clauses emit identical expressions for every column class. Tests: two new cases in order-by-enum.integration.test.ts — one asserting the rendered SQL contains the same array_position expression in both DISTINCT ON and ORDER BY (was red on HEAD), one verifying the query executes without error against PGlite; plus a plain-scalar case asserting no array_position is emitted (confirms scalar distinctOn is unchanged). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Will Madden <madden@prisma.io> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Remove PostgresEnumType, PostgresEnumStorageEntry, StorageValueSet-based namespace type slot (entries.type), CreateEnumTypeCall/AddEnumValuesCall/ DropEnumTypeCall/RenameTypeCall op-factory shapes, nativeEnumPlanCallStrategy, enumRebuildCallRecipe, resolveExistingEnumValues/resolveExistingEnumValuesForContract, enum-control-hooks.ts introspection, and enum-planning.ts diffing infrastructure. Emitter now emits valueSet namespace type entries. codec-ref-for-column no longer falls back to entries.type for enum codec lookup. sql-context no longer branches on enum views. The postgres adapter's introspect no longer queries pg_enum or populates enumTypes in annotations. Test files deleted: enum-collision.test.ts, enum-control-hooks.basic.test.ts, planner.storage-types.integration.test.ts, control-field.test.ts (postgres-target), postgres-enum.json snapshot fixture. pnpm test:packages passes (800 test files, 10348 tests). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
- Drop PslEnum/PslEnumValue/flatPslEnums/namespace.enums from psl-ast.ts and all call sites (makePslNamespaceEntries signature loses the enums parameter; parser, printer, and test helpers updated accordingly). - Remove flatPslEnums from psl-parser's public export surface. - Delete seven it.skip blocks whose TODO noted "deleted in D1" (native enum syntax): interpreter.test.ts ×2, interpreter.types.test.ts ×3, interpreter.extensions.test.ts ×1, ts-psl-parity.test.ts ×1. - Convert five it.skip/describe.skip blocks that were to assert the component-3 diagnostic into live passing tests: sql-schema-ir-to-psl- ast.test.ts ×2 (throw on pg/enum@1 annotation), print-psl.enums.test.ts (full describe rewritten: names types, names multiple types, mentions pg/text@1 replacement), print-psl.defaults-and-types.test.ts ×1 (rewritten without enum annotation to cover scalar/model disambiguation), print-psl.naming-and-constraints.test.ts ×2 (converted from stale collision snapshot to diagnostic assertion). - Add the diagnostic throw in sqlSchemaIrToPslAst when enumInfo.typeNames is non-empty: names the types, says not adoptable, points at value-set form with pg/text@1. - Replay judgment: committed ops.json files embed raw SQL inline and do not call TypeScript enum-builder functions; no legacy-replay module needed — full delete is safe. - data-transform-enum-rebuild e2e: already uses domain enum form (enumType/enumColumn); the fixtures reference deleted native helpers and fail pre-commit on D2 HEAD — that is a D3 straggler, not a D2 regression. - fixtures:check, lint:deps, lint:casts (delta -32) gates pass; typecheck and psl-family/contract-psl/psl-parser unit tests pass clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…dead enum-reader surface - Create postgres-schema-ir-annotations.ts with readPostgresSchemaIrAnnotations and resolveDdlSchemaForNamespaceStorage (only live logic, no PgEnumTypesMap / readPgEnumTypesMap) - Delete packages/3-targets/3-targets/postgres/src/core/migrations/enum-planning.ts - Update exports/enum-planning.ts to import from the new file Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…eferences Remove PgEnumCodec, PgEnumDescriptor, pgEnumDescriptor, pgEnumColumn, PG_ENUM_CODEC_ID, pgEnumRenderOutputType, and the 'enum' entry from codec-type-map. Every prior test fixture referencing 'pg/enum@1' is updated to a context-appropriate stand-in codec id (app/test-enum@1, app/udt@1, app/test-type@1, app/test-opaque@1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…ospect path Add a detection-only pg_type query to introspectSchema that collects enum type names (pg_type WHERE typtype='e' for the introspected schema) and sets annotations.pg.nativeEnumTypeNames. Rewrite extractEnumInfo to read from that field instead of the old enumTypes structure, removing the ENUM_CODEC_ID dependency. Update the psl-contract-infer unit tests to use the new annotation shape. Add an end-to-end PGlite integration test proving the diagnostic fires on the real introspect→inferPslContract path with a CREATE TYPE ... AS ENUM database. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…n-enum shape Add 20260611T1856_convert_user_type_to_value_set to the demo chain: a data-only self-edge migration (from === to, per the migration-new --from recipe) that alters "user"."kind" to text (USING "kind"::text), adds the user_kind_check value-set CHECK, and drops the native "public"."user_type" type via inline rawSql. Attested by self-emit (tsx migration.ts); migration check and the offline integrity test stay green. Add migration-replay.integration.test.ts: replays every execute step of the shipped chain against a fresh dev database, then asserts kind is text, no native enums remain, the check constraint exists, and full verifySchema against the current contract passes with zero issues. Commit the one-time .d.ts regeneration (31 files): the component-2 type-slot removal (`type` slot dropped / valueSet shape) across example apps, extension contracts, and test fixtures. fixtures:check is clean after this commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…xtures and doc comments
- Delete the dead enum-planning export surface: exports/enum-planning.ts, the
relocated-but-dead postgres-schema-ir-annotations.ts helpers (caller removed in
the D2 bulk delete), the package.json ./enum-planning export, and the tsdown entry.
- Delete data-transform-enum-rebuild.e2e.test.ts and its contract-status-enum*
fixtures: the journey tested the deleted enumChangeCallStrategy native rebuild
recipe (createEnumType temp / renameType). The value-set shrink equivalent is a
check swap, proven end-to-end by enum-check-constraint.integration.test.ts
("re-plans drop+recreate when enum members change"); the user-fills-placeholder
dataTransform CLI journey is proven by the three sibling data-transform journeys.
- Update ts-psl-parity terseness fixtures from native enum syntax / deleted
enumEntity API to the domain-enum forms (@@type + member values, enumType/member).
- Doc-comment sweep: replace deleted-class references (PostgresEnumType,
nativeEnumPlanCallStrategy, CreateEnumTypeCall, "enum shrink/rebuild",
dependencyInstallCallStrategy) with live examples in sql-node.ts,
storage-type-instance.ts, issue-planner.ts, op-factory-call.ts,
planner-strategies.ts.
- Cloudflare-worker verified fully converted in D1: schema is domain-enum syntax,
contract.json carries pg/text@1 + valueSet + check, no native remnants; no change needed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…sion-author) User entry (skills/upgrade, 0.13-to-0.14): the enum keyword semantic flip — native enum syntax gone, @@type("<codec-id>") required, members carry = "value" (@Map on members removed, the value is the mapping), transitional enum2 renames to enum unchanged. Includes the TS authoring conversion (enumType + member from the contract-builder; native enumType/enumColumn from adapter column-types deleted) and the database conversion recipe (data-only self-edge migration: ALTER ... TYPE text USING ::text, add the value-set CHECK, rawSql DROP TYPE), pointing at the demo converting migration as the worked example. Detection: .prisma files with enum/enum2 blocks; the body scopes it to blocks without @@type. Extension-author entry (cross-audience: the branch touches packages/3-extensions/postgres/src/contract/define-contract.ts): PostgresEnumStorageEntry deleted from the SPI, storage.types is codec-instance only, the pg/enum@1 codec surface and native column-type helpers are gone, introspection records annotations.pg.nativeEnumTypeNames instead of enumTypes. Validated by execution: reverted examples/prisma-next-demo authoring surface (src/prisma/ + prisma/contract.ts) to the merge base, walked the entry (PSL + TS conversion, re-emit) — resulting tree byte-identical to HEAD; demo suite 11 files / 57 tests green including the migration-integrity and migration-replay proofs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
… mechanism remain Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…docs, skills, and test plumbing - skills/prisma-next-contract: the enum workflow now describes the domain enum (@@type + member values + CHECK) instead of native CREATE TYPE / pg/enum@1 - contract-ts README: replace the deleted enumEntity({name, values}) example with enumType + member and the enums return key - Subsystem docs (Data Contract, Contract Emitter & Types, Adapters & Targets) and typescript-patterns: replace PostgresEnumType / sql-enum-type worked examples with the live StorageValueSet / domain-enum story - psl-extension-block doc comment: enum2 -> enum - control-adapter.test: strip dead pg_enum mock matchers (the deleted enum introspect query they matched no longer exists) - control-stack.test: neutral fixture discriminator (postgres-enum -> test-enum) - sql-contract vitest config: drop coverage exclude for the deleted postgres-enum-storage-entry.ts - contract-psl interpreter: rename local enumEntityDescriptor -> enumDescriptor Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
…e API The D2 commit deleted enumType from @prisma-next/adapter-postgres/column-types and replaced it with a codec-taking signature on @prisma-next/postgres/contract-builder. These two integration-test fixtures were missed in the D3 sweep. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Review feedback: the single-arg member('admin') form reads ambiguously in
the TS function-call surface (unlike the PSL bare member). Use the explicit
member('admin','admin') here; rename UserType -> UserEnum.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
After rebasing onto TML-2887 (namespace entries open-dictionary), five files had broken imports or type errors from the conflict merge: - control-policy.ts: replace non-existent `storageTableAt` with `entityAt<StorageTable>` from framework-components/ir - planner-strategies.ts: re-add missing `StorageTypeInstance` and `blindCast` imports that conflict resolution incorrectly dropped - postgres-contract-serializer.ts: bracket notation for index-sig access (`entries['valueSet']`, `entries['table']`) - postgres-schema.ts: same bracket-notation fix + cast for valueSet return type - postgres-schema.test.ts: bracket-notation fix in assertions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Signed-off-by: willbot <w.a.madden+machine@gmail.com>
f67fe59 to
25dac4b
Compare
wmadden
left a comment
There was a problem hiding this comment.
Pre-emptive approval. Address the remaining comments then add to the merge queue
…ot textColumn
Both contract.ts and contract-add-project-slug.ts passed `textColumn` (a
column-type builder) as the second argument to `enumType()`, where a codec
descriptor is required. Add `pgText = { codecId: 'pg/text@1', nativeType:
'text' }` and use it instead. Also align the enumType name strings with
their declaration keys (key must equal name per build-contract invariant).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
- sql-context.ts, verify-sql-schema.ts: drop redundant `as StorageTypeInstance`
casts introduced in the cutover; the values are already typed correctly by
their container types, so no cast is needed.
- native-enum-infer-diagnostic.integration.test.ts: replace deprecated
`describe.sequential` with `describe('...', { concurrent: false }, ...)`.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…rride, #829) Revises spec component 4 to record the multi-step regeneration approach. The earlier single-migration framing (#817 review) was itself overruled on #829: the demo must keep a multi-step incremental chain to demonstrate the incremental migration CLI. Component 4 now describes re-authoring the original history in the value-set representation — initial migration creates user.kind as text + user_kind_check from the start, convert self-edge removed, all other incremental milestones preserved. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Merge origin/main tip 90d93bd (PR #816 Mongo migration DDL, PR #817 enum-as-domain-concept native machinery deletion) into tml-2890-uniform-kind-dispatch. Conflicts resolved: - validators.ts: took HEAD's version (main's changes were comment-only tweaks in lines HEAD had already deleted). - postgres-schema.ts: took main's version. HEAD's typeEntityKind referenced PostgresEnumType, which PR #817 deleted; retaining typeEntityKind would reference a non-existent type. - postgres-contract-serializer.ts: took main's version (no typeEntityKind import, plain super(storageTypesHydrators) call matching main). Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…(drop manual per-kind casts) The merge resolution took main's PostgresSchema constructor, which uses a manual per-kind loop with two blindCasts (the exact smell TML-2890 removes) plus a bare `as` in the valueSet getter. Behaviorally correct but it dropped this branch's descriptor redesign. Re-apply the descriptor path: hydrateNamespaceEntities + composeSqlEntityKinds (no typeEntityKind — #817 deleted PostgresEnumType and the postgres `type` kind, so postgres now has only the SQL-family kinds table/valueSet). The constructor collapses to a single boundary blindCast; the getters become cast-free; the entries field narrows to SqlNamespaceEntries. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
's merge race) (prisma#829) ## Linked issue Refs [TML-2853](https://linear.app/prisma-company/issue/TML-2853). Follow-up to prisma#817. ## Why this exists prisma#817 merged on a stale HEAD due to an auto-merge/merge-queue race: the migration-history regeneration commit was pushed but not yet ingested into the PR when the queue merged the prior commit. So the cutover landed, but the demo's migration chain on `main` still carries the pre-cutover artifact it was meant to remove — an initial migration that runs `CREATE TYPE "public"."user_type" AS ENUM (…)` (a state the post-cutover system can no longer produce) plus a `convert_user_type_to_value_set` self-edge migrating that impossible start-state to the value-set form. As discussed on the prisma#817 review: a migration demonstrating a transition *from a now-impossible system state* is an incoherent teaching artifact. This PR lands the fix that missed the merge. ## What it does Deletes the entire `examples/prisma-next-demo/migrations/app/` chain (all 7 folders, including the converting self-edge) and regenerates it from scratch via the standard regen flow into a single `20260615T0000_initial` that authors the current value-set / domain-enum representation directly: - `user.kind` is `text NOT NULL` + `user_kind_check` CHECK — no `CREATE TYPE` anywhere. - `post.priority` is `text DEFAULT 'low'` + `post_priority_check`. - Full current schema (pgvector, all tables/FKs/indexes) built by the one baseline migration. `migration-integrity` and `migration-replay` tests re-pointed at the regenerated chain (replay verified against a dev DB). Spec component 4 amended to record the operator's override of the earlier "history is OUT" pin. ## Chain shape (judgment call, flagging) Collapsed to a **single** initial migration rather than a regenerated multi-step evolution chain — the integrity test's self-edge case injects its own synthetic migration, so it doesn't need a real multi-step chain, and a single baseline is the simplest honest shape. If a multi-migration evolution narrative (each step in the new representation) is preferred for the demo, say so and I'll regenerate as a chain. ## Verification - `pnpm build` 66/66 · `pnpm typecheck` 138/138 · `pnpm fixtures:check` clean · `pnpm --filter prisma-next-demo test` 57/57 (integrity offline + replay against dev DB) - Grep-zero: no `CREATE TYPE`, `convert_user_type`, `enum2`, `postgres-enum`, `pg/enum@1` in committed demo migration ops. ## Checklist - [x] All commits signed off (DCO). - [x] Tests updated (migration-integrity + migration-replay re-pointed). - [x] PR title in `TML-NNNN:` form. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated upgrade guide to document migration chain regeneration for domain-enum representation. * **Refactor** * Regenerated example migration chain to use CHECK constraints for user-type validation instead of native Postgres enums. * Removed explicit enum value mappings across multiple migration files. * Consolidated and restructured migrations for improved consistency. * **Chores** * Updated test documentation and formatting for clarity. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…k slice status (#835) ## What & why Main's `projects/postgres-rls/` carried the **original M1–M5 layer-cut plan with nothing marked complete** — out of date. The project was re-cut on 2026-06-10 into four behaviour-named slices and has progressed substantially, but those doc updates were stuck behind #771's 85-commit code PR, so main never saw them. This brings the project tracking on main current, decoupled from the code PR. ## What changed (docs only) - **`plan.md`** → the current four-slice behaviour-cut (`select-policies-dependable`, `drift-handled-correctly`, `all-policy-types`, `typescript-authoring`), ported from #771. Plus two edits on top of #771's version: - Fixed the vestigial `## Slices / The five PRs below correspond to the five slices (M1–M5)` line that contradicted the re-cut. - Added an at-a-glance **Status:** marker per slice — Slice 1 🚧 in progress (PR #771; architecture + SELECT spine landed, remaining DoD items listed), Slices 2–4 ⬜ not started. - **`spec.md`** → the current, trimmed spec (the design-as-five-decisions version), ported from #771. - **`specs/design-rls-authoring-surface.md`**, **`specs/reconciliation-2026-06-08.md`** → added (the design docs the plan/spec link to; without them those links 404 on main). No code, no slice-execution artifacts (dispatches/, trace.jsonl stay with #771). ## Notes for the RLS owner - **One known staleness left as-is:** `spec.md` D1 still describes policies registering 'via the same `AuthoringContributions.entityTypes` mechanism `PostgresEnumType` already uses'. Since then #817 deleted `PostgresEnumType` and #826 (merged) added the `EntityKindDescriptor` seam for namespace `entries` kinds. I did **not** rewrite that design rationale — it's your call whether `policy` lands as a namespace-`entries` kind via `composeSqlEntityKinds([policyEntityKind])` or on the `storage.types` axis. Flagging so it gets reconciled when #771 next touches the spec. - **Pre-existing forward-ref:** `../cross-contract-refs/spec.md` resolves only once that sibling project merges — unchanged from main's previous plan, not introduced here. - When #771 merges, its copies of these files match this content (plus the two edits above), so the overlap is trivial. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
After merging origin/main (#817 deleted PostgresEnumStorageEntry; #826 introduced the entity-kind seam), interpreter.ts had stale references and test files accessed entries.policy / entries.role directly instead of through the safe getters on PostgresSchema. - Add AuthoringEntityTypeDescriptor to the import type block - Remove the deleted PostgresEnumStorageEntry type and the second enumTypes param from createNamespace signatures - Switch test accesses of ns.entries.policy / ns.entries.role to the ns.policy / ns.role getters (which handle the optional type) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
The entries key 'type' was for native postgres enum types deleted in #817. The key is no longer a registered entity kind, so it fails the contract validator when these contracts go through verifySchema or applyContract. Remove it from all RLS test fixtures. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Linked issue
Refs TML-2853 — cutover:
enumbecomes the domain concept; delete the native machinery.Prerequisite: TML-2885 (#809) — typed domain enum block in
contract.d.ts.At a glance
Before 0.14 (native form, now deleted):
After 0.14 (domain enum, what
enummeans now):Same change in the TS authoring API:
The emitted contract is identical to what
enum2produced in 0.13.Reviewer notes
Big diff, but mostly deletion. The net stat is −6936 lines across 244 files, driven by the native-enum machinery removal. The meaningful additions are in the PSL interpreter, the TS contract-builder, the converting migration, and the upgrade instructions. Spot-check
packages/2-sql/2-authoring/contract-psl/src/interpreter.ts,packages/3-targets/3-targets/postgres/src/core/migrations/planner-strategies.ts, and the upgrade instructions inskills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.md.The example-app migration history is by-design regenerated.
fixtures:checkdeterministically recomputes all migration artifact hashes after an emitter-touching change; the single changed file (20260422T0720_initial/migration.json) is the canonical output of that process, not a hand-merged hash. Commitf585e1506captures it.lint:castsdelta is −34 vs merge-base. The removed enum codec and planner paths carried most of the existingblindCast/castAscalls. No new casts introduced.enum2keyword is retired, not converted. Any schema withenum2blocks will produce a diagnostic after 0.14 until the author renames toenum. The upgrade instructions explain the rename.rebase --ontoconflict resolution. The rebase had 5 conflict files, all enum-adjacent or migration-hash. Inplanner-strategies.tsthe conflict was between main's DDL-AST-pioneer version ofbuildColumnSpec(which still referencedPostgresEnumStorageEntry) and D2's deletion of that type. Resolution: kept the DDL-pioneer logic, dropped thePostgresEnumStorageEntrytype from the cast (replaced with plainStorageTypeInstance). Incodec-ids.tsthe samePG_UUID_CODEC_IDconstant appeared in both sides — kept the main HEAD addition; droppedPG_ENUM_CODEC_ID(gone in D2).Mongo + typing mechanism are NOT in this PR. R10 (Mongo enums) and the emit-path typing fix are follow-up work. The
plan.mdnotes this explicitly.Decision
This PR delivers two things:
Keyword flip. The
enumPSL keyword and theenumType/enumColumnTS helpers now author the domain enum (text-class column + CHECK constraint). The transitionalenum2keyword introduced in TML-2880 is retired;enumis the only form. Thepostgres/contract-builderis the canonical author import; the old nativeenumType/enumColumnfromadapter-postgres/column-typesare deleted.Native-enum machinery deletion. The entire native Postgres enum stack is gone:
PostgresEnumType,postgres-enum-storage-entry.ts, thepg/enum@1codec, migration opsCreateEnumTypeCall/AddEnumValuesCall/DropEnumTypeCall/RenameTypeCall,enum-planning.ts,operations/enums.ts,nativeEnumPlanCallStrategy, nativepg_enumintrospection, and thepostgresAuthoringEntityTypes.enumcontribution. The cast ratchet drops by 34 (lint:castscurrent=1203 vs merge-base=1237). See spec § What this replaces for the deletion inventory.How it fits together
PSL parser — enum block removed.
parsePslDocumentno longer recognizesenumas a namespace-level block declaration. The parser no longer accumulatesPslEnumnodes;parseEnumBlock,flatPslEnums,PslEnum/PslEnumValuetypes, and related diagnostics are deleted. Theenumkeyword previously produced a native-enum entity via the Postgres authoring contribution; it now has no parser recognition at all. File:packages/1-framework/2-authoring/psl-parser/src/parser.ts.PSL interpreter — domain enum lowering. The interpreter now treats a PSL
enumblock as a domain-enum block (same asenum2).processEnumDeclarationsis gone;processEnumTypeBlocks(already present forenum2) handles both keywords after D1 aliasesenumtoenum2in the interpreter's dispatch. File:packages/2-sql/2-authoring/contract-psl/src/interpreter.ts.TS contract-builder — native helpers deleted.
enumType(name, values[])andenumColumnfrom@prisma-next/adapter-postgres/column-typesare deleted. The canonical authoring path isenumType(name, codecRef, ...members)+member(name, value)from@prisma-next/postgres/contract-builder, returning anEnumTypeHandleunder the contract'senumskey.defineContractalready acceptedenums; no shape change. File:packages/2-sql/2-authoring/contract-ts/src/contract-builder.ts.Planner — native enum strategies gone.
nativeEnumPlanCallStrategy,CreateEnumTypeCall,AddEnumValuesCall,DropEnumTypeCall,RenameTypeCall, andenum-planning.tsare deleted. The planner only handles the value-set + CHECK realization, which was already in place from the domain-enum slices. Files:packages/3-targets/3-targets/postgres/src/core/migrations/planner-strategies.ts,op-factory-call.ts,operations/enums.ts(deleted).Introspection diagnostic re-wired. The control adapter no longer queries
pg_enum. The native-enum introspection path is replaced with a diagnostic that tells users native enum types cannot be adopted (they need the converting migration). File:packages/3-targets/6-adapters/postgres/src/core/control-adapter.ts.Converting migration in the demo.
examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.tsis the converting migration for the demo'sprioritycolumn: ALTER to text USING cast, add the value-set CHECK, DROP the native type. Themigration-replaytest inprisma-next-demoreplays all migrations and confirms the database lands on the domain-enum shape. File:examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.ts.Behavior changes & evidence
enumkeyword in PSL now authors a domain enum, not a native Postgres enum. A schema withenum Foo { @@type("pg/text@1") A = "a" }emits a domainenumentry and avalueSetstorage entry; columns typedFooget a CHECK constraint in migration DDL. The PSL parity test confirms emit matches the TS-authored contract:test/integration/test/authoring/parity/core-surface/contract.ts,expected.contract.json.enum2keyword is retired. The interpreter no longer recognizesenum2; schemas using it get aPSL_UNKNOWN_BLOCKdiagnostic. Evidence:packages/1-framework/2-authoring/psl-parser/test/parser-enum.test.ts(renamed fromparser-enum2.test.ts).pg/enum@1codec and native-enum column type are gone.PG_ENUM_CODEC_IDis removed fromcodec-ids.ts;PG_ENUM_CODEC_IDreferences in tests are replaced with value-set variants. Evidence:packages/3-targets/3-targets/postgres/test/codecs.test.ts.Migration planner no longer emits native enum DDL.
CreateEnumTypeCall,AddEnumValuesCall,DropEnumTypeCall, andRenameTypeCallare deleted. The planner emitsAddCheckConstraintCall/DropCheckConstraintCallfor value-set changes instead. Evidence:test/integration/test/cross-package/postgres-issue-planner.test.ts.Demo's converting migration replays cleanly. The
prisma-next-demomigration chain (57/57 tests passing incl.migration-integrity+migration-replay) proves the converting migration round-trips the database from the native-enum shape to the domain-enum shape.Compatibility / migration / risk
This is a breaking change in 0.14. Any project with PSL
enumblocks (without@@type(...)) or TSenumTypefromadapter-postgres/column-typeswill fail to compile after upgrade. The upgrade instructions atskills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.mdandskills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14/instructions.mdcover:@@type(...), replace member names with= "value"form, drop@map, renameenum2toenum).enumType+memberfrompostgres/contract-builder).CREATE TYPEenum.Databases that already carry native Postgres enum types need a one-time converting migration before they can use the new
enumform.contract inferwill refuse native enum types and name them in its diagnostic.Verification
Follow-ups
db.enums.<Name>accessor type-widens toJsonValuein the emitted-path accessor surface (the same escape noted in the spec for TML-2852 D4). Follow-up after the emit-typed-block slice lands.Alternatives considered
enumas a native-enum keyword and retire it in a future version. We chose to flipenumimmediately because the native semantics are being deleted in this PR anyway — there is nothing to keep backward-compatible. A phased deprecation would extend the window during which the codebase contains dead native-enum infrastructure.pg/enum@1codec for projects that want native enums. The spec explicitly positions native Postgres enum types as a non-goal for this project. They can return as an alternative storage realization later; keeping the codec now would leave dead infra in place and add ambiguity about whether native enums are still a first-class surface.enum2as an alias indefinitely. Rejected. Theenumkeyword carrying the domain semantics is the whole point of the cutover. A permanent alias for the same form would just be noise in the grammar.Checklist
git commit -s) per the DCO.git log origin/main..HEAD --format='%(trailers:key=Signed-off-by)'showsSigned-off-by:trailers on all 15 commits.TML-NNNN: <sentence-case title>form.skills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.mdandskills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14/instructions.mddocument the enum-becomes-domain-concept migration.skills/prisma-next-contract/SKILL.mdupdated to reflect the newenumType/memberAPI.