Skip to content

TML-2795: M:N slice 6 — PG demo M:N examples - #820

Merged
aqrln merged 22 commits into
mainfrom
tml-2795-slice-6-pg-demo-mn-examples
Jun 24, 2026
Merged

TML-2795: M:N slice 6 — PG demo M:N examples#820
aqrln merged 22 commits into
mainfrom
tml-2795-slice-6-pg-demo-mn-examples

Conversation

@tensordreams

@tensordreams tensordreams commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Slice 6 of the SQL ORM: Many-to-Many End to End project. Refs TML-2795.

Rebased onto main; no longer stacked.

Overview

M:N examples. Post ↔ Tag many-to-many authored in PSL using slice 5's explicit-junction form (composite-@@id PostTag + bare list fields on both sides), with Tag.label @unique so the by-label API has a stable 1:1 lookup key. The demo's migrations are baselined into a single 20260422T0720_initial snapshot carrying the full schema (Post / Tag / PostTag with the composite junction PK, FK indexes + FKs, and the unique Tag.label). All nine M:N surfaces from the SQLite demo are mirrored as repo-* CLI commands: include in both directions, some/none/every filters (vacuous-truth every observable via an untagged seed post), connect, disconnect, nested create, and connect-in-create. Seed adds tags + junction rows; README documents the commands and the required-payload-junction guard.

Dual-mode / no-emit left as-is. The PG demo remains dual-mode (PSL src/prisma/contract.prisma + TS prisma/contract.ts + the no-emit workflow). The TS contract builder cannot author the discriminated Task/Bug/Feature hierarchy (nor M:N), so pnpm test:dual-mode is red on the TS leg — but it is not run by CI (CI runs typecheck:examples / lint:examples / test:examples, all green). Bringing the TS leg to parity and greening the dual-mode test is deferred to TML-2938, blocked by TML-2228 (TS authoring DSL polymorphism support). This PR is additive M:N only; the no-emit / dual-mode surface is unchanged from main.

Tests

8 PGlite-backed integration tests (test/many-to-many.integration.test.ts) per the project standard: whole-shape toEqual, explicit select in most reads plus one implicit default-selection include, all three filter predicates, and include-readback after each of the four write kinds. Full demo suite green (12 files / 65 tests). Root fixtures:check and typecheck:examples green.

Scope

examples/prisma-next-demo only — no framework, PSL-interpreter, or sql-orm-client changes. With this slice, the M:N API is demonstrated in both demos and the project's follow-on scope is complete.

Summary by CodeRabbit

  • New Features
    • Added many-to-many post/tag examples, including browsing tags from posts, browsing posts from tags, and filtering by relation matching modes.
    • Added support for creating, connecting, and disconnecting tags on posts, plus creating posts with new or existing tags.
    • Added a priority field for posts and updated demo data to include tags and junction entries.
    • Standardized demo IDs to UUIDs and expanded task inheritance examples.

@tensordreams
tensordreams requested a review from a team as a code owner June 12, 2026 20:17
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 086370b2-c478-4856-8003-fc5a5d1e2c0d

📥 Commits

Reviewing files that changed from the base of the PR and between 5de29d5 and 1948239.

📒 Files selected for processing (1)
  • examples/prisma-next-demo/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/prisma-next-demo/README.md

📝 Walkthrough

Walkthrough

The PR updates the prisma-next-demo initial migration artifacts for UUID identifiers, Priority, Tag/PostTag, and Task polymorphism. It removes superseded migration files, adds tag ORM and CLI flows, updates seeding, and expands the README with many-to-many examples.

Changes

Schema, migration artifacts, and demo tag flows

Layer / File(s) Summary
Initial schema and generated contract artifacts
examples/prisma-next-demo/migrations/app/20260422T0720_initial/*
The initial Prisma schema and regenerated contract files add UUID ids, Priority, Tag/PostTag, Task discriminators, and updated storage/execution metadata.
Initial migration SQL and removed migration files
examples/prisma-next-demo/migrations/app/20260422T0720_initial/*, examples/prisma-next-demo/migrations/app/20260422T0748_migration/*, examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/*
The initial migration SQL is regenerated for the new schema, and later migration entrypoints, ops, and contract artifacts are removed.
Tag ORM collection and post-tag helpers
examples/prisma-next-demo/src/orm-client/*, examples/prisma-next-demo/src/orm-client/connect-post-tags.ts, examples/prisma-next-demo/src/orm-client/disconnect-post-tags.ts
The ORM client registers TagCollection, adds a byLabel helper, and introduces connect/disconnect helpers for post-tag relations.
Seed data and CLI tag commands
examples/prisma-next-demo/scripts/seed.ts, examples/prisma-next-demo/src/main.ts
The seed script now inserts tags and junction rows, and the CLI adds traversal, relation-filter, connect/disconnect, and nested post-tag commands.
README examples for many-to-many usage
examples/prisma-next-demo/README.md
The README documents the updated emit example, the new Post↔Tag commands, and the many-to-many junction behavior.

Sequence Diagram(s)

sequenceDiagram
  participant main.ts
  participant helper as ormClientConnectPostTags
  participant orm as createOrmClient
  participant db as Postgres
  main.ts->>helper: postId, tagIds, runtime
  helper->>orm: createOrmClient(runtime)
  orm->>db: find Post by id
  helper->>db: connect/disconnect tags
  db-->>helper: updated post
  helper-->>main.ts: JSON result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • prisma/prisma-next#502: Regenerates migration artifacts and hashes for prisma-next-demo, similar to the updated migration.json, contract, and ops outputs here.
  • prisma/prisma-next#742: Adds the same Post↔Tag many-to-many demo surface, including CLI and ORM helper paths.
  • prisma/prisma-next#680: Changes many-to-many relation filtering behavior that matches the new some/none/every demo commands.

Poem

A bunny hops through taggy fields,
With UUID roots and carrot yields.
Post and Tag now dance in pairs,
Through little junction bunny stairs.
I nibble docs, then hop away 🐰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the PR’s main change: PostgreSQL many-to-many demo examples for slice 6.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tml-2795-slice-6-pg-demo-mn-examples

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.

@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/prisma-next/@prisma-next/extension-author-tools@820

@prisma-next/mongo-runtime

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

@prisma-next/family-mongo

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

@prisma-next/sql-runtime

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

@prisma-next/family-sql

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

@prisma-next/extension-arktype-json

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

@prisma-next/middleware-cache

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

@prisma-next/mongo

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

@prisma-next/extension-paradedb

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

@prisma-next/extension-pgvector

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

@prisma-next/extension-postgis

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

@prisma-next/postgres

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

@prisma-next/sql-orm-client

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

@prisma-next/sqlite

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

@prisma-next/extension-supabase

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

@prisma-next/target-mongo

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

@prisma-next/adapter-mongo

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

@prisma-next/driver-mongo

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

@prisma-next/contract

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

@prisma-next/utils

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

@prisma-next/config

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

@prisma-next/errors

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

@prisma-next/framework-components

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

@prisma-next/operations

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

@prisma-next/ts-render

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

@prisma-next/contract-authoring

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

@prisma-next/ids

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

@prisma-next/psl-parser

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

@prisma-next/psl-printer

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

@prisma-next/cli

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

@prisma-next/cli-telemetry

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

@prisma-next/config-loader

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

@prisma-next/emitter

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

@prisma-next/language-server

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/language-server@820

@prisma-next/migration-tools

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

prisma-next

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

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

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

@prisma-next/mongo-codec

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

@prisma-next/mongo-contract

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

@prisma-next/mongo-value

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

@prisma-next/mongo-contract-psl

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

@prisma-next/mongo-contract-ts

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

@prisma-next/mongo-emitter

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

@prisma-next/mongo-schema-ir

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

@prisma-next/mongo-query-ast

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

@prisma-next/mongo-orm

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

@prisma-next/mongo-query-builder

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

@prisma-next/mongo-lowering

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

@prisma-next/mongo-wire

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

@prisma-next/sql-contract

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

@prisma-next/sql-errors

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

@prisma-next/sql-operations

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

@prisma-next/sql-schema-ir

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

@prisma-next/sql-contract-psl

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

@prisma-next/sql-contract-ts

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

@prisma-next/sql-contract-emitter

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

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

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

@prisma-next/sql-relational-core

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

@prisma-next/sql-builder

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

@prisma-next/target-postgres

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

@prisma-next/target-sqlite

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

@prisma-next/adapter-postgres

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

@prisma-next/adapter-sqlite

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

@prisma-next/driver-postgres

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

@prisma-next/driver-sqlite

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

commit: 1948239

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
postgres / no-emit 158.28 KB (0%)
postgres / emit 145.84 KB (0%)
mongo / no-emit 78 KB (0%)
mongo / emit 72.09 KB (0%)
cf-worker / no-emit 185.59 KB (0%)
cf-worker / emit 171.64 KB (0%)

@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from 8d27a89 to ffd4829 Compare June 15, 2026 10:07
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 872c0ac to 1c43446 Compare June 15, 2026 10:07
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from ffd4829 to d89a2f4 Compare June 15, 2026 16:57
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 1c43446 to 564ebc0 Compare June 15, 2026 16:57
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from d89a2f4 to 382c349 Compare June 16, 2026 07:39
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch 2 times, most recently from 96a2c6f to 3903f46 Compare June 16, 2026 15:09
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from 382c349 to bf39877 Compare June 16, 2026 15:10
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 3903f46 to 23d1440 Compare June 16, 2026 18:55
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from bf39877 to ea1eb5d Compare June 16, 2026 19:01
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 23d1440 to 389209a Compare June 17, 2026 11:59
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from ea1eb5d to 856ac15 Compare June 17, 2026 12:01
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 389209a to 643be8b Compare June 17, 2026 13:59
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from 856ac15 to f5dd02e Compare June 17, 2026 14:00
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 643be8b to 9c981ce Compare June 17, 2026 14:24
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from f5dd02e to c5add23 Compare June 17, 2026 14:25
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 9c981ce to 153e30a Compare June 18, 2026 13:40
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from c5add23 to 06419ec Compare June 18, 2026 13:40
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 153e30a to 03a7a8b Compare June 18, 2026 13:50
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from 06419ec to bd43c38 Compare June 18, 2026 13:50
@tensordreams
tensordreams force-pushed the tml-2794-slice-5-psl-mn-authoring branch from 03a7a8b to 7d71303 Compare June 18, 2026 14:36
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch 5 times, most recently from 47316a3 to 23675e5 Compare June 19, 2026 15:58
…refs

Rebase onto the slice-3 namespace change: regenerate the pg demo contract
and the add_post_tags migration snapshot so their execution-default refs
carry the namespace.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Rebase onto main brought the enum-becomes-domain-concept refactor and the
op-factory-to-method migration API. Update the add_post_tags migration:
its contract.prisma snapshot adopts the domain-enum syntax (enum + @@type,
enum2 -> enum) to match the regenerated demo chain, and migration.ts moves
the bare createIndex/addForeignKey factories to this.createIndex/
this.addForeignKey. Regenerate the demo contract + migration chain.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
…se onto 0.14.0 main

Rebasing onto main picked up TML-2916 (un-namespaced PG models default to
`public`, dropping the empty `__unbound__` storage slot). Re-emit the demo
contract and regenerate the `add_post_tags` M:N migration so they match the new
emitter output; storage/migration hashes update and the chain stays consistent.
Lockfile drops the demo's `@prisma-next/sql-contract-ts` dependency (the demo is
now PSL-only).

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
…arity

The N:M through-consistency validator (TML-2794 slice 5) requires
junction columns to share the storage type of the id they reference. The
PG demo declared uuid ids (`String @default(uuid())` -> char(36)) with
plain `String` junction FKs (-> text), so post_tag.{postId,tagId} did not
match post.id/tag.id.

Switch every uuid column (ids and FKs) to a shared `Uuid = String
@db.Uuid` so they all emit native `uuid` consistently, and collapse the
demo's migration chain into a single uuid-consistent baseline — the old
snapshots encoded the pre-fix mismatch, which validateSqlContractFully
rejects on historical contracts too. One offline test's hard-coded id
codec assertion updated (sql/char@1 -> pg/uuid@1).

Claude-Session: https://claude.ai/code/session_01XcWuDhwCq2tXf5W4Py1Mk6
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Rebase onto main brought TML-2929/2928 (CST parser + formatter), whose
emitter formats the generated contract.d.ts slightly differently for the
pgvector codec type. Re-emit the demo contract.d.ts and the baseline
migration's end-contract.d.ts so emit:check / fixtures:check stay clean.
No contract.json change.

Claude-Session: https://claude.ai/code/session_01XcWuDhwCq2tXf5W4Py1Mk6
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
….14→0.15

Slice 6 touches `examples/prisma-next-demo/**` to demonstrate the new
Post<->Tag many-to-many, which trips the `check-upgrade-coverage` per-PR
gate: a PR touching examples/ must record a deliberate declaration in the
in-flight `0.14-to-0.15/instructions.md`.

The diff is an additive demonstration of slice 5's many-to-many authoring
surface — no consumer contract changes shape and no migration is forced —
so record it as an incidental substrate diff (`changes: []`) with an
explanatory comment, matching the established pattern.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
@tensordreams
tensordreams force-pushed the tml-2795-slice-6-pg-demo-mn-examples branch from d86d1a6 to df501d2 Compare June 24, 2026 09:34
Comment thread examples/prisma-next-demo/src/orm-client/connect-post-tags.ts Outdated
Comment thread examples/prisma-next-demo/src/orm-client/disconnect-post-tags.ts Outdated
… PSL parity

Slice 6 originally reconciled the demo's pre-existing dual-mode contract
drift by deleting the TypeScript contract source and the no-emit workflow,
making the demo PSL-only. That removed the only demonstration of the
no-emit / inline-TS-contract workflow.

Restore them as-is from main: the TS contract source (prisma/contract.ts),
its emit config (prisma-next.config.ts-contract.ts), the no-emit CLI +
queries + runtime, and the dual-mode test scripts plus the TS-leg test
files. The slice's M:N additions are kept (PSL Post<->Tag relation, native
uuid ids, ORM examples, CLI commands, seed, integration tests) — the
no-emit surface is left exactly as main had it, additive M:N only.

The TS leg diverges from the PSL source (no discriminated Task/Bug/Feature
hierarchy, no displayName/typed Address, no M:N, uuid-string vs native
uuid), so `pnpm test:dual-mode` is red on the TS leg. This is tolerated
because CI does not run it — CI runs typecheck:examples / lint:examples /
test:examples, all of which are green (demo typecheck + lint clean, 65
tests pass). Real parity is tracked by TML-2938, blocked by TML-2228 (TS
authoring DSL polymorphism support — the discriminated hierarchy cannot be
authored in TypeScript until that lands).

- README + App.tsx: restore the two-workflows / dual-mode narrative; the
  M:N sections are preserved.
- upgrade 0.14->0.15 instructions: drop the now-inaccurate "PSL-only
  single-source" claim from the TML-2795 note.
- slice spec: record the deferral and the TML-2938 / TML-2228 tracking.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
@tensordreams

Copy link
Copy Markdown
Contributor Author

On it — addressing the README client-signature note: examples/prisma-next-demo/README.md documents postgres<Contract, TypeMaps>({ contractJson, url }), but the demo's src/prisma/db.ts uses postgres<Contract>(...). I'll update the README text to match. (The other two findings in this review are tracked on their inline threads.)

…pdate query

The M:N connect example issued two queries: an .update() that linked the
tags, then a separate .select().include().first() to read the post back.
The .include(...).update(...) chain returns the updated post with its tags
in one query, so fold the read-back into the mutation.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
…e+update query

The M:N disconnect example issued two queries: an .update() that unlinked
the tags, then a separate .select().include().first() to read the post
back. The .include(...).update(...) chain returns the updated post with its
remaining tags in one query, so fold the read-back into the mutation.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
The Emit-Workflow paragraph documented `postgres<Contract, TypeMaps>({ contractJson, url })`,
but src/prisma/db.ts constructs the client with a single `Contract` type
parameter. Drop the second type parameter and the "Contract and TypeMaps"
wording so the README reflects what the demo actually does.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Tag labels in the demo are conceptually unique (they're the human-facing
identity of a tag), and the connect/disconnect examples treat them as such.
Mark Tag.label @unique in both PSL sources (the app schema and the baseline
migration's own contract.prisma), re-emit the contract, and regenerate the
migration so the baseline CREATE TABLE adds the tag_label_key UNIQUE
constraint. The migration's hand-authored operations carry the matching
unique() constraint so the applied schema verifies against the contract.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
The single-query include+update returns the full Post row by default; the
example demonstrates a projected read-back of just id, title, and the tag
list. Restore the explicit .select('id', 'title') in the chain so the
returned shape stays narrow.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
The single-query include+update returns the full Post row by default; the
example demonstrates a projected read-back of just id, title, and the
remaining tag list. Restore the explicit .select('id', 'title') in the
chain so the returned shape stays narrow.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
@tensordreams

Copy link
Copy Markdown
Contributor Author

Done (README client signature) — examples/prisma-next-demo/README.md now documents postgres<Contract>({ contractJson, url }) to match src/prisma/db.ts, which constructs the client with a single Contract type parameter. Dropped the second type parameter and the "Contract and TypeMaps" wording (commit 0dbd56e).

coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 24, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/prisma-next-demo/README.md`:
- Around line 70-74: The README’s Markdown fence under the Usage section is
missing the required blank line before the fenced block, causing markdownlint
MD031 failures. Update the README content around the Usage example so the fenced
block is separated by blank lines from the preceding text, keeping the code
fence itself unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4e4f1239-8fab-4963-956b-8ca273f06c73

📥 Commits

Reviewing files that changed from the base of the PR and between df501d2 and 5de29d5.

📒 Files selected for processing (15)
  • examples/prisma-next-demo/README.md
  • 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/20260422T0720_initial/ops.json
  • examples/prisma-next-demo/src/main.ts
  • examples/prisma-next-demo/src/orm-client/connect-post-tags.ts
  • examples/prisma-next-demo/src/orm-client/disconnect-post-tags.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
  • projects/sql-orm-many-to-many/slices/06-pg-demo-examples/spec.md
  • skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md

@coderabbitai coderabbitai Bot 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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/prisma-next-demo/README.md`:
- Around line 70-74: The README’s Markdown fence under the Usage section is
missing the required blank line before the fenced block, causing markdownlint
MD031 failures. Update the README content around the Usage example so the fenced
block is separated by blank lines from the preceding text, keeping the code
fence itself unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4e4f1239-8fab-4963-956b-8ca273f06c73

📥 Commits

Reviewing files that changed from the base of the PR and between df501d2 and 5de29d5.

📒 Files selected for processing (15)
  • examples/prisma-next-demo/README.md
  • 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/20260422T0720_initial/ops.json
  • examples/prisma-next-demo/src/main.ts
  • examples/prisma-next-demo/src/orm-client/connect-post-tags.ts
  • examples/prisma-next-demo/src/orm-client/disconnect-post-tags.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
  • projects/sql-orm-many-to-many/slices/06-pg-demo-examples/spec.md
  • skills/upgrade/prisma-next-upgrade/upgrades/0.14-to-0.15/instructions.md
🛑 Comments failed to post (1)
examples/prisma-next-demo/README.md (1)

70-74: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a blank line before the fenced block.

markdownlint is flagging this code fence (MD031), so the README will keep failing docs lint until the fence is surrounded by blank lines.

Suggested fix
 **Usage**:
+
 ```bash
 # No emit step needed - just run the app
 pnpm start:no-emit -- users
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
**Usage**:

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 71-71: Fenced code blocks should be surrounded by blank lines

(MD031, blanks-around-fences)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/prisma-next-demo/README.md` around lines 70 - 74, The README’s
Markdown fence under the Usage section is missing the required blank line before
the fenced block, causing markdownlint MD031 failures. Update the README content
around the Usage example so the fenced block is separated by blank lines from
the preceding text, keeping the code fence itself unchanged.

Source: Linters/SAST tools

@tensordreams tensordreams changed the title TML-2795: M:N slice 6 — PG demo M:N examples + PSL-only contract source TML-2795: M:N slice 6 — PG demo M:N examples Jun 24, 2026
@aqrln
aqrln enabled auto-merge June 24, 2026 12:20
…031)

The Setup and No-Emit Usage fenced blocks sat directly under their
`**...**:` labels with no separating blank line, tripping markdownlint
MD031 (blanks-around-fences). Add the blank line before each fence.

Claude-Session: https://claude.ai/code/session_019LgHiD5BC7aHcjSmBkCQF2
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
@tensordreams

Copy link
Copy Markdown
Contributor Author

Done — fixed the markdownlint MD031 nit in examples/prisma-next-demo/README.md (blank line before the Setup and Usage code fences) in 1948239. CodeRabbit's inline comment failed to post, so flagging the fix here at the top level.

@aqrln
aqrln added this pull request to the merge queue Jun 24, 2026
Merged via the queue into main with commit fbcda64 Jun 24, 2026
21 checks passed
@aqrln
aqrln deleted the tml-2795-slice-6-pg-demo-mn-examples branch June 24, 2026 13:55
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