Skip to content

TML-2853: enum becomes the domain concept — delete the native machinery#817

Merged
wmadden-electric merged 20 commits into
mainfrom
tml-2853-slice-cutover-enum-becomes-the-domain-concept-delete-the
Jun 15, 2026
Merged

TML-2853: enum becomes the domain concept — delete the native machinery#817
wmadden-electric merged 20 commits into
mainfrom
tml-2853-slice-cutover-enum-becomes-the-domain-concept-delete-the

Conversation

@wmadden-electric

Copy link
Copy Markdown
Contributor

Linked issue

Refs TML-2853 — cutover: enum becomes 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):

enum user_type {
  admin
  user
}

After 0.14 (domain enum, what enum means now):

enum user_type {
  @@type("pg/text@1")
  admin = "admin"
  user  = "user"
}

Same change in the TS authoring API:

// Before — deleted
import { enumType } from '@prisma-next/adapter-postgres/column-types';
const Role = enumType('Role', ['USER', 'ADMIN']);

// After — `enumType` + `member` from the contract-builder
import { enumType, member } from '@prisma-next/postgres/contract-builder';
const pgText = { codecId: 'pg/text@1', nativeType: 'text' } as const;
const Role = enumType('Role', pgText, member('USER', 'USER'), member('ADMIN', 'ADMIN'));

The emitted contract is identical to what enum2 produced 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 in skills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.md.

  • The example-app migration history is by-design regenerated. fixtures:check deterministically 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. Commit f585e1506 captures it.

  • lint:casts delta is −34 vs merge-base. The removed enum codec and planner paths carried most of the existing blindCast / castAs calls. No new casts introduced.

  • enum2 keyword is retired, not converted. Any schema with enum2 blocks will produce a diagnostic after 0.14 until the author renames to enum. The upgrade instructions explain the rename.

  • rebase --onto conflict resolution. The rebase had 5 conflict files, all enum-adjacent or migration-hash. In planner-strategies.ts the conflict was between main's DDL-AST-pioneer version of buildColumnSpec (which still referenced PostgresEnumStorageEntry) and D2's deletion of that type. Resolution: kept the DDL-pioneer logic, dropped the PostgresEnumStorageEntry type from the cast (replaced with plain StorageTypeInstance). In codec-ids.ts the same PG_UUID_CODEC_ID constant appeared in both sides — kept the main HEAD addition; dropped PG_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.md notes this explicitly.


Decision

This PR delivers two things:

  1. Keyword flip. The enum PSL keyword and the enumType / enumColumn TS helpers now author the domain enum (text-class column + CHECK constraint). The transitional enum2 keyword introduced in TML-2880 is retired; enum is the only form. The postgres/contract-builder is the canonical author import; the old native enumType/enumColumn from adapter-postgres/column-types are deleted.

  2. Native-enum machinery deletion. The entire native Postgres enum stack is gone: PostgresEnumType, postgres-enum-storage-entry.ts, the pg/enum@1 codec, migration ops CreateEnumTypeCall / AddEnumValuesCall / DropEnumTypeCall / RenameTypeCall, enum-planning.ts, operations/enums.ts, nativeEnumPlanCallStrategy, native pg_enum introspection, and the postgresAuthoringEntityTypes.enum contribution. The cast ratchet drops by 34 (lint:casts current=1203 vs merge-base=1237). See spec § What this replaces for the deletion inventory.


How it fits together

  1. PSL parser — enum block removed. parsePslDocument no longer recognizes enum as a namespace-level block declaration. The parser no longer accumulates PslEnum nodes; parseEnumBlock, flatPslEnums, PslEnum/PslEnumValue types, and related diagnostics are deleted. The enum keyword 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.

  2. PSL interpreter — domain enum lowering. The interpreter now treats a PSL enum block as a domain-enum block (same as enum2). processEnumDeclarations is gone; processEnumTypeBlocks (already present for enum2) handles both keywords after D1 aliases enum to enum2 in the interpreter's dispatch. File: packages/2-sql/2-authoring/contract-psl/src/interpreter.ts.

  3. TS contract-builder — native helpers deleted. enumType(name, values[]) and enumColumn from @prisma-next/adapter-postgres/column-types are deleted. The canonical authoring path is enumType(name, codecRef, ...members) + member(name, value) from @prisma-next/postgres/contract-builder, returning an EnumTypeHandle under the contract's enums key. defineContract already accepted enums; no shape change. File: packages/2-sql/2-authoring/contract-ts/src/contract-builder.ts.

  4. Planner — native enum strategies gone. nativeEnumPlanCallStrategy, CreateEnumTypeCall, AddEnumValuesCall, DropEnumTypeCall, RenameTypeCall, and enum-planning.ts are 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).

  5. 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.

  6. Converting migration in the demo. examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.ts is the converting migration for the demo's priority column: ALTER to text USING cast, add the value-set CHECK, DROP the native type. The migration-replay test in prisma-next-demo replays 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

  • enum keyword in PSL now authors a domain enum, not a native Postgres enum. A schema with enum Foo { @@type("pg/text@1") A = "a" } emits a domain enum entry and a valueSet storage entry; columns typed Foo get 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.

  • enum2 keyword is retired. The interpreter no longer recognizes enum2; schemas using it get a PSL_UNKNOWN_BLOCK diagnostic. Evidence: packages/1-framework/2-authoring/psl-parser/test/parser-enum.test.ts (renamed from parser-enum2.test.ts).

  • pg/enum@1 codec and native-enum column type are gone. PG_ENUM_CODEC_ID is removed from codec-ids.ts; PG_ENUM_CODEC_ID references 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, and RenameTypeCall are deleted. The planner emits AddCheckConstraintCall / DropCheckConstraintCall for value-set changes instead. Evidence: test/integration/test/cross-package/postgres-issue-planner.test.ts.

  • Demo's converting migration replays cleanly. The prisma-next-demo migration 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 enum blocks (without @@type(...)) or TS enumType from adapter-postgres/column-types will fail to compile after upgrade. The upgrade instructions at skills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.md and skills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14/instructions.md cover:

  • Converting PSL schema syntax (add @@type(...), replace member names with = "value" form, drop @map, rename enum2 to enum).
  • Replacing the TS authoring API (enumType + member from postgres/contract-builder).
  • Writing the one-time converting migration for databases that already carry a native CREATE TYPE enum.

Databases that already carry native Postgres enum types need a one-time converting migration before they can use the new enum form. contract infer will refuse native enum types and name them in its diagnostic.


Verification

pnpm build              # 66/66 tasks, clean
pnpm typecheck          # 138/138
pnpm fixtures:check     # exit 0; 1 migration artifact regenerated + committed
pnpm lint:deps          # no violations
pnpm lint:casts         # current=1203 merge-base=1237 delta=−34
pnpm --filter prisma-next-demo test   # 57/57 (migration-integrity + migration-replay included)

Follow-ups

  • R10 — Mongo domain enums. Not in this PR. Independent of the SQL cutover; Mongo has no native type to replace. Follow-up ticket.
  • Emit-path typing fix. The db.enums.<Name> accessor type-widens to JsonValue in 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

  • Keep enum as a native-enum keyword and retire it in a future version. We chose to flip enum immediately 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.
  • Keep pg/enum@1 codec 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.
  • Keep enum2 as an alias indefinitely. Rejected. The enum keyword 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

  • All commits are signed off (git commit -s) per the DCO. git log origin/main..HEAD --format='%(trailers:key=Signed-off-by)' shows Signed-off-by: trailers on all 15 commits.
  • I read CONTRIBUTING.md and the change is scoped to one logical concern.
  • Tests are updated (PSL parser tests, planner tests, parity tests, demo migration tests).
  • The PR title is in TML-NNNN: <sentence-case title> form.
  • Skill update: skills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.md and skills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14/instructions.md document the enum-becomes-domain-concept migration. skills/prisma-next-contract/SKILL.md updated to reflect the new enumType/member API.

@wmadden-electric wmadden-electric requested a review from a team as a code owner June 12, 2026 14:15
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 214 files, which is 64 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 3b3d14ba-c047-4d99-a3f7-e2d10e575f69

📥 Commits

Reviewing files that changed from the base of the PR and between 8abe8fc and 222b439.

⛔ Files ignored due to path filters (10)
  • examples/bundle-size/src/postgres/generated/contract.d.ts is excluded by !**/generated/**
  • packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • projects/enums-as-domain-concept/plan.md is excluded by !projects/**
  • projects/enums-as-domain-concept/slices/cutover-delete-native-enums/plan.md is excluded by !projects/**
  • projects/enums-as-domain-concept/slices/cutover-delete-native-enums/spec.md is excluded by !projects/**
  • test/e2e/framework/test/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • test/integration/test/sql-builder/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • test/integration/test/sql-orm-client/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • test/integration/test/sql-orm-client/fixtures/polymorphism/generated/contract.d.ts is excluded by !**/generated/**
📒 Files selected for processing (214)
  • apps/telemetry-backend/src/prisma/contract.d.ts
  • docs/architecture docs/subsystems/1. Data Contract.md
  • docs/architecture docs/subsystems/2. Contract Emitter & Types.md
  • docs/architecture docs/subsystems/5. Adapters & Targets.md
  • docs/reference/typescript-patterns.md
  • examples/multi-extension-monorepo/app/src/contract.d.ts
  • examples/multi-extension-monorepo/packages/audit/src/contract.d.ts
  • examples/multi-extension-monorepo/packages/feature-flags/src/contract.d.ts
  • examples/paradedb-demo/src/prisma/contract.d.ts
  • examples/prisma-next-cloudflare-worker/src/prisma/contract.d.ts
  • examples/prisma-next-cloudflare-worker/src/prisma/contract.json
  • examples/prisma-next-cloudflare-worker/src/prisma/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/migration.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/migration.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/migration.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/migration.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/migration.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/migration.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/migration.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/migration.ts
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.ts
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/migration.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/migration.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/contract.prisma
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/migration.json
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/migration.ts
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/ops.json
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260611T1856_convert_user_type_to_value_set/start-contract.json
  • examples/prisma-next-demo/prisma/contract.ts
  • examples/prisma-next-demo/src/prisma/contract.d.ts
  • examples/prisma-next-demo/src/prisma/contract.json
  • examples/prisma-next-demo/src/prisma/contract.prisma
  • examples/prisma-next-demo/test/migration-replay.integration.test.ts
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/end-contract.d.ts
  • examples/prisma-next-postgis-demo/src/prisma/contract.d.ts
  • examples/react-router-demo/src/prisma/contract.d.ts
  • packages/1-framework/1-core/framework-components/src/control/psl-ast.ts
  • packages/1-framework/1-core/framework-components/src/shared/psl-extension-block.ts
  • packages/1-framework/1-core/framework-components/test/control-stack.test.ts
  • packages/1-framework/1-core/framework-components/test/psl-ast.test.ts
  • packages/1-framework/1-core/framework-components/test/psl-extension-block-validator.test.ts
  • packages/1-framework/2-authoring/psl-parser/src/exports/index.ts
  • packages/1-framework/2-authoring/psl-parser/src/parser.ts
  • packages/1-framework/2-authoring/psl-parser/test/parser-enum.test.ts
  • packages/1-framework/2-authoring/psl-parser/test/parser.test.ts
  • packages/1-framework/2-authoring/psl-printer/src/ast-to-print-document.ts
  • packages/1-framework/2-authoring/psl-printer/src/print-document.ts
  • packages/1-framework/2-authoring/psl-printer/src/serialize-print-document.ts
  • packages/1-framework/2-authoring/psl-printer/src/types.ts
  • packages/1-framework/2-authoring/psl-printer/test/generic-extension-block-printer.test.ts
  • packages/1-framework/2-authoring/psl-printer/test/print-psl-from-ast.test.ts
  • packages/1-framework/3-tooling/cli/test/commands/contract-infer.command.test.ts
  • packages/2-sql/1-core/contract/src/exports/types.ts
  • packages/2-sql/1-core/contract/src/ir/postgres-enum-storage-entry.ts
  • packages/2-sql/1-core/contract/src/ir/sql-node.ts
  • packages/2-sql/1-core/contract/src/ir/storage-type-instance.ts
  • packages/2-sql/1-core/contract/src/types.ts
  • packages/2-sql/1-core/contract/src/validators.ts
  • packages/2-sql/1-core/contract/test/sql-storage.test.ts
  • packages/2-sql/1-core/contract/vitest.config.ts
  • packages/2-sql/2-authoring/contract-psl/src/interpreter.ts
  • packages/2-sql/2-authoring/contract-psl/src/psl-field-resolution.ts
  • packages/2-sql/2-authoring/contract-psl/test/fixtures.ts
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.enum.test.ts
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.extensions.test.ts
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.test.ts
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.types.test.ts
  • packages/2-sql/2-authoring/contract-psl/test/ts-psl-parity.test.ts
  • packages/2-sql/2-authoring/contract-ts/README.md
  • packages/2-sql/2-authoring/contract-ts/src/build-contract.ts
  • packages/2-sql/2-authoring/contract-ts/src/contract-builder.ts
  • packages/2-sql/2-authoring/contract-ts/src/contract-definition.ts
  • packages/2-sql/2-authoring/contract-ts/src/contract-dsl.ts
  • packages/2-sql/2-authoring/contract-ts/src/contract-lowering.ts
  • packages/2-sql/2-authoring/contract-ts/src/contract-warnings.ts
  • packages/2-sql/2-authoring/contract-ts/test/contract-builder.contract-definition.test.ts
  • packages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.helpers.test.ts
  • packages/2-sql/2-authoring/contract-ts/test/contract-builder.dsl.test.ts
  • packages/2-sql/2-authoring/contract-ts/test/contract.parameterized-types.test.ts
  • packages/2-sql/3-tooling/emitter/src/index.ts
  • packages/2-sql/4-lanes/relational-core/src/codec-ref-for-column.ts
  • packages/2-sql/5-runtime/src/sql-context.ts
  • packages/2-sql/9-family/src/core/authoring-entity-types.ts
  • packages/2-sql/9-family/src/core/control-adapter.ts
  • packages/2-sql/9-family/src/core/control-instance.ts
  • packages/2-sql/9-family/src/core/migrations/contract-to-schema-ir.ts
  • packages/2-sql/9-family/src/core/psl-contract-infer/postgres-type-map.ts
  • packages/2-sql/9-family/src/core/psl-contract-infer/sql-schema-ir-to-psl-ast.ts
  • packages/2-sql/9-family/src/core/schema-verify/verify-sql-schema.ts
  • packages/2-sql/9-family/test/mutation-default-assembly.test.ts
  • packages/2-sql/9-family/test/psl-contract-infer/postgres-type-map.test.ts
  • packages/2-sql/9-family/test/psl-contract-infer/print-psl/print-psl.defaults-and-types.test.ts
  • packages/2-sql/9-family/test/psl-contract-infer/print-psl/print-psl.enums.test.ts
  • packages/2-sql/9-family/test/psl-contract-infer/print-psl/print-psl.naming-and-constraints.test.ts
  • packages/2-sql/9-family/test/psl-contract-infer/sql-schema-ir-to-psl-ast.test.ts
  • packages/2-sql/9-family/test/schema-verify.control-policy.test.ts
  • packages/2-sql/9-family/test/schema-verify.helpers.ts
  • packages/3-extensions/pgvector/src/contract.d.ts
  • packages/3-extensions/pgvector/test/migrations/planner.contract-to-schema-ir.test.ts
  • packages/3-extensions/pgvector/test/migrations/planner.storage-types.test.ts
  • packages/3-extensions/postgis/src/contract.d.ts
  • packages/3-extensions/postgres/src/contract/define-contract.ts
  • packages/3-extensions/sql-orm-client/test/namespace-qualification.test.ts
  • packages/3-targets/3-targets/postgres/package.json
  • packages/3-targets/3-targets/postgres/src/core/authoring.ts
  • packages/3-targets/3-targets/postgres/src/core/codec-helpers.ts
  • packages/3-targets/3-targets/postgres/src/core/codec-ids.ts
  • packages/3-targets/3-targets/postgres/src/core/codec-type-map.ts
  • packages/3-targets/3-targets/postgres/src/core/codecs.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/control-policy.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/enum-planning.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/issue-planner.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/op-factory-call.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/operations/enums.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/planner-ddl-builders.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/planner-identity-values.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/planner-recipes.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/planner-sql-checks.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/planner-strategies.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/planner-type-resolution.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/planner.ts
  • packages/3-targets/3-targets/postgres/src/core/migrations/runner.ts
  • packages/3-targets/3-targets/postgres/src/core/postgres-contract-serializer.ts
  • packages/3-targets/3-targets/postgres/src/core/postgres-enum-type.ts
  • packages/3-targets/3-targets/postgres/src/core/postgres-schema.ts
  • packages/3-targets/3-targets/postgres/src/exports/codecs.ts
  • packages/3-targets/3-targets/postgres/src/exports/control.ts
  • packages/3-targets/3-targets/postgres/src/exports/enum-planning.ts
  • packages/3-targets/3-targets/postgres/src/exports/migration.ts
  • packages/3-targets/3-targets/postgres/src/exports/op-factory-call.ts
  • packages/3-targets/3-targets/postgres/src/exports/types.ts
  • packages/3-targets/3-targets/postgres/test/codec-render-output-type.test.ts
  • packages/3-targets/3-targets/postgres/test/codecs-class.test.ts
  • packages/3-targets/3-targets/postgres/test/codecs.test.ts
  • packages/3-targets/3-targets/postgres/test/control-field.test.ts
  • packages/3-targets/3-targets/postgres/test/element-coordinates.test.ts
  • packages/3-targets/3-targets/postgres/test/fixtures/snapshot-read-shapes/postgres-enum.json
  • packages/3-targets/3-targets/postgres/test/migrations/enum-collision.test.ts
  • packages/3-targets/3-targets/postgres/test/migrations/verify-postgres-namespaces.test.ts
  • packages/3-targets/3-targets/postgres/test/postgres-contract-serializer.test.ts
  • packages/3-targets/3-targets/postgres/test/postgres-schema.test.ts
  • packages/3-targets/3-targets/postgres/test/snapshot-read-shapes.test.ts
  • packages/3-targets/3-targets/postgres/tsdown.config.ts
  • packages/3-targets/3-targets/sqlite/src/core/migrations/issue-planner.ts
  • packages/3-targets/3-targets/sqlite/src/core/migrations/planner-ddl-builders.ts
  • packages/3-targets/3-targets/sqlite/src/core/migrations/planner-strategies.ts
  • packages/3-targets/6-adapters/postgres/src/core/control-adapter.ts
  • packages/3-targets/6-adapters/postgres/src/core/enum-control-hooks.ts
  • packages/3-targets/6-adapters/postgres/src/core/sql-renderer.ts
  • packages/3-targets/6-adapters/postgres/src/exports/column-types.ts
  • packages/3-targets/6-adapters/postgres/test/adapter.test.ts
  • packages/3-targets/6-adapters/postgres/test/control-adapter.test.ts
  • packages/3-targets/6-adapters/postgres/test/enum-control-hooks.basic.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/native-enum-infer-diagnostic.integration.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/op-factory-call.lowering.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/op-factory-call.rendering.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/order-by-enum.integration.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/planner-sql-checks.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/planner.reconciliation.integration.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/planner.storage-types.integration.test.ts
  • packages/3-targets/6-adapters/postgres/test/migrations/schema-verify.after-runner.integration.test.ts
  • packages/3-targets/6-adapters/postgres/test/sql-renderer-namespace-qualification.test.ts
  • packages/3-targets/6-adapters/postgres/test/sql-renderer.cast-policy.test.ts
  • packages/3-targets/6-adapters/postgres/test/test-utils.ts
  • skills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14/instructions.md
  • skills/prisma-next-contract/SKILL.md
  • skills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.md
  • test/e2e/framework/test/multi-namespace-runtime.test.ts
  • test/integration/test/authoring/parity/core-surface/contract.ts
  • test/integration/test/authoring/parity/core-surface/expected.contract.json
  • test/integration/test/authoring/parity/core-surface/schema.prisma
  • test/integration/test/cli-journeys/data-transform-enum-rebuild.e2e.test.ts
  • test/integration/test/contract-builder.types.test-d.ts
  • test/integration/test/cross-package/postgres-issue-planner.test.ts
  • test/integration/test/fixtures/cli/cli-e2e-test-app/fixtures/cli-journeys/contract-status-enum-shrunk.ts
  • test/integration/test/fixtures/cli/cli-e2e-test-app/fixtures/cli-journeys/contract-status-enum.ts
  • test/integration/test/fixtures/cli/cli-e2e-test-app/fixtures/db-update-scenarios/contract-add-project-slug.ts
  • test/integration/test/fixtures/cli/cli-e2e-test-app/fixtures/db-update-scenarios/contract.ts
  • test/integration/test/fixtures/cli/cli-integration-test-app/fixtures/emit-command/contract.parity.ts
  • test/integration/test/fixtures/cli/cli-integration-test-app/fixtures/emit-command/schema.parity.psl
  • test/integration/test/fixtures/contract.d.ts
  • test/integration/test/utils/journey-test-helpers.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tml-2853-slice-cutover-enum-becomes-the-domain-concept-delete-the

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new

pkg-pr-new Bot commented Jun 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

@prisma-next/extension-author-tools

npm i https://pkg.pr.new/@prisma-next/extension-author-tools@817

@prisma-next/mongo-runtime

npm i https://pkg.pr.new/@prisma-next/mongo-runtime@817

@prisma-next/family-mongo

npm i https://pkg.pr.new/@prisma-next/family-mongo@817

@prisma-next/sql-runtime

npm i https://pkg.pr.new/@prisma-next/sql-runtime@817

@prisma-next/family-sql

npm i https://pkg.pr.new/@prisma-next/family-sql@817

@prisma-next/extension-arktype-json

npm i https://pkg.pr.new/@prisma-next/extension-arktype-json@817

@prisma-next/middleware-cache

npm i https://pkg.pr.new/@prisma-next/middleware-cache@817

@prisma-next/mongo

npm i https://pkg.pr.new/@prisma-next/mongo@817

@prisma-next/extension-paradedb

npm i https://pkg.pr.new/@prisma-next/extension-paradedb@817

@prisma-next/extension-pgvector

npm i https://pkg.pr.new/@prisma-next/extension-pgvector@817

@prisma-next/extension-postgis

npm i https://pkg.pr.new/@prisma-next/extension-postgis@817

@prisma-next/postgres

npm i https://pkg.pr.new/@prisma-next/postgres@817

@prisma-next/sql-orm-client

npm i https://pkg.pr.new/@prisma-next/sql-orm-client@817

@prisma-next/sqlite

npm i https://pkg.pr.new/@prisma-next/sqlite@817

@prisma-next/extension-supabase

npm i https://pkg.pr.new/@prisma-next/extension-supabase@817

@prisma-next/target-mongo

npm i https://pkg.pr.new/@prisma-next/target-mongo@817

@prisma-next/adapter-mongo

npm i https://pkg.pr.new/@prisma-next/adapter-mongo@817

@prisma-next/driver-mongo

npm i https://pkg.pr.new/@prisma-next/driver-mongo@817

@prisma-next/contract

npm i https://pkg.pr.new/@prisma-next/contract@817

@prisma-next/utils

npm i https://pkg.pr.new/@prisma-next/utils@817

@prisma-next/config

npm i https://pkg.pr.new/@prisma-next/config@817

@prisma-next/errors

npm i https://pkg.pr.new/@prisma-next/errors@817

@prisma-next/framework-components

npm i https://pkg.pr.new/@prisma-next/framework-components@817

@prisma-next/operations

npm i https://pkg.pr.new/@prisma-next/operations@817

@prisma-next/ts-render

npm i https://pkg.pr.new/@prisma-next/ts-render@817

@prisma-next/contract-authoring

npm i https://pkg.pr.new/@prisma-next/contract-authoring@817

@prisma-next/ids

npm i https://pkg.pr.new/@prisma-next/ids@817

@prisma-next/psl-parser

npm i https://pkg.pr.new/@prisma-next/psl-parser@817

@prisma-next/psl-printer

npm i https://pkg.pr.new/@prisma-next/psl-printer@817

@prisma-next/cli

npm i https://pkg.pr.new/@prisma-next/cli@817

@prisma-next/cli-telemetry

npm i https://pkg.pr.new/@prisma-next/cli-telemetry@817

@prisma-next/emitter

npm i https://pkg.pr.new/@prisma-next/emitter@817

@prisma-next/migration-tools

npm i https://pkg.pr.new/@prisma-next/migration-tools@817

prisma-next

npm i https://pkg.pr.new/prisma-next@817

@prisma-next/vite-plugin-contract-emit

npm i https://pkg.pr.new/@prisma-next/vite-plugin-contract-emit@817

@prisma-next/mongo-codec

npm i https://pkg.pr.new/@prisma-next/mongo-codec@817

@prisma-next/mongo-contract

npm i https://pkg.pr.new/@prisma-next/mongo-contract@817

@prisma-next/mongo-value

npm i https://pkg.pr.new/@prisma-next/mongo-value@817

@prisma-next/mongo-contract-psl

npm i https://pkg.pr.new/@prisma-next/mongo-contract-psl@817

@prisma-next/mongo-contract-ts

npm i https://pkg.pr.new/@prisma-next/mongo-contract-ts@817

@prisma-next/mongo-emitter

npm i https://pkg.pr.new/@prisma-next/mongo-emitter@817

@prisma-next/mongo-schema-ir

npm i https://pkg.pr.new/@prisma-next/mongo-schema-ir@817

@prisma-next/mongo-query-ast

npm i https://pkg.pr.new/@prisma-next/mongo-query-ast@817

@prisma-next/mongo-orm

npm i https://pkg.pr.new/@prisma-next/mongo-orm@817

@prisma-next/mongo-query-builder

npm i https://pkg.pr.new/@prisma-next/mongo-query-builder@817

@prisma-next/mongo-lowering

npm i https://pkg.pr.new/@prisma-next/mongo-lowering@817

@prisma-next/mongo-wire

npm i https://pkg.pr.new/@prisma-next/mongo-wire@817

@prisma-next/sql-contract

npm i https://pkg.pr.new/@prisma-next/sql-contract@817

@prisma-next/sql-errors

npm i https://pkg.pr.new/@prisma-next/sql-errors@817

@prisma-next/sql-operations

npm i https://pkg.pr.new/@prisma-next/sql-operations@817

@prisma-next/sql-schema-ir

npm i https://pkg.pr.new/@prisma-next/sql-schema-ir@817

@prisma-next/sql-contract-psl

npm i https://pkg.pr.new/@prisma-next/sql-contract-psl@817

@prisma-next/sql-contract-ts

npm i https://pkg.pr.new/@prisma-next/sql-contract-ts@817

@prisma-next/sql-contract-emitter

npm i https://pkg.pr.new/@prisma-next/sql-contract-emitter@817

@prisma-next/sql-lane-query-builder

npm i https://pkg.pr.new/@prisma-next/sql-lane-query-builder@817

@prisma-next/sql-relational-core

npm i https://pkg.pr.new/@prisma-next/sql-relational-core@817

@prisma-next/sql-builder

npm i https://pkg.pr.new/@prisma-next/sql-builder@817

@prisma-next/target-postgres

npm i https://pkg.pr.new/@prisma-next/target-postgres@817

@prisma-next/target-sqlite

npm i https://pkg.pr.new/@prisma-next/target-sqlite@817

@prisma-next/adapter-postgres

npm i https://pkg.pr.new/@prisma-next/adapter-postgres@817

@prisma-next/adapter-sqlite

npm i https://pkg.pr.new/@prisma-next/adapter-sqlite@817

@prisma-next/driver-postgres

npm i https://pkg.pr.new/@prisma-next/driver-postgres@817

@prisma-next/driver-sqlite

npm i https://pkg.pr.new/@prisma-next/driver-sqlite@817

commit: 222b439

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
postgres / no-emit 152.67 KB (-1.61% 🔽)
postgres / emit 120.9 KB (-1.27% 🔽)
mongo / no-emit 76.92 KB (0%)
mongo / emit 71.01 KB (0%)
cf-worker / no-emit 181.08 KB (-1.52% 🔽)
cf-worker / emit 146.05 KB (-1.15% 🔽)

Comment thread examples/prisma-next-demo/prisma/contract.ts Outdated
@wmadden-electric wmadden-electric force-pushed the tml-2853-slice-cutover-enum-becomes-the-domain-concept-delete-the branch from 997dd1c to f67fe59 Compare June 15, 2026 11:21
wmadden and others added 18 commits June 15, 2026 13:23
…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>
@wmadden-electric wmadden-electric force-pushed the tml-2853-slice-cutover-enum-becomes-the-domain-concept-delete-the branch from f67fe59 to 25dac4b Compare June 15, 2026 11:27

@wmadden wmadden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-emptive approval. Address the remaining comments then add to the merge queue

Comment thread packages/2-sql/5-runtime/src/sql-context.ts Outdated
Comment thread packages/2-sql/9-family/src/core/schema-verify/verify-sql-schema.ts Outdated
wmadden-electric and others added 2 commits June 15, 2026 14:01
…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>
@wmadden-electric wmadden-electric added this pull request to the merge queue Jun 15, 2026
Merged via the queue into main with commit 1be9505 Jun 15, 2026
21 checks passed
@wmadden-electric wmadden-electric deleted the tml-2853-slice-cutover-enum-becomes-the-domain-concept-delete-the branch June 15, 2026 12:37
wmadden-electric added a commit that referenced this pull request Jun 15, 2026
…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>
wmadden-electric added a commit that referenced this pull request Jun 15, 2026
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>
wmadden-electric added a commit that referenced this pull request Jun 15, 2026
…(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>
paulwer pushed a commit to paulwer/prisma-next that referenced this pull request Jun 15, 2026
'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>
wmadden pushed a commit that referenced this pull request Jun 16, 2026
…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>
wmadden-electric added a commit that referenced this pull request Jun 16, 2026
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>
wmadden-electric added a commit that referenced this pull request Jun 16, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants