Skip to content

TML-2790: M:N SQLite demo examples + project plan expansion (slices 4–6)#742

Open
tensordreams wants to merge 14 commits into
tml-2787-slice-3-writefrom
tml-2790-mn-demo-examples
Open

TML-2790: M:N SQLite demo examples + project plan expansion (slices 4–6)#742
tensordreams wants to merge 14 commits into
tml-2787-slice-3-writefrom
tml-2790-mn-demo-examples

Conversation

@tensordreams

Copy link
Copy Markdown
Contributor

Supersedes #697 — that PR was auto-marked merged by GitHub when a botched force-push briefly made its head identical to its base (nothing was actually merged; the branch content is unchanged). Same commits, same review state.

Follow-on to the SQL ORM: Many-to-Many End to End project: M:N demo examples + the project-plan expansion they surfaced.

Stacked PR — top of the M:N stack: tml-2787 (#683) → … → tml-2729 (#667) → main (the whole stack is rebased onto the latest main).

SQLite demo M:N examples (72ef8b793, 883309ecc)

The SQLite demo (examples/prisma-next-demo-sqlite, TS-authored) now demonstrates the full M:N ORM API via a pure Post ↔ Tag junction (PostTag):

  • Read: get-post-tags.include(tags, t => t.select(...)).
  • Filter: get-posts-by-tag-filter.where(p => p.tags.some/none/every(t => t.label.eq(...))).
  • Write (callback mutator): connect-post-tags / disconnect-post-tags / create-post-with-tags.update/.create({ tags: t => t.connect/disconnect/create([...]) }) with readback.

Wired as 6 CLI commands + seed; smoke-tested end-to-end (SQLite is offline-runnable); emitted contract carries cardinality:N:M + through; emit:check + typecheck clean.

Why only SQLite (and the plan expansion) (d711adfb6)

Adding examples surfaced a real gap: the navigable M:N API is authorable only via the TS contract builder (rel.manyToMany), not PSL — PSL emits only 1:N/N:1 and routes M:N to explicit junction models. The PG demo emits from PSL, so it cant show M:N until PSL learns to author it. So:

  • Filed TML-2794 — PSL many-to-many authoring (the framework gap).
  • Filed TML-2795 — PG demo M:N examples + pre-existing dual-mode contract drift (blocked by TML-2794).
  • Amended the project spec + plan with follow-on slices 4–6 (SQLite examples [done], PSL M:N authoring [planned], PG demo [planned]) + slice specs/plans. Slice 5 is framework-scoped and flagged for possible promotion to its own project.

Scope / notes

This PR ships the SQLite examples + the planning docs only. PG demo examples + PSL authoring are tracked (TML-2794/2795) and specd but not implemented here. No production src/ changes — demo + project-docs only.

Refs: TML-2790.

@tensordreams tensordreams requested a review from a team as a code owner June 5, 2026 15:04
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 128d9c13-f401-45ec-81e6-2c7233f36609

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-2790-mn-demo-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 and usage tips.

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
postgres / no-emit 156.34 KB (0%)
postgres / emit 123.64 KB (0%)
mongo / no-emit 76.92 KB (0%)
mongo / emit 71.01 KB (0%)
cf-worker / no-emit 183.82 KB (0%)
cf-worker / emit 147.7 KB (0%)

@pkg-pr-new

pkg-pr-new Bot commented Jun 5, 2026

Copy link
Copy Markdown

Open in StackBlitz

@prisma-next/extension-author-tools

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

@prisma-next/mongo-runtime

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

@prisma-next/family-mongo

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

@prisma-next/sql-runtime

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

@prisma-next/family-sql

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

@prisma-next/extension-arktype-json

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

@prisma-next/middleware-cache

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

@prisma-next/mongo

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

@prisma-next/extension-paradedb

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

@prisma-next/extension-pgvector

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

@prisma-next/extension-postgis

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

@prisma-next/postgres

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

@prisma-next/sql-orm-client

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

@prisma-next/sqlite

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

@prisma-next/extension-supabase

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

@prisma-next/target-mongo

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

@prisma-next/adapter-mongo

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

@prisma-next/driver-mongo

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

@prisma-next/contract

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

@prisma-next/utils

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

@prisma-next/config

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

@prisma-next/errors

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

@prisma-next/framework-components

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

@prisma-next/operations

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

@prisma-next/ts-render

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

@prisma-next/contract-authoring

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

@prisma-next/ids

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

@prisma-next/psl-parser

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

@prisma-next/psl-printer

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

@prisma-next/cli

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

@prisma-next/cli-telemetry

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

@prisma-next/emitter

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

@prisma-next/migration-tools

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

prisma-next

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

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

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

@prisma-next/mongo-codec

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

@prisma-next/mongo-contract

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

@prisma-next/mongo-value

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

@prisma-next/mongo-contract-psl

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

@prisma-next/mongo-contract-ts

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

@prisma-next/mongo-emitter

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

@prisma-next/mongo-schema-ir

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

@prisma-next/mongo-query-ast

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

@prisma-next/mongo-orm

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

@prisma-next/mongo-query-builder

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

@prisma-next/mongo-lowering

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

@prisma-next/mongo-wire

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

@prisma-next/sql-contract

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

@prisma-next/sql-errors

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

@prisma-next/sql-operations

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

@prisma-next/sql-schema-ir

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

@prisma-next/sql-contract-psl

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

@prisma-next/sql-contract-ts

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

@prisma-next/sql-contract-emitter

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

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

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

@prisma-next/sql-relational-core

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

@prisma-next/sql-builder

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

@prisma-next/target-postgres

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

@prisma-next/target-sqlite

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

@prisma-next/adapter-postgres

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

@prisma-next/adapter-sqlite

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

@prisma-next/driver-postgres

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

@prisma-next/driver-sqlite

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

commit: 868089d

@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 16dc690 to f3a7a5c Compare June 8, 2026 10:19
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from 1e62c8e to dbaf95a Compare June 8, 2026 10:19
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from f3a7a5c to b772b54 Compare June 8, 2026 11:19
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch 2 times, most recently from e19ee4a to 074d298 Compare June 8, 2026 14:46
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from b772b54 to 0f9d0c2 Compare June 8, 2026 14:46
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from 074d298 to ce2608d Compare June 8, 2026 16:45
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 0f9d0c2 to 2a360f4 Compare June 8, 2026 16:45
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from ce2608d to ac1c05d Compare June 9, 2026 11:07
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 2a360f4 to 67fb93c Compare June 9, 2026 11:07
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from ac1c05d to a5f259c Compare June 9, 2026 16:37
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch 2 times, most recently from 9feb292 to facaadf Compare June 9, 2026 16:39
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from a5f259c to 9829a58 Compare June 9, 2026 16:39
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from facaadf to 679770d Compare June 9, 2026 16:53
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from 9829a58 to 79ebfd0 Compare June 9, 2026 16:53
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 679770d to 302e804 Compare June 9, 2026 17:21
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch 2 times, most recently from 20e4a68 to 7774dfc Compare June 10, 2026 14:26
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 302e804 to 100b1d5 Compare June 10, 2026 14:26
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from 7774dfc to cef9592 Compare June 10, 2026 15:26
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 100b1d5 to 91b8cc4 Compare June 10, 2026 15:26
@tensordreams

Copy link
Copy Markdown
Contributor Author

Reviewed this PR separately against tml-2787-slice-3-write (origin/tml-2787-slice-3-write...origin/tml-2790-mn-demo-examples). I focused on the SQLite demo command wiring, handwritten ORM modules, seed data, generated contract consistency, migration refs, and upgrade note placement. I did not find actionable issues in this PR. Verification while reviewing: pnpm --filter prisma-next-demo-sqlite typecheck, pnpm --filter prisma-next-demo-sqlite emit:check, and git diff --check for this PR diff all passed.

@tensordreams tensordreams left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reviewed against projects/sql-orm-many-to-many/slices/04-sqlite-demo-examples/spec.md; ran pnpm -C examples/prisma-next-demo-sqlite typecheck and emit:check locally (both pass).

Solid, well-scoped PR: the new ORM-client modules are idiomatic and cleanly demonstrate the full M:N surface (include, some/none/every, connect/disconnect, nested create), castAs is used at branded-id boundaries with no bare as or any in the new files, the CLI wiring matches the existing command style exactly (usage errors, exit codes, JSON output), and the planning docs for slices 4–6 are internally consistent with correct ticket references. The upgrade note correctly lives only in the 0.13→0.14 cycle with no leftover in 0.12→0.13.

One issue should be resolved before merge: the newly committed migrations/app/refs/ snapshot is stale against the re-emitted contract (old canonical shape, mismatched storage hash) — see inline. Everything else is polish.

Comment thread examples/prisma-next-demo-sqlite/migrations/app/refs/db.json Outdated
Comment thread projects/sql-orm-many-to-many/slices/04-sqlite-demo-examples/spec.md Outdated
Comment thread projects/sql-orm-many-to-many/slices/04-sqlite-demo-examples/spec.md Outdated
Comment thread examples/prisma-next-demo-sqlite/src/orm-client/connect-post-tags.ts Outdated
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 91b8cc4 to 4ea74ff Compare June 10, 2026 18:15
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch 2 times, most recently from 2f4d2d2 to 1d48265 Compare June 12, 2026 10:27
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 2dc2eec to f773b93 Compare June 12, 2026 11:07
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from 194bcbc to f61b14e Compare June 12, 2026 11:07
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from f773b93 to 81eca2a Compare June 12, 2026 12:19
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from f61b14e to 2124c19 Compare June 12, 2026 12:19
@tensordreams tensordreams force-pushed the tml-2787-slice-3-write branch from 81eca2a to 3440e5d Compare June 12, 2026 13:07
@tensordreams tensordreams force-pushed the tml-2790-mn-demo-examples branch from 2124c19 to 49c9d80 Compare June 12, 2026 13:08
Adds Tag model, PostTag junction (composite PK post_tag_pkey), and
rel.manyToMany() declarations on both Post.tags and Tag.posts.
Re-emits contract.json / contract.d.ts; cardinality 'N:M' + through
descriptor present in the generated artifacts.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Adds five ORM client modules exercising the Post↔Tag N:M relation:
- get-post-tags: .include('tags', ...) — include read across junction
- get-posts-by-tag-filter: .some()/.none()/.every() on N:M relation
- connect-post-tags: update + t.connect([{id}]) callback mutator
- disconnect-post-tags: update + t.disconnect([{id}]) callback mutator
- create-post-with-tags: create + t.create([...]) nested mutation

Seed extended with Tag rows + junction rows (typescript/orm/demo tags
linked to First Post and Second Post). CLI commands registered in
main.ts. Migration refs committed for offline db:init reproducibility.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Spec + plan amended for the follow-on scope (demos + authoring completeness):
slice 4 SQLite demo examples (done, TML-2790), slice 5 PSL M:N authoring
(TML-2794, framework gap — may promote to its own project), slice 6 PG demo
examples + dual-mode reconciliation (TML-2795, blocked by slice 5). Slice
specs + provisional dispatch plans for each.

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

The new main baseline (TML-2605) trips the no-bare-cast ratchet on the
string->branded-id casts in the M:N example helpers (+10). Replace the
bare `as PostId`/`as TagId` casts with castAs<T> to keep lint:casts at
delta 0. Behaviour unchanged (casts are erased at runtime).

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
… models (TML-2807 rebase)

The post_tag and tag models added by this branch were emitted before
main emitted SqlModelStorage.namespaceId (TML-2807); re-emit so the
demo contract matches a fresh emit.

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

The through descriptor now carries the junction's namespaceId; re-emit
the demo contract so both M:N relations declare it.

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

The check:upgrade-coverage gate requires every PR whose diff touches
examples/ to also touch the in-flight user-skill instructions. The M:N
demo additions need no user-side action (additive), so no new changes[]
entry — the existing array stays; this records the incidental diff.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
0.13.0 shipped without the M:N ORM-client examples, so the user-upgrade
note belongs in a new 0.13→0.14 instructions directory, not the
now-released 0.12→0.13 doc. The upgrade-coverage gate targets 0.13→0.14
after the release bump.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Main renamed the char(36) uuid authoring helpers to make storage explicit
(field.uuid -> field.uuidString, field.id.uuidv4 -> field.id.uuidv4String).
The pre-existing User/Post models were migrated on main; the M:N models
added on this branch still called the old names, failing contract emit.
Emitted contract is unchanged (same storage semantics, no hash drift).

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Close the two coverage gaps against the shipped M:N runtime: a reverse-
direction include (tag-posts, db.Tag.include("posts")) and connect inside
the create flow (create-post-connect-tags). Document the M:N commands in
the README, including a prose note on the required-payload junction guard,
which has no runnable example by design (the type gate makes it
uncompilable). All 9 M:N commands smoke-tested end-to-end on a fresh
database.

Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant