[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-prisma-prisma-next-migration-review":3,"mdc-qcki3p-key":38,"related-org-prisma-prisma-next-migration-review":3138,"related-repo-prisma-prisma-next-migration-review":3298},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":34,"sourceUrl":36,"mdContent":37},"prisma-next-migration-review","review and resolve Prisma Next migrations","Review what Prisma Next migrations will run on merge or deploy, render the migration graph, resolve concurrent \u002F diamond-convergence conflicts, and configure environment refs for CI. Use for \"what migrations are going to run\", \"what runs on deploy\", merge conflict, diamond convergence, concurrent migrations, migration status, ref management, staging, production, MIGRATION.DIVERGED, MIGRATION.NO_MARKER, MIGRATION.MARKER_NOT_IN_HISTORY, prisma migrate status, prisma migrate diff, prisma migrate resolve.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"prisma","Prisma","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fprisma.png",[12,16,19,22,23],{"name":13,"slug":14,"type":15},"Code Review","code-review","tag",{"name":17,"slug":18,"type":15},"Database","database",{"name":20,"slug":21,"type":15},"Migration","migration",{"name":9,"slug":8,"type":15},{"name":24,"slug":25,"type":15},"CI\u002FCD","ci-cd",415,"https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma-next","2026-07-24T05:37:11.422323",null,15,[32,33],"loggy-core","loggy-terminal",{"repoUrl":27,"stars":26,"forks":30,"topics":35,"description":29},[32,33],"https:\u002F\u002Fgithub.com\u002Fprisma\u002Fprisma-next\u002Ftree\u002FHEAD\u002Fskills\u002Fprisma-next-migration-review","---\nname: prisma-next-migration-review\ndescription: Review what Prisma Next migrations will run on merge or deploy, render the migration graph, resolve concurrent \u002F diamond-convergence conflicts, and configure environment refs for CI. Use for \"what migrations are going to run\", \"what runs on deploy\", merge conflict, diamond convergence, concurrent migrations, migration status, ref management, staging, production, MIGRATION.DIVERGED, MIGRATION.NO_MARKER, MIGRATION.MARKER_NOT_IN_HISTORY, prisma migrate status, prisma migrate diff, prisma migrate resolve.\n---\n\n# Prisma Next — Migration Review (Deployment + Concurrency)\n\n> **Edit your data contract. Prisma handles the rest.**\n\nThis skill is about *reviewing* migrations, not authoring them. It covers the questions that come up at deploy time and when multiple developers are landing migrations concurrently.\n\nThe skill teaches *the system's mental model* — what a ref is, what a marker is, what the migration graph is — and shows how to ask the system for its state. It does **not** prescribe rigid step-by-step procedures: most \"review\" questions are answered by understanding the model and querying the right thing. Rigid procedures are reserved for the rare case where there's literally one safe path.\n\n## When to Use\n\n- User asks *\"what migrations will run when I merge this?\"* or *\"what's about to run on deploy?\"*.\n- User hit a concurrent-migration conflict (`main` advanced while their branch was open).\n- User wants to wire up a `staging` \u002F `production` ref so CI can deploy against it.\n- User wants to run a migration against an environment that isn't the local dev DB.\n- User asks about CI integration for migrations.\n\n## When Not to Use\n\n- User wants to *author* a migration → `prisma-next-migrations`.\n- User wants to fix a hash-mismatch \u002F drift in a single env → `prisma-next-migrations` (re-plan path) or `prisma-next-debug` (envelope-driven).\n- User wants to edit the contract → `prisma-next-contract`.\n\n## Key Concepts — the navigation model\n\n**Every migration question is a navigation from an *origin* to a *destination*.** Once you have this model, the rest of the skill is just \"which command asks the system about which navigation.\"\n\n### Origin\n\nThe **origin** is the database's *current contract hash*. The database carries a row in PN's marker table that records *\"this database is at hash X\"*. When the CLI runs online (a `--db \u003Curl>` is provided, or `db.connection` is set in `prisma-next.config.ts`), PN reads the marker and that hash is the origin. Offline (no DB connection), the origin is unknown — many commands degrade to listing the on-disk migrations and skip the per-edge applied\u002Fpending status.\n\nA live DB is therefore the authoritative source of origin. The \"recorded marker\" in any other artifact (refs, local cache, your assumptions) is a working copy that can drift; the live DB never does.\n\n### Destination\n\nThe **destination** is the contract hash you want the database to be at. Two ways to name a destination:\n\n- **A `--to \u003Cname>`** — a named pointer to a hash, stored under `migrations\u002Fapp\u002Frefs\u002F\u003Cname>`. Refs are named after environments by convention (`staging`, `production`) to communicate *\"this is where production is expected to be\"*. The ref itself is just a hash + an optional set of required invariants; it has nothing to do with which database you connect to.\n- **The current contract head** — implicit when no `--to` is passed. This is the hash of the current `contract.json` on disk.\n\n`--to staging` does **not** mean \"connect to the staging database.\" It means \"navigate the database I connected to (via `--db` or config) toward whatever hash this ref points at.\" Database selection is orthogonal: pass `--db $STAGING_DATABASE_URL` to actually point at staging.\n\n### The migration graph\n\nThe on-disk migrations form a directed graph: **nodes are contract hashes; edges are migrations.** Each migration declares a `from` hash and a `to` hash. A migration applies only when the database's current marker matches its `from` hash; running it advances the marker to its `to` hash.\n\n`migration status` queries the graph for the path from origin to destination and reports per-edge status:\n\n- **applied** — on the path from `EMPTY_CONTRACT_HASH` to the marker (history).\n- **pending** — on the path from the marker to the destination (what would run).\n- **unreachable** — on the path from `EMPTY_CONTRACT_HASH` to the destination, but the marker is on a different branch and won't reach it without first re-routing.\n\n### Diagnostic codes\n\n`migration status` emits structured diagnostics on the result envelope (`diagnostics[].code`) so the agent can branch on the code rather than parsing the prose summary. Each diagnostic also carries `severity` (`warn` or `info`), a human `message`, and `hints` — the same hints the CLI prints under the summary line.\n\n| Code | Severity | Meaning in the navigation model | Next move |\n|---|---|---|---|\n| `MIGRATION.UP_TO_DATE` | info | Marker = destination; no edges to walk. | Nothing to do. |\n| `MIGRATION.DATABASE_BEHIND` | info | Marker is an ancestor of the destination; N pending edges in between. | `migrate --to \u003Cname> --db $URL`. |\n| `MIGRATION.MISSING_INVARIANTS` | info | Marker reached destination structurally but missing required invariants the ref declares. | `migrate --to \u003Cname> --db $URL` to take a path that covers them. |\n| `MIGRATION.NO_MARKER` | warn | Online, but the database has no marker row — never initialised. | `migrate --db $URL` (first apply writes the marker). |\n| `MIGRATION.MARKER_NOT_IN_HISTORY` | warn | Online; marker hash is not a node in the graph. The database was changed outside the migration system. | Decide which side is truth: `db sign` (accept DB as truth), `db update` (push contract to DB), `contract infer` (re-derive contract from DB), or `db verify` (inspect first). **Not** the same as `MIGRATION.MARKER_MISMATCH`: `MARKER_NOT_IN_HISTORY` is emitted during the runner's graph walk when the live marker is off the path being traversed; `MARKER_MISMATCH` fires earlier, at the CLI pre-DDL gate, when the marker hash is not a graph node at all. |\n| `MIGRATION.DIVERGED` | warn | Multiple valid leaves; the destination is ambiguous. | Pass `--to \u003Cname>`, or `ref set \u003Cname> \u003Chash>` to create one. |\n| `CONTRACT.AHEAD` | warn | Contract head is not in the graph — the contract was edited without re-planning. | `migration plan` to extend the graph. |\n| `CONTRACT.UNREADABLE` | warn | `contract.json` couldn't be read. | `contract emit` to regenerate it. |\n\n### Graph-tree output\n\n`migration status` (and `migration list`) render the migration graph as a colored lane tree in the terminal. Two flags control the rendering:\n\n- `--legend` — prints the key for the tree glyphs and lane colors before the tree.\n- `--ascii` — replaces box-drawing glyphs with pipe-safe ASCII characters (useful in CI logs or environments that don't support Unicode).\n\nBoth flags are also available on `migration list` and `migration graph`. `migration log` supports `--ascii` only (it renders a flat chronological table, not a tree).\n\n### Plan- and apply-time diagnostics\n\nThese codes surface on `migration plan`, `ref set`, and `migrate` — not on `migration status`. See [Migration System § Recovery affordances](..\u002F..\u002Fdocs\u002Farchitecture%20docs\u002Fsubsystems\u002F7.%20Migration%20System.md#recovery-affordances) and [ADR 218](..\u002F..\u002Fdocs\u002Farchitecture%20docs\u002Fadrs\u002FADR%20218%20-%20Refs%20with%20paired%20contract%20snapshots%20and%20universal%20graph-node%20invariant.md).\n\n| Code | When | Meaning | Next move |\n|---|---|---|---|\n| `MIGRATION.HASH_NOT_IN_GRAPH` | `migration plan` (non-empty graph) or `ref set` | Resolved hash is not a node in the on-disk migration graph — typical when the default `db` ref points past the graph tip after dev-only `db update` cycles. | `migration plan --from \u003Creachable-ref>` (e.g. `--from production`); or realign the ref with `ref set db \u003Cgraph-node-hash>`. |\n| `MIGRATION.SNAPSHOT_MISSING` | `migration plan` | A named ref has no pointer file (`\u003Cname>.json`), and the hash being resolved isn't a node in the migration graph either. | `ref set \u003Cname> \u003Chash>` to create the ref, `db update --advance-ref \u003Cname>` to advance it, or pass a hash that is a graph node. |\n| `MIGRATION.MARKER_MISMATCH` | `migrate` (pre-DDL, before the runner) | Live DB marker hash is not a graph node — drift the offline planner cannot see. | `migration plan --from \u003Cgraph-tip>` if the marker is canonical; `ref set db \u003Cmarker-hash>` if the on-disk graph is canonical; investigate out-of-band applies. |\n| `MIGRATION.PATH_UNREACHABLE` | `migrate` (path resolution) | No migration path from the current marker to the resolved target in the on-disk graph. | Read the improved `fix` payload — it names `fromHash` \u002F `targetHash` and suggests `migration plan --from \u003Cfrom> --to \u003Ctarget>`; run `migration list` to inspect the graph. |\n\nA CI gate should read `diagnostics` from `--json` output and decide based on `severity` plus `code`; see *Workflow — CI* below for the structure.\n\n## Workflow — *\"What's about to run on deploy?\"*\n\nThe user asks: *\"I'm about to merge this PR. What migrations are going to run when I deploy to staging?\"*\n\nThis is the navigation question: **origin** = staging's live marker; **destination** = the ref `staging` (or the contract head if you haven't set one). Ask the system:\n\n```bash\npnpm prisma-next migration status --to staging --db \"$STAGING_DATABASE_URL\"\n```\n\nThe command:\n\n1. Reads the staging DB's marker (the origin).\n2. Resolves `staging` to a contract hash (the destination).\n3. Renders the path between them as an ordered list of migrations, with per-edge `applied` \u002F `pending` \u002F `unreachable` status, and an explicit summary line of the form *\"N migration(s) behind ref 'staging'\"*.\n4. Prints a header that names the config, migrations directory, the active ref, and the database connection (masked) — so the framing is visible in the output.\n\nIf you omit `--db`, the command runs offline: it lists the migrations on disk but cannot tell you what's applied, because it has no origin. That's fine for *\"what's on this branch?\"*; it's not fine for *\"what's about to run on staging?\"* — for that you need staging's live marker.\n\nIf you omit `--to`, the destination defaults to the contract head — which answers *\"is this branch's contract reachable from the database, and how?\"*, not *\"what runs on deploy\"*. Pass the ref explicitly when the question is about a specific environment.\n\n`migration status` summarises each pending migration's operations by class (`additive`, `widening`, `data`, `destructive`) and reports a destructive-op count when destructive operations are present. Surface that count to the user before they merge or deploy — destructive operations are the class that warrants manual review.\n\n## Workflow — *\"What state is each environment at?\"*\n\nJust `migration status --db $URL` for each environment's DB. The marker (origin) comes back from the DB itself; the summary line tells you whether the environment is at the contract head, at a named ref, ahead of head, or on a divergent branch.\n\n## Concept — concurrent migrations on the same branch point\n\nThis used to be called *diamond convergence* in some PN docs; the situation is the same regardless of the label.\n\n**What's happening.** Two topic branches each authored a migration off the same parent contract hash. The first branch merges to `main`; the destination ref (e.g. `production`) advances to that branch's `to` hash. Your branch's migration still has its `from` hash pointing at the *old* parent. The migration graph, after rebase, no longer has a clean path through your migration:\n\n- Your migration's `from` is no longer an ancestor of the new head.\n- Or your migration's `from` is reachable, but the path through your migration arrives at a hash that's not the union of both branches' changes.\n\nEither way, the on-disk plan is stale.\n\n**Resolution.** The on-disk plan is stale because its `from` hash is no longer the head of the graph; apply the cluster's standard *edit → plan → apply* loop to the post-rebase state and the planner produces a fresh migration whose `from` matches the new head.\n\n**The one thing the planner can't do for you** is port custom data-transform logic from the abandoned `migration.ts` into the new one — schema deltas are derived from the contract, but any hand-written `data` operations are yours to carry across before applying. There is no separate \"revalidate\" step, no special \"diamond apply\" flow.\n\n## Workflow — set, list, get, delete refs\n\nRefs are small artifacts. There's no per-environment lifecycle; you just point a name at a hash.\n\n```bash\npnpm prisma-next ref set production \u003Ccontract-hash>\npnpm prisma-next ref list\n# `ref get` was removed — use `ref list` and filter by name\npnpm prisma-next ref list | grep production\npnpm prisma-next ref delete production\n```\n\n`ref set` writes a file at `migrations\u002Fapp\u002Frefs\u002F\u003Cname>` carrying the hash and any required invariants. Refs are commit-friendly artifacts — keep them in git; the team agrees on what `production` points at the same way they agree on what `main` is.\n\n## Workflow — apply a migration against an environment\n\n```bash\npnpm prisma-next migrate --to production --db \"$PRODUCTION_DATABASE_URL\"\n```\n\nThe destination is the ref's hash; the origin is the production DB's live marker. The command computes the path between them and applies each pending migration in order, advancing the marker.\n\n`--db` is the environment selection knob. `--to` is the destination-hash knob. They're independent.\n\n## Concept — ref-mismatch on CI \u002F deploy\n\nCI reports: *\"the recorded ref `production` is at hash X; the live DB is at hash Y.\"*\n\nThe mismatch is a fact about *two pieces of state that disagree*. The investigation is the same regardless of which piece is wrong:\n\n- **DB ahead of the ref.** Someone applied a migration outside CI without updating the ref in git. Re-record the ref with `prisma-next ref set \u003Cref-name> \u003Cdb-marker-hash>` (commit + push); then audit how the out-of-band apply happened.\n- **DB behind the ref.** A previous deploy was rolled back, or the DB was restored from an older backup. Either re-apply forward with `prisma-next migrate --to \u003Cref-name> --db $URL`, or re-route the ref backward to match what's actually deployed with `prisma-next ref set \u003Cref-name> \u003Cdb-marker-hash>`. The choice is the user's — name both options.\n- **DB on a different branch.** An out-of-band schema change (manual SQL, ad-hoc migration) wrote something the migration graph doesn't model. Run `prisma-next db verify` to inspect the drift, then either `prisma-next contract infer` to re-derive the contract from the database, or edit the contract and run `prisma-next migration plan` so the database is the eventual destination.\n\n`ref set` to silently align the ref with whatever the DB happens to be at is almost never the right move. It papers over drift that you'll pay for later.\n\n## Workflow — CI: verify a branch can advance the target environment\n\nThe gate is `migration status --to \u003Cenv> --db $URL`: it computes the path from the live marker to the ref and reports it, without mutating anything. There is no `--dry-run` flag on `migrate`; the inspect \u002F gate step is `migration status`.\n\nFor a human-readable ordered preview of the migration path before applying, use `migrate --show --db $URL`. For applied history after a deploy, use `migration log --db $URL` (flat chronological table).\n\n```yaml\n- name: Verify staging is reachable\n  run: |\n    pnpm prisma-next migration status \\\n      --to staging --db \"$STAGING_DATABASE_URL\" --json > status.json\n    node -e '\n      const s = JSON.parse(require(\"fs\").readFileSync(\"status.json\", \"utf8\"));\n      const warns = (s.diagnostics ?? []).filter(d => d.severity === \"warn\");\n      if (warns.length) {\n        console.error(\"Blocking diagnostics:\", warns);\n        process.exit(1);\n      }\n    '\n- name: Apply\n  run: pnpm prisma-next migrate --to staging --db \"$STAGING_DATABASE_URL\"\n```\n\n`migration status` exits non-zero only on hard errors (unreadable migrations directory, unsatisfiable invariants, unreconstructable history). Diagnostics like `MIGRATION.MARKER_NOT_IN_HISTORY`, `MIGRATION.DIVERGED`, `CONTRACT.AHEAD`, and `MIGRATION.NO_MARKER` are reported on the result envelope with `severity: 'warn'` but the process exits `0` — the agent (or a CI gate) must inspect `diagnostics[]` and fail the build itself. Use `--json` so the gate parses a structured shape rather than the human summary.\n\n`migrate` is interactive-free and has no destructive-op confirmation prompt — the safety rails that prompt for destructive changes live on `db update` (see the `prisma-next-migrations` skill). Whatever the planner put in the migration graph is what `migrate` runs; review happens at `migration plan` and at `migration status` time, before the apply step.\n\n## Common Pitfalls\n\n1. **Reading `migration status` without `--to` for a deploy question.** That asks *\"can this branch's contract reach the head?\"*, not *\"what's about to run on staging?\"*. Always pass the ref when the question is about a specific environment.\n2. **Reading `migration status` without `--db` for a deploy question.** Without a live DB, you have no origin. The output lists what's on disk; it can't say what's applied on the environment. Pass `--db $URL` for any high-stakes question.\n3. **Confusing the ref with a DB connection.** `--to staging` selects the destination hash, not the database. Pass both `--to` and `--db` explicitly.\n4. **Treating diamond convergence as a special procedure.** It's not. It's the normal *edit → plan → apply* loop applied to the post-rebase state. The only extra step is *\"port any data-transform logic from your old `migration.ts` over.\"*\n5. **Running `ref set` to silence a CI mismatch without understanding the cause.** That can mask out-of-band changes or rollback drift. Investigate first.\n\n## What Prisma Next doesn't do yet\n\n- **Per-environment migration ordering beyond the default chain.** If you need staging to skip a migration that production requires (or vice versa), the supported path is to author the per-env divergence as separate migrations and gate them in your deploy script. If you want first-class per-env routing, file a feature request via the `prisma-next-feedback` skill.\n- **A built-in side-by-side \"branch diff\" view.** There is a full-graph render (`migration graph`) that shows branches, but no `git diff`-style comparison between two branches' migration sets. Workaround: run `migration status` on each branch and `diff` the output. If you want a built-in branch-comparison view, file a feature request via the `prisma-next-feedback` skill.\n\n## Reference Files\n\nThis skill is intentionally body-only; the underlying CLI reference (`prisma-next migration status --help`, `migrate --help`, `ref --help`) is the authoritative surface for flag-level detail. When in doubt, run `--help` and read the actual command's description rather than guessing from this skill.\n\n## Checklist\n\n- [ ] Named both the **origin** (live DB marker) and the **destination** (ref or contract head) for the question the user asked.\n- [ ] Passed `--db $URL` whenever the question involves a specific environment.\n- [ ] Passed `--to \u003Cname>` whenever the question is about deploying *to* a named environment, not just *from* the current branch's head.\n- [ ] Read the `migration status` header (it names config, ref, database) and the summary line (it names the origin\u002Fdestination distance) before reading the per-edge list.\n- [ ] For concurrent-migration conflicts: re-applied the *core* workflow (edit → plan → apply) rather than following a memorised \"diamond convergence\" procedure. Ported any data-transform logic from the abandoned `migration.ts` over.\n- [ ] For a ref-mismatch: investigated *which* piece of state is wrong (DB ahead, DB behind, DB on a divergent branch). Did NOT `ref set` to silence the mismatch.\n- [ ] Surfaced the destructive-op count from `migration status` (the only operation class that warrants manual review pre-deploy) before the user merges or deploys.\n- [ ] In CI: parsed `migration status --json` `diagnostics[]` and gated on `severity === 'warn'`; did NOT rely on a `--dry-run` flag on `migrate` (no such flag exists).\n- [ ] Did NOT confuse `--to` with database selection (`--to` picks the destination hash; `--db` picks the database).\n- [ ] Did NOT use `--ref` (removed; use `--to`).\n- [ ] Did NOT confabulate a \"branch diff\" CLI subcommand, a `migration revalidate` step, or any other API the skill above doesn't reference.\n",{"data":39,"body":40},{"name":4,"description":6},{"type":41,"children":42},"root",[43,52,66,79,98,105,174,180,234,240,263,269,318,323,328,338,412,445,451,493,504,551,557,614,971,977,995,1020,1055,1061,1109,1378,1420,1431,1441,1465,1536,1541,1597,1623,1648,1687,1697,1710,1716,1728,1773,1800,1805,1836,1861,1867,1872,2017,2048,2054,2102,2107,2124,2130,2147,2159,2239,2249,2255,2289,2310,2486,2552,2597,2603,2746,2752,2819,2825,2860,2866,3132],{"type":44,"tag":45,"props":46,"children":48},"element","h1",{"id":47},"prisma-next-migration-review-deployment-concurrency",[49],{"type":50,"value":51},"text","Prisma Next — Migration Review (Deployment + Concurrency)",{"type":44,"tag":53,"props":54,"children":55},"blockquote",{},[56],{"type":44,"tag":57,"props":58,"children":59},"p",{},[60],{"type":44,"tag":61,"props":62,"children":63},"strong",{},[64],{"type":50,"value":65},"Edit your data contract. Prisma handles the rest.",{"type":44,"tag":57,"props":67,"children":68},{},[69,71,77],{"type":50,"value":70},"This skill is about ",{"type":44,"tag":72,"props":73,"children":74},"em",{},[75],{"type":50,"value":76},"reviewing",{"type":50,"value":78}," migrations, not authoring them. It covers the questions that come up at deploy time and when multiple developers are landing migrations concurrently.",{"type":44,"tag":57,"props":80,"children":81},{},[82,84,89,91,96],{"type":50,"value":83},"The skill teaches ",{"type":44,"tag":72,"props":85,"children":86},{},[87],{"type":50,"value":88},"the system's mental model",{"type":50,"value":90}," — what a ref is, what a marker is, what the migration graph is — and shows how to ask the system for its state. It does ",{"type":44,"tag":61,"props":92,"children":93},{},[94],{"type":50,"value":95},"not",{"type":50,"value":97}," prescribe rigid step-by-step procedures: most \"review\" questions are answered by understanding the model and querying the right thing. Rigid procedures are reserved for the rare case where there's literally one safe path.",{"type":44,"tag":99,"props":100,"children":102},"h2",{"id":101},"when-to-use",[103],{"type":50,"value":104},"When to Use",{"type":44,"tag":106,"props":107,"children":108},"ul",{},[109,129,143,164,169],{"type":44,"tag":110,"props":111,"children":112},"li",{},[113,115,120,122,127],{"type":50,"value":114},"User asks ",{"type":44,"tag":72,"props":116,"children":117},{},[118],{"type":50,"value":119},"\"what migrations will run when I merge this?\"",{"type":50,"value":121}," or ",{"type":44,"tag":72,"props":123,"children":124},{},[125],{"type":50,"value":126},"\"what's about to run on deploy?\"",{"type":50,"value":128},".",{"type":44,"tag":110,"props":130,"children":131},{},[132,134,141],{"type":50,"value":133},"User hit a concurrent-migration conflict (",{"type":44,"tag":135,"props":136,"children":138},"code",{"className":137},[],[139],{"type":50,"value":140},"main",{"type":50,"value":142}," advanced while their branch was open).",{"type":44,"tag":110,"props":144,"children":145},{},[146,148,154,156,162],{"type":50,"value":147},"User wants to wire up a ",{"type":44,"tag":135,"props":149,"children":151},{"className":150},[],[152],{"type":50,"value":153},"staging",{"type":50,"value":155}," \u002F ",{"type":44,"tag":135,"props":157,"children":159},{"className":158},[],[160],{"type":50,"value":161},"production",{"type":50,"value":163}," ref so CI can deploy against it.",{"type":44,"tag":110,"props":165,"children":166},{},[167],{"type":50,"value":168},"User wants to run a migration against an environment that isn't the local dev DB.",{"type":44,"tag":110,"props":170,"children":171},{},[172],{"type":50,"value":173},"User asks about CI integration for migrations.",{"type":44,"tag":99,"props":175,"children":177},{"id":176},"when-not-to-use",[178],{"type":50,"value":179},"When Not to Use",{"type":44,"tag":106,"props":181,"children":182},{},[183,202,222],{"type":44,"tag":110,"props":184,"children":185},{},[186,188,193,195,201],{"type":50,"value":187},"User wants to ",{"type":44,"tag":72,"props":189,"children":190},{},[191],{"type":50,"value":192},"author",{"type":50,"value":194}," a migration → ",{"type":44,"tag":135,"props":196,"children":198},{"className":197},[],[199],{"type":50,"value":200},"prisma-next-migrations",{"type":50,"value":128},{"type":44,"tag":110,"props":203,"children":204},{},[205,207,212,214,220],{"type":50,"value":206},"User wants to fix a hash-mismatch \u002F drift in a single env → ",{"type":44,"tag":135,"props":208,"children":210},{"className":209},[],[211],{"type":50,"value":200},{"type":50,"value":213}," (re-plan path) or ",{"type":44,"tag":135,"props":215,"children":217},{"className":216},[],[218],{"type":50,"value":219},"prisma-next-debug",{"type":50,"value":221}," (envelope-driven).",{"type":44,"tag":110,"props":223,"children":224},{},[225,227,233],{"type":50,"value":226},"User wants to edit the contract → ",{"type":44,"tag":135,"props":228,"children":230},{"className":229},[],[231],{"type":50,"value":232},"prisma-next-contract",{"type":50,"value":128},{"type":44,"tag":99,"props":235,"children":237},{"id":236},"key-concepts-the-navigation-model",[238],{"type":50,"value":239},"Key Concepts — the navigation model",{"type":44,"tag":57,"props":241,"children":242},{},[243,261],{"type":44,"tag":61,"props":244,"children":245},{},[246,248,253,255,260],{"type":50,"value":247},"Every migration question is a navigation from an ",{"type":44,"tag":72,"props":249,"children":250},{},[251],{"type":50,"value":252},"origin",{"type":50,"value":254}," to a ",{"type":44,"tag":72,"props":256,"children":257},{},[258],{"type":50,"value":259},"destination",{"type":50,"value":128},{"type":50,"value":262}," Once you have this model, the rest of the skill is just \"which command asks the system about which navigation.\"",{"type":44,"tag":264,"props":265,"children":266},"h3",{"id":252},[267],{"type":50,"value":268},"Origin",{"type":44,"tag":57,"props":270,"children":271},{},[272,274,278,280,285,287,292,294,300,302,308,310,316],{"type":50,"value":273},"The ",{"type":44,"tag":61,"props":275,"children":276},{},[277],{"type":50,"value":252},{"type":50,"value":279}," is the database's ",{"type":44,"tag":72,"props":281,"children":282},{},[283],{"type":50,"value":284},"current contract hash",{"type":50,"value":286},". The database carries a row in PN's marker table that records ",{"type":44,"tag":72,"props":288,"children":289},{},[290],{"type":50,"value":291},"\"this database is at hash X\"",{"type":50,"value":293},". When the CLI runs online (a ",{"type":44,"tag":135,"props":295,"children":297},{"className":296},[],[298],{"type":50,"value":299},"--db \u003Curl>",{"type":50,"value":301}," is provided, or ",{"type":44,"tag":135,"props":303,"children":305},{"className":304},[],[306],{"type":50,"value":307},"db.connection",{"type":50,"value":309}," is set in ",{"type":44,"tag":135,"props":311,"children":313},{"className":312},[],[314],{"type":50,"value":315},"prisma-next.config.ts",{"type":50,"value":317},"), PN reads the marker and that hash is the origin. Offline (no DB connection), the origin is unknown — many commands degrade to listing the on-disk migrations and skip the per-edge applied\u002Fpending status.",{"type":44,"tag":57,"props":319,"children":320},{},[321],{"type":50,"value":322},"A live DB is therefore the authoritative source of origin. The \"recorded marker\" in any other artifact (refs, local cache, your assumptions) is a working copy that can drift; the live DB never does.",{"type":44,"tag":264,"props":324,"children":325},{"id":259},[326],{"type":50,"value":327},"Destination",{"type":44,"tag":57,"props":329,"children":330},{},[331,332,336],{"type":50,"value":273},{"type":44,"tag":61,"props":333,"children":334},{},[335],{"type":50,"value":259},{"type":50,"value":337}," is the contract hash you want the database to be at. Two ways to name a destination:",{"type":44,"tag":106,"props":339,"children":340},{},[341,386],{"type":44,"tag":110,"props":342,"children":343},{},[344,355,357,363,365,370,372,377,379,384],{"type":44,"tag":61,"props":345,"children":346},{},[347,349],{"type":50,"value":348},"A ",{"type":44,"tag":135,"props":350,"children":352},{"className":351},[],[353],{"type":50,"value":354},"--to \u003Cname>",{"type":50,"value":356}," — a named pointer to a hash, stored under ",{"type":44,"tag":135,"props":358,"children":360},{"className":359},[],[361],{"type":50,"value":362},"migrations\u002Fapp\u002Frefs\u002F\u003Cname>",{"type":50,"value":364},". Refs are named after environments by convention (",{"type":44,"tag":135,"props":366,"children":368},{"className":367},[],[369],{"type":50,"value":153},{"type":50,"value":371},", ",{"type":44,"tag":135,"props":373,"children":375},{"className":374},[],[376],{"type":50,"value":161},{"type":50,"value":378},") to communicate ",{"type":44,"tag":72,"props":380,"children":381},{},[382],{"type":50,"value":383},"\"this is where production is expected to be\"",{"type":50,"value":385},". The ref itself is just a hash + an optional set of required invariants; it has nothing to do with which database you connect to.",{"type":44,"tag":110,"props":387,"children":388},{},[389,394,396,402,404,410],{"type":44,"tag":61,"props":390,"children":391},{},[392],{"type":50,"value":393},"The current contract head",{"type":50,"value":395}," — implicit when no ",{"type":44,"tag":135,"props":397,"children":399},{"className":398},[],[400],{"type":50,"value":401},"--to",{"type":50,"value":403}," is passed. This is the hash of the current ",{"type":44,"tag":135,"props":405,"children":407},{"className":406},[],[408],{"type":50,"value":409},"contract.json",{"type":50,"value":411}," on disk.",{"type":44,"tag":57,"props":413,"children":414},{},[415,421,423,427,429,435,437,443],{"type":44,"tag":135,"props":416,"children":418},{"className":417},[],[419],{"type":50,"value":420},"--to staging",{"type":50,"value":422}," does ",{"type":44,"tag":61,"props":424,"children":425},{},[426],{"type":50,"value":95},{"type":50,"value":428}," mean \"connect to the staging database.\" It means \"navigate the database I connected to (via ",{"type":44,"tag":135,"props":430,"children":432},{"className":431},[],[433],{"type":50,"value":434},"--db",{"type":50,"value":436}," or config) toward whatever hash this ref points at.\" Database selection is orthogonal: pass ",{"type":44,"tag":135,"props":438,"children":440},{"className":439},[],[441],{"type":50,"value":442},"--db $STAGING_DATABASE_URL",{"type":50,"value":444}," to actually point at staging.",{"type":44,"tag":264,"props":446,"children":448},{"id":447},"the-migration-graph",[449],{"type":50,"value":450},"The migration graph",{"type":44,"tag":57,"props":452,"children":453},{},[454,456,461,463,469,471,477,479,484,486,491],{"type":50,"value":455},"The on-disk migrations form a directed graph: ",{"type":44,"tag":61,"props":457,"children":458},{},[459],{"type":50,"value":460},"nodes are contract hashes; edges are migrations.",{"type":50,"value":462}," Each migration declares a ",{"type":44,"tag":135,"props":464,"children":466},{"className":465},[],[467],{"type":50,"value":468},"from",{"type":50,"value":470}," hash and a ",{"type":44,"tag":135,"props":472,"children":474},{"className":473},[],[475],{"type":50,"value":476},"to",{"type":50,"value":478}," hash. A migration applies only when the database's current marker matches its ",{"type":44,"tag":135,"props":480,"children":482},{"className":481},[],[483],{"type":50,"value":468},{"type":50,"value":485}," hash; running it advances the marker to its ",{"type":44,"tag":135,"props":487,"children":489},{"className":488},[],[490],{"type":50,"value":476},{"type":50,"value":492}," hash.",{"type":44,"tag":57,"props":494,"children":495},{},[496,502],{"type":44,"tag":135,"props":497,"children":499},{"className":498},[],[500],{"type":50,"value":501},"migration status",{"type":50,"value":503}," queries the graph for the path from origin to destination and reports per-edge status:",{"type":44,"tag":106,"props":505,"children":506},{},[507,525,535],{"type":44,"tag":110,"props":508,"children":509},{},[510,515,517,523],{"type":44,"tag":61,"props":511,"children":512},{},[513],{"type":50,"value":514},"applied",{"type":50,"value":516}," — on the path from ",{"type":44,"tag":135,"props":518,"children":520},{"className":519},[],[521],{"type":50,"value":522},"EMPTY_CONTRACT_HASH",{"type":50,"value":524}," to the marker (history).",{"type":44,"tag":110,"props":526,"children":527},{},[528,533],{"type":44,"tag":61,"props":529,"children":530},{},[531],{"type":50,"value":532},"pending",{"type":50,"value":534}," — on the path from the marker to the destination (what would run).",{"type":44,"tag":110,"props":536,"children":537},{},[538,543,544,549],{"type":44,"tag":61,"props":539,"children":540},{},[541],{"type":50,"value":542},"unreachable",{"type":50,"value":516},{"type":44,"tag":135,"props":545,"children":547},{"className":546},[],[548],{"type":50,"value":522},{"type":50,"value":550}," to the destination, but the marker is on a different branch and won't reach it without first re-routing.",{"type":44,"tag":264,"props":552,"children":554},{"id":553},"diagnostic-codes",[555],{"type":50,"value":556},"Diagnostic codes",{"type":44,"tag":57,"props":558,"children":559},{},[560,565,567,573,575,581,583,589,590,596,598,604,606,612],{"type":44,"tag":135,"props":561,"children":563},{"className":562},[],[564],{"type":50,"value":501},{"type":50,"value":566}," emits structured diagnostics on the result envelope (",{"type":44,"tag":135,"props":568,"children":570},{"className":569},[],[571],{"type":50,"value":572},"diagnostics[].code",{"type":50,"value":574},") so the agent can branch on the code rather than parsing the prose summary. Each diagnostic also carries ",{"type":44,"tag":135,"props":576,"children":578},{"className":577},[],[579],{"type":50,"value":580},"severity",{"type":50,"value":582}," (",{"type":44,"tag":135,"props":584,"children":586},{"className":585},[],[587],{"type":50,"value":588},"warn",{"type":50,"value":121},{"type":44,"tag":135,"props":591,"children":593},{"className":592},[],[594],{"type":50,"value":595},"info",{"type":50,"value":597},"), a human ",{"type":44,"tag":135,"props":599,"children":601},{"className":600},[],[602],{"type":50,"value":603},"message",{"type":50,"value":605},", and ",{"type":44,"tag":135,"props":607,"children":609},{"className":608},[],[610],{"type":50,"value":611},"hints",{"type":50,"value":613}," — the same hints the CLI prints under the summary line.",{"type":44,"tag":615,"props":616,"children":617},"table",{},[618,647],{"type":44,"tag":619,"props":620,"children":621},"thead",{},[622],{"type":44,"tag":623,"props":624,"children":625},"tr",{},[626,632,637,642],{"type":44,"tag":627,"props":628,"children":629},"th",{},[630],{"type":50,"value":631},"Code",{"type":44,"tag":627,"props":633,"children":634},{},[635],{"type":50,"value":636},"Severity",{"type":44,"tag":627,"props":638,"children":639},{},[640],{"type":50,"value":641},"Meaning in the navigation model",{"type":44,"tag":627,"props":643,"children":644},{},[645],{"type":50,"value":646},"Next move",{"type":44,"tag":648,"props":649,"children":650},"tbody",{},[651,678,709,740,772,861,902,934],{"type":44,"tag":623,"props":652,"children":653},{},[654,664,668,673],{"type":44,"tag":655,"props":656,"children":657},"td",{},[658],{"type":44,"tag":135,"props":659,"children":661},{"className":660},[],[662],{"type":50,"value":663},"MIGRATION.UP_TO_DATE",{"type":44,"tag":655,"props":665,"children":666},{},[667],{"type":50,"value":595},{"type":44,"tag":655,"props":669,"children":670},{},[671],{"type":50,"value":672},"Marker = destination; no edges to walk.",{"type":44,"tag":655,"props":674,"children":675},{},[676],{"type":50,"value":677},"Nothing to do.",{"type":44,"tag":623,"props":679,"children":680},{},[681,690,694,699],{"type":44,"tag":655,"props":682,"children":683},{},[684],{"type":44,"tag":135,"props":685,"children":687},{"className":686},[],[688],{"type":50,"value":689},"MIGRATION.DATABASE_BEHIND",{"type":44,"tag":655,"props":691,"children":692},{},[693],{"type":50,"value":595},{"type":44,"tag":655,"props":695,"children":696},{},[697],{"type":50,"value":698},"Marker is an ancestor of the destination; N pending edges in between.",{"type":44,"tag":655,"props":700,"children":701},{},[702,708],{"type":44,"tag":135,"props":703,"children":705},{"className":704},[],[706],{"type":50,"value":707},"migrate --to \u003Cname> --db $URL",{"type":50,"value":128},{"type":44,"tag":623,"props":710,"children":711},{},[712,721,725,730],{"type":44,"tag":655,"props":713,"children":714},{},[715],{"type":44,"tag":135,"props":716,"children":718},{"className":717},[],[719],{"type":50,"value":720},"MIGRATION.MISSING_INVARIANTS",{"type":44,"tag":655,"props":722,"children":723},{},[724],{"type":50,"value":595},{"type":44,"tag":655,"props":726,"children":727},{},[728],{"type":50,"value":729},"Marker reached destination structurally but missing required invariants the ref declares.",{"type":44,"tag":655,"props":731,"children":732},{},[733,738],{"type":44,"tag":135,"props":734,"children":736},{"className":735},[],[737],{"type":50,"value":707},{"type":50,"value":739}," to take a path that covers them.",{"type":44,"tag":623,"props":741,"children":742},{},[743,752,756,761],{"type":44,"tag":655,"props":744,"children":745},{},[746],{"type":44,"tag":135,"props":747,"children":749},{"className":748},[],[750],{"type":50,"value":751},"MIGRATION.NO_MARKER",{"type":44,"tag":655,"props":753,"children":754},{},[755],{"type":50,"value":588},{"type":44,"tag":655,"props":757,"children":758},{},[759],{"type":50,"value":760},"Online, but the database has no marker row — never initialised.",{"type":44,"tag":655,"props":762,"children":763},{},[764,770],{"type":44,"tag":135,"props":765,"children":767},{"className":766},[],[768],{"type":50,"value":769},"migrate --db $URL",{"type":50,"value":771}," (first apply writes the marker).",{"type":44,"tag":623,"props":773,"children":774},{},[775,784,788,793],{"type":44,"tag":655,"props":776,"children":777},{},[778],{"type":44,"tag":135,"props":779,"children":781},{"className":780},[],[782],{"type":50,"value":783},"MIGRATION.MARKER_NOT_IN_HISTORY",{"type":44,"tag":655,"props":785,"children":786},{},[787],{"type":50,"value":588},{"type":44,"tag":655,"props":789,"children":790},{},[791],{"type":50,"value":792},"Online; marker hash is not a node in the graph. The database was changed outside the migration system.",{"type":44,"tag":655,"props":794,"children":795},{},[796,798,804,806,812,814,820,822,828,830,835,837,843,845,851,853,859],{"type":50,"value":797},"Decide which side is truth: ",{"type":44,"tag":135,"props":799,"children":801},{"className":800},[],[802],{"type":50,"value":803},"db sign",{"type":50,"value":805}," (accept DB as truth), ",{"type":44,"tag":135,"props":807,"children":809},{"className":808},[],[810],{"type":50,"value":811},"db update",{"type":50,"value":813}," (push contract to DB), ",{"type":44,"tag":135,"props":815,"children":817},{"className":816},[],[818],{"type":50,"value":819},"contract infer",{"type":50,"value":821}," (re-derive contract from DB), or ",{"type":44,"tag":135,"props":823,"children":825},{"className":824},[],[826],{"type":50,"value":827},"db verify",{"type":50,"value":829}," (inspect first). ",{"type":44,"tag":61,"props":831,"children":832},{},[833],{"type":50,"value":834},"Not",{"type":50,"value":836}," the same as ",{"type":44,"tag":135,"props":838,"children":840},{"className":839},[],[841],{"type":50,"value":842},"MIGRATION.MARKER_MISMATCH",{"type":50,"value":844},": ",{"type":44,"tag":135,"props":846,"children":848},{"className":847},[],[849],{"type":50,"value":850},"MARKER_NOT_IN_HISTORY",{"type":50,"value":852}," is emitted during the runner's graph walk when the live marker is off the path being traversed; ",{"type":44,"tag":135,"props":854,"children":856},{"className":855},[],[857],{"type":50,"value":858},"MARKER_MISMATCH",{"type":50,"value":860}," fires earlier, at the CLI pre-DDL gate, when the marker hash is not a graph node at all.",{"type":44,"tag":623,"props":862,"children":863},{},[864,873,877,882],{"type":44,"tag":655,"props":865,"children":866},{},[867],{"type":44,"tag":135,"props":868,"children":870},{"className":869},[],[871],{"type":50,"value":872},"MIGRATION.DIVERGED",{"type":44,"tag":655,"props":874,"children":875},{},[876],{"type":50,"value":588},{"type":44,"tag":655,"props":878,"children":879},{},[880],{"type":50,"value":881},"Multiple valid leaves; the destination is ambiguous.",{"type":44,"tag":655,"props":883,"children":884},{},[885,887,892,894,900],{"type":50,"value":886},"Pass ",{"type":44,"tag":135,"props":888,"children":890},{"className":889},[],[891],{"type":50,"value":354},{"type":50,"value":893},", or ",{"type":44,"tag":135,"props":895,"children":897},{"className":896},[],[898],{"type":50,"value":899},"ref set \u003Cname> \u003Chash>",{"type":50,"value":901}," to create one.",{"type":44,"tag":623,"props":903,"children":904},{},[905,914,918,923],{"type":44,"tag":655,"props":906,"children":907},{},[908],{"type":44,"tag":135,"props":909,"children":911},{"className":910},[],[912],{"type":50,"value":913},"CONTRACT.AHEAD",{"type":44,"tag":655,"props":915,"children":916},{},[917],{"type":50,"value":588},{"type":44,"tag":655,"props":919,"children":920},{},[921],{"type":50,"value":922},"Contract head is not in the graph — the contract was edited without re-planning.",{"type":44,"tag":655,"props":924,"children":925},{},[926,932],{"type":44,"tag":135,"props":927,"children":929},{"className":928},[],[930],{"type":50,"value":931},"migration plan",{"type":50,"value":933}," to extend the graph.",{"type":44,"tag":623,"props":935,"children":936},{},[937,946,950,960],{"type":44,"tag":655,"props":938,"children":939},{},[940],{"type":44,"tag":135,"props":941,"children":943},{"className":942},[],[944],{"type":50,"value":945},"CONTRACT.UNREADABLE",{"type":44,"tag":655,"props":947,"children":948},{},[949],{"type":50,"value":588},{"type":44,"tag":655,"props":951,"children":952},{},[953,958],{"type":44,"tag":135,"props":954,"children":956},{"className":955},[],[957],{"type":50,"value":409},{"type":50,"value":959}," couldn't be read.",{"type":44,"tag":655,"props":961,"children":962},{},[963,969],{"type":44,"tag":135,"props":964,"children":966},{"className":965},[],[967],{"type":50,"value":968},"contract emit",{"type":50,"value":970}," to regenerate it.",{"type":44,"tag":264,"props":972,"children":974},{"id":973},"graph-tree-output",[975],{"type":50,"value":976},"Graph-tree output",{"type":44,"tag":57,"props":978,"children":979},{},[980,985,987,993],{"type":44,"tag":135,"props":981,"children":983},{"className":982},[],[984],{"type":50,"value":501},{"type":50,"value":986}," (and ",{"type":44,"tag":135,"props":988,"children":990},{"className":989},[],[991],{"type":50,"value":992},"migration list",{"type":50,"value":994},") render the migration graph as a colored lane tree in the terminal. Two flags control the rendering:",{"type":44,"tag":106,"props":996,"children":997},{},[998,1009],{"type":44,"tag":110,"props":999,"children":1000},{},[1001,1007],{"type":44,"tag":135,"props":1002,"children":1004},{"className":1003},[],[1005],{"type":50,"value":1006},"--legend",{"type":50,"value":1008}," — prints the key for the tree glyphs and lane colors before the tree.",{"type":44,"tag":110,"props":1010,"children":1011},{},[1012,1018],{"type":44,"tag":135,"props":1013,"children":1015},{"className":1014},[],[1016],{"type":50,"value":1017},"--ascii",{"type":50,"value":1019}," — replaces box-drawing glyphs with pipe-safe ASCII characters (useful in CI logs or environments that don't support Unicode).",{"type":44,"tag":57,"props":1021,"children":1022},{},[1023,1025,1030,1032,1038,1040,1046,1048,1053],{"type":50,"value":1024},"Both flags are also available on ",{"type":44,"tag":135,"props":1026,"children":1028},{"className":1027},[],[1029],{"type":50,"value":992},{"type":50,"value":1031}," and ",{"type":44,"tag":135,"props":1033,"children":1035},{"className":1034},[],[1036],{"type":50,"value":1037},"migration graph",{"type":50,"value":1039},". ",{"type":44,"tag":135,"props":1041,"children":1043},{"className":1042},[],[1044],{"type":50,"value":1045},"migration log",{"type":50,"value":1047}," supports ",{"type":44,"tag":135,"props":1049,"children":1051},{"className":1050},[],[1052],{"type":50,"value":1017},{"type":50,"value":1054}," only (it renders a flat chronological table, not a tree).",{"type":44,"tag":264,"props":1056,"children":1058},{"id":1057},"plan-and-apply-time-diagnostics",[1059],{"type":50,"value":1060},"Plan- and apply-time diagnostics",{"type":44,"tag":57,"props":1062,"children":1063},{},[1064,1066,1071,1072,1078,1079,1085,1087,1092,1094,1101,1102,1108],{"type":50,"value":1065},"These codes surface on ",{"type":44,"tag":135,"props":1067,"children":1069},{"className":1068},[],[1070],{"type":50,"value":931},{"type":50,"value":371},{"type":44,"tag":135,"props":1073,"children":1075},{"className":1074},[],[1076],{"type":50,"value":1077},"ref set",{"type":50,"value":605},{"type":44,"tag":135,"props":1080,"children":1082},{"className":1081},[],[1083],{"type":50,"value":1084},"migrate",{"type":50,"value":1086}," — not on ",{"type":44,"tag":135,"props":1088,"children":1090},{"className":1089},[],[1091],{"type":50,"value":501},{"type":50,"value":1093},". See ",{"type":44,"tag":1095,"props":1096,"children":1098},"a",{"href":1097},"..\u002F..\u002Fdocs\u002Farchitecture%20docs\u002Fsubsystems\u002F7.%20Migration%20System.md#recovery-affordances",[1099],{"type":50,"value":1100},"Migration System § Recovery affordances",{"type":50,"value":1031},{"type":44,"tag":1095,"props":1103,"children":1105},{"href":1104},"..\u002F..\u002Fdocs\u002Farchitecture%20docs\u002Fadrs\u002FADR%20218%20-%20Refs%20with%20paired%20contract%20snapshots%20and%20universal%20graph-node%20invariant.md",[1106],{"type":50,"value":1107},"ADR 218",{"type":50,"value":128},{"type":44,"tag":615,"props":1110,"children":1111},{},[1112,1136],{"type":44,"tag":619,"props":1113,"children":1114},{},[1115],{"type":44,"tag":623,"props":1116,"children":1117},{},[1118,1122,1127,1132],{"type":44,"tag":627,"props":1119,"children":1120},{},[1121],{"type":50,"value":631},{"type":44,"tag":627,"props":1123,"children":1124},{},[1125],{"type":50,"value":1126},"When",{"type":44,"tag":627,"props":1128,"children":1129},{},[1130],{"type":50,"value":1131},"Meaning",{"type":44,"tag":627,"props":1133,"children":1134},{},[1135],{"type":50,"value":646},{"type":44,"tag":648,"props":1137,"children":1138},{},[1139,1212,1263,1308],{"type":44,"tag":623,"props":1140,"children":1141},{},[1142,1151,1166,1186],{"type":44,"tag":655,"props":1143,"children":1144},{},[1145],{"type":44,"tag":135,"props":1146,"children":1148},{"className":1147},[],[1149],{"type":50,"value":1150},"MIGRATION.HASH_NOT_IN_GRAPH",{"type":44,"tag":655,"props":1152,"children":1153},{},[1154,1159,1161],{"type":44,"tag":135,"props":1155,"children":1157},{"className":1156},[],[1158],{"type":50,"value":931},{"type":50,"value":1160}," (non-empty graph) or ",{"type":44,"tag":135,"props":1162,"children":1164},{"className":1163},[],[1165],{"type":50,"value":1077},{"type":44,"tag":655,"props":1167,"children":1168},{},[1169,1171,1177,1179,1184],{"type":50,"value":1170},"Resolved hash is not a node in the on-disk migration graph — typical when the default ",{"type":44,"tag":135,"props":1172,"children":1174},{"className":1173},[],[1175],{"type":50,"value":1176},"db",{"type":50,"value":1178}," ref points past the graph tip after dev-only ",{"type":44,"tag":135,"props":1180,"children":1182},{"className":1181},[],[1183],{"type":50,"value":811},{"type":50,"value":1185}," cycles.",{"type":44,"tag":655,"props":1187,"children":1188},{},[1189,1195,1197,1203,1205,1211],{"type":44,"tag":135,"props":1190,"children":1192},{"className":1191},[],[1193],{"type":50,"value":1194},"migration plan --from \u003Creachable-ref>",{"type":50,"value":1196}," (e.g. ",{"type":44,"tag":135,"props":1198,"children":1200},{"className":1199},[],[1201],{"type":50,"value":1202},"--from production",{"type":50,"value":1204},"); or realign the ref with ",{"type":44,"tag":135,"props":1206,"children":1208},{"className":1207},[],[1209],{"type":50,"value":1210},"ref set db \u003Cgraph-node-hash>",{"type":50,"value":128},{"type":44,"tag":623,"props":1213,"children":1214},{},[1215,1224,1232,1245],{"type":44,"tag":655,"props":1216,"children":1217},{},[1218],{"type":44,"tag":135,"props":1219,"children":1221},{"className":1220},[],[1222],{"type":50,"value":1223},"MIGRATION.SNAPSHOT_MISSING",{"type":44,"tag":655,"props":1225,"children":1226},{},[1227],{"type":44,"tag":135,"props":1228,"children":1230},{"className":1229},[],[1231],{"type":50,"value":931},{"type":44,"tag":655,"props":1233,"children":1234},{},[1235,1237,1243],{"type":50,"value":1236},"A named ref has no pointer file (",{"type":44,"tag":135,"props":1238,"children":1240},{"className":1239},[],[1241],{"type":50,"value":1242},"\u003Cname>.json",{"type":50,"value":1244},"), and the hash being resolved isn't a node in the migration graph either.",{"type":44,"tag":655,"props":1246,"children":1247},{},[1248,1253,1255,1261],{"type":44,"tag":135,"props":1249,"children":1251},{"className":1250},[],[1252],{"type":50,"value":899},{"type":50,"value":1254}," to create the ref, ",{"type":44,"tag":135,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":50,"value":1260},"db update --advance-ref \u003Cname>",{"type":50,"value":1262}," to advance it, or pass a hash that is a graph node.",{"type":44,"tag":623,"props":1264,"children":1265},{},[1266,1274,1284,1289],{"type":44,"tag":655,"props":1267,"children":1268},{},[1269],{"type":44,"tag":135,"props":1270,"children":1272},{"className":1271},[],[1273],{"type":50,"value":842},{"type":44,"tag":655,"props":1275,"children":1276},{},[1277,1282],{"type":44,"tag":135,"props":1278,"children":1280},{"className":1279},[],[1281],{"type":50,"value":1084},{"type":50,"value":1283}," (pre-DDL, before the runner)",{"type":44,"tag":655,"props":1285,"children":1286},{},[1287],{"type":50,"value":1288},"Live DB marker hash is not a graph node — drift the offline planner cannot see.",{"type":44,"tag":655,"props":1290,"children":1291},{},[1292,1298,1300,1306],{"type":44,"tag":135,"props":1293,"children":1295},{"className":1294},[],[1296],{"type":50,"value":1297},"migration plan --from \u003Cgraph-tip>",{"type":50,"value":1299}," if the marker is canonical; ",{"type":44,"tag":135,"props":1301,"children":1303},{"className":1302},[],[1304],{"type":50,"value":1305},"ref set db \u003Cmarker-hash>",{"type":50,"value":1307}," if the on-disk graph is canonical; investigate out-of-band applies.",{"type":44,"tag":623,"props":1309,"children":1310},{},[1311,1320,1330,1335],{"type":44,"tag":655,"props":1312,"children":1313},{},[1314],{"type":44,"tag":135,"props":1315,"children":1317},{"className":1316},[],[1318],{"type":50,"value":1319},"MIGRATION.PATH_UNREACHABLE",{"type":44,"tag":655,"props":1321,"children":1322},{},[1323,1328],{"type":44,"tag":135,"props":1324,"children":1326},{"className":1325},[],[1327],{"type":50,"value":1084},{"type":50,"value":1329}," (path resolution)",{"type":44,"tag":655,"props":1331,"children":1332},{},[1333],{"type":50,"value":1334},"No migration path from the current marker to the resolved target in the on-disk graph.",{"type":44,"tag":655,"props":1336,"children":1337},{},[1338,1340,1346,1348,1354,1355,1361,1363,1369,1371,1376],{"type":50,"value":1339},"Read the improved ",{"type":44,"tag":135,"props":1341,"children":1343},{"className":1342},[],[1344],{"type":50,"value":1345},"fix",{"type":50,"value":1347}," payload — it names ",{"type":44,"tag":135,"props":1349,"children":1351},{"className":1350},[],[1352],{"type":50,"value":1353},"fromHash",{"type":50,"value":155},{"type":44,"tag":135,"props":1356,"children":1358},{"className":1357},[],[1359],{"type":50,"value":1360},"targetHash",{"type":50,"value":1362}," and suggests ",{"type":44,"tag":135,"props":1364,"children":1366},{"className":1365},[],[1367],{"type":50,"value":1368},"migration plan --from \u003Cfrom> --to \u003Ctarget>",{"type":50,"value":1370},"; run ",{"type":44,"tag":135,"props":1372,"children":1374},{"className":1373},[],[1375],{"type":50,"value":992},{"type":50,"value":1377}," to inspect the graph.",{"type":44,"tag":57,"props":1379,"children":1380},{},[1381,1383,1389,1391,1397,1399,1404,1406,1411,1413,1418],{"type":50,"value":1382},"A CI gate should read ",{"type":44,"tag":135,"props":1384,"children":1386},{"className":1385},[],[1387],{"type":50,"value":1388},"diagnostics",{"type":50,"value":1390}," from ",{"type":44,"tag":135,"props":1392,"children":1394},{"className":1393},[],[1395],{"type":50,"value":1396},"--json",{"type":50,"value":1398}," output and decide based on ",{"type":44,"tag":135,"props":1400,"children":1402},{"className":1401},[],[1403],{"type":50,"value":580},{"type":50,"value":1405}," plus ",{"type":44,"tag":135,"props":1407,"children":1409},{"className":1408},[],[1410],{"type":50,"value":135},{"type":50,"value":1412},"; see ",{"type":44,"tag":72,"props":1414,"children":1415},{},[1416],{"type":50,"value":1417},"Workflow — CI",{"type":50,"value":1419}," below for the structure.",{"type":44,"tag":99,"props":1421,"children":1423},{"id":1422},"workflow-whats-about-to-run-on-deploy",[1424,1426],{"type":50,"value":1425},"Workflow — ",{"type":44,"tag":72,"props":1427,"children":1428},{},[1429],{"type":50,"value":1430},"\"What's about to run on deploy?\"",{"type":44,"tag":57,"props":1432,"children":1433},{},[1434,1436],{"type":50,"value":1435},"The user asks: ",{"type":44,"tag":72,"props":1437,"children":1438},{},[1439],{"type":50,"value":1440},"\"I'm about to merge this PR. What migrations are going to run when I deploy to staging?\"",{"type":44,"tag":57,"props":1442,"children":1443},{},[1444,1446,1450,1452,1456,1458,1463],{"type":50,"value":1445},"This is the navigation question: ",{"type":44,"tag":61,"props":1447,"children":1448},{},[1449],{"type":50,"value":252},{"type":50,"value":1451}," = staging's live marker; ",{"type":44,"tag":61,"props":1453,"children":1454},{},[1455],{"type":50,"value":259},{"type":50,"value":1457}," = the ref ",{"type":44,"tag":135,"props":1459,"children":1461},{"className":1460},[],[1462],{"type":50,"value":153},{"type":50,"value":1464}," (or the contract head if you haven't set one). Ask the system:",{"type":44,"tag":1466,"props":1467,"children":1472},"pre",{"className":1468,"code":1469,"language":1470,"meta":1471,"style":1471},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm prisma-next migration status --to staging --db \"$STAGING_DATABASE_URL\"\n","bash","",[1473],{"type":44,"tag":135,"props":1474,"children":1475},{"__ignoreMap":1471},[1476],{"type":44,"tag":1477,"props":1478,"children":1481},"span",{"class":1479,"line":1480},"line",1,[1482,1488,1494,1499,1504,1509,1514,1519,1525,1531],{"type":44,"tag":1477,"props":1483,"children":1485},{"style":1484},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[1486],{"type":50,"value":1487},"pnpm",{"type":44,"tag":1477,"props":1489,"children":1491},{"style":1490},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[1492],{"type":50,"value":1493}," prisma-next",{"type":44,"tag":1477,"props":1495,"children":1496},{"style":1490},[1497],{"type":50,"value":1498}," migration",{"type":44,"tag":1477,"props":1500,"children":1501},{"style":1490},[1502],{"type":50,"value":1503}," status",{"type":44,"tag":1477,"props":1505,"children":1506},{"style":1490},[1507],{"type":50,"value":1508}," --to",{"type":44,"tag":1477,"props":1510,"children":1511},{"style":1490},[1512],{"type":50,"value":1513}," staging",{"type":44,"tag":1477,"props":1515,"children":1516},{"style":1490},[1517],{"type":50,"value":1518}," --db",{"type":44,"tag":1477,"props":1520,"children":1522},{"style":1521},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[1523],{"type":50,"value":1524}," \"",{"type":44,"tag":1477,"props":1526,"children":1528},{"style":1527},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[1529],{"type":50,"value":1530},"$STAGING_DATABASE_URL",{"type":44,"tag":1477,"props":1532,"children":1533},{"style":1521},[1534],{"type":50,"value":1535},"\"\n",{"type":44,"tag":57,"props":1537,"children":1538},{},[1539],{"type":50,"value":1540},"The command:",{"type":44,"tag":1542,"props":1543,"children":1544},"ol",{},[1545,1550,1562,1592],{"type":44,"tag":110,"props":1546,"children":1547},{},[1548],{"type":50,"value":1549},"Reads the staging DB's marker (the origin).",{"type":44,"tag":110,"props":1551,"children":1552},{},[1553,1555,1560],{"type":50,"value":1554},"Resolves ",{"type":44,"tag":135,"props":1556,"children":1558},{"className":1557},[],[1559],{"type":50,"value":153},{"type":50,"value":1561}," to a contract hash (the destination).",{"type":44,"tag":110,"props":1563,"children":1564},{},[1565,1567,1572,1573,1578,1579,1584,1586,1591],{"type":50,"value":1566},"Renders the path between them as an ordered list of migrations, with per-edge ",{"type":44,"tag":135,"props":1568,"children":1570},{"className":1569},[],[1571],{"type":50,"value":514},{"type":50,"value":155},{"type":44,"tag":135,"props":1574,"children":1576},{"className":1575},[],[1577],{"type":50,"value":532},{"type":50,"value":155},{"type":44,"tag":135,"props":1580,"children":1582},{"className":1581},[],[1583],{"type":50,"value":542},{"type":50,"value":1585}," status, and an explicit summary line of the form ",{"type":44,"tag":72,"props":1587,"children":1588},{},[1589],{"type":50,"value":1590},"\"N migration(s) behind ref 'staging'\"",{"type":50,"value":128},{"type":44,"tag":110,"props":1593,"children":1594},{},[1595],{"type":50,"value":1596},"Prints a header that names the config, migrations directory, the active ref, and the database connection (masked) — so the framing is visible in the output.",{"type":44,"tag":57,"props":1598,"children":1599},{},[1600,1602,1607,1609,1614,1616,1621],{"type":50,"value":1601},"If you omit ",{"type":44,"tag":135,"props":1603,"children":1605},{"className":1604},[],[1606],{"type":50,"value":434},{"type":50,"value":1608},", the command runs offline: it lists the migrations on disk but cannot tell you what's applied, because it has no origin. That's fine for ",{"type":44,"tag":72,"props":1610,"children":1611},{},[1612],{"type":50,"value":1613},"\"what's on this branch?\"",{"type":50,"value":1615},"; it's not fine for ",{"type":44,"tag":72,"props":1617,"children":1618},{},[1619],{"type":50,"value":1620},"\"what's about to run on staging?\"",{"type":50,"value":1622}," — for that you need staging's live marker.",{"type":44,"tag":57,"props":1624,"children":1625},{},[1626,1627,1632,1634,1639,1641,1646],{"type":50,"value":1601},{"type":44,"tag":135,"props":1628,"children":1630},{"className":1629},[],[1631],{"type":50,"value":401},{"type":50,"value":1633},", the destination defaults to the contract head — which answers ",{"type":44,"tag":72,"props":1635,"children":1636},{},[1637],{"type":50,"value":1638},"\"is this branch's contract reachable from the database, and how?\"",{"type":50,"value":1640},", not ",{"type":44,"tag":72,"props":1642,"children":1643},{},[1644],{"type":50,"value":1645},"\"what runs on deploy\"",{"type":50,"value":1647},". Pass the ref explicitly when the question is about a specific environment.",{"type":44,"tag":57,"props":1649,"children":1650},{},[1651,1656,1658,1664,1665,1671,1672,1678,1679,1685],{"type":44,"tag":135,"props":1652,"children":1654},{"className":1653},[],[1655],{"type":50,"value":501},{"type":50,"value":1657}," summarises each pending migration's operations by class (",{"type":44,"tag":135,"props":1659,"children":1661},{"className":1660},[],[1662],{"type":50,"value":1663},"additive",{"type":50,"value":371},{"type":44,"tag":135,"props":1666,"children":1668},{"className":1667},[],[1669],{"type":50,"value":1670},"widening",{"type":50,"value":371},{"type":44,"tag":135,"props":1673,"children":1675},{"className":1674},[],[1676],{"type":50,"value":1677},"data",{"type":50,"value":371},{"type":44,"tag":135,"props":1680,"children":1682},{"className":1681},[],[1683],{"type":50,"value":1684},"destructive",{"type":50,"value":1686},") and reports a destructive-op count when destructive operations are present. Surface that count to the user before they merge or deploy — destructive operations are the class that warrants manual review.",{"type":44,"tag":99,"props":1688,"children":1690},{"id":1689},"workflow-what-state-is-each-environment-at",[1691,1692],{"type":50,"value":1425},{"type":44,"tag":72,"props":1693,"children":1694},{},[1695],{"type":50,"value":1696},"\"What state is each environment at?\"",{"type":44,"tag":57,"props":1698,"children":1699},{},[1700,1702,1708],{"type":50,"value":1701},"Just ",{"type":44,"tag":135,"props":1703,"children":1705},{"className":1704},[],[1706],{"type":50,"value":1707},"migration status --db $URL",{"type":50,"value":1709}," for each environment's DB. The marker (origin) comes back from the DB itself; the summary line tells you whether the environment is at the contract head, at a named ref, ahead of head, or on a divergent branch.",{"type":44,"tag":99,"props":1711,"children":1713},{"id":1712},"concept-concurrent-migrations-on-the-same-branch-point",[1714],{"type":50,"value":1715},"Concept — concurrent migrations on the same branch point",{"type":44,"tag":57,"props":1717,"children":1718},{},[1719,1721,1726],{"type":50,"value":1720},"This used to be called ",{"type":44,"tag":72,"props":1722,"children":1723},{},[1724],{"type":50,"value":1725},"diamond convergence",{"type":50,"value":1727}," in some PN docs; the situation is the same regardless of the label.",{"type":44,"tag":57,"props":1729,"children":1730},{},[1731,1736,1738,1743,1745,1750,1752,1757,1759,1764,1766,1771],{"type":44,"tag":61,"props":1732,"children":1733},{},[1734],{"type":50,"value":1735},"What's happening.",{"type":50,"value":1737}," Two topic branches each authored a migration off the same parent contract hash. The first branch merges to ",{"type":44,"tag":135,"props":1739,"children":1741},{"className":1740},[],[1742],{"type":50,"value":140},{"type":50,"value":1744},"; the destination ref (e.g. ",{"type":44,"tag":135,"props":1746,"children":1748},{"className":1747},[],[1749],{"type":50,"value":161},{"type":50,"value":1751},") advances to that branch's ",{"type":44,"tag":135,"props":1753,"children":1755},{"className":1754},[],[1756],{"type":50,"value":476},{"type":50,"value":1758}," hash. Your branch's migration still has its ",{"type":44,"tag":135,"props":1760,"children":1762},{"className":1761},[],[1763],{"type":50,"value":468},{"type":50,"value":1765}," hash pointing at the ",{"type":44,"tag":72,"props":1767,"children":1768},{},[1769],{"type":50,"value":1770},"old",{"type":50,"value":1772}," parent. The migration graph, after rebase, no longer has a clean path through your migration:",{"type":44,"tag":106,"props":1774,"children":1775},{},[1776,1788],{"type":44,"tag":110,"props":1777,"children":1778},{},[1779,1781,1786],{"type":50,"value":1780},"Your migration's ",{"type":44,"tag":135,"props":1782,"children":1784},{"className":1783},[],[1785],{"type":50,"value":468},{"type":50,"value":1787}," is no longer an ancestor of the new head.",{"type":44,"tag":110,"props":1789,"children":1790},{},[1791,1793,1798],{"type":50,"value":1792},"Or your migration's ",{"type":44,"tag":135,"props":1794,"children":1796},{"className":1795},[],[1797],{"type":50,"value":468},{"type":50,"value":1799}," is reachable, but the path through your migration arrives at a hash that's not the union of both branches' changes.",{"type":44,"tag":57,"props":1801,"children":1802},{},[1803],{"type":50,"value":1804},"Either way, the on-disk plan is stale.",{"type":44,"tag":57,"props":1806,"children":1807},{},[1808,1813,1815,1820,1822,1827,1829,1834],{"type":44,"tag":61,"props":1809,"children":1810},{},[1811],{"type":50,"value":1812},"Resolution.",{"type":50,"value":1814}," The on-disk plan is stale because its ",{"type":44,"tag":135,"props":1816,"children":1818},{"className":1817},[],[1819],{"type":50,"value":468},{"type":50,"value":1821}," hash is no longer the head of the graph; apply the cluster's standard ",{"type":44,"tag":72,"props":1823,"children":1824},{},[1825],{"type":50,"value":1826},"edit → plan → apply",{"type":50,"value":1828}," loop to the post-rebase state and the planner produces a fresh migration whose ",{"type":44,"tag":135,"props":1830,"children":1832},{"className":1831},[],[1833],{"type":50,"value":468},{"type":50,"value":1835}," matches the new head.",{"type":44,"tag":57,"props":1837,"children":1838},{},[1839,1844,1846,1852,1854,1859],{"type":44,"tag":61,"props":1840,"children":1841},{},[1842],{"type":50,"value":1843},"The one thing the planner can't do for you",{"type":50,"value":1845}," is port custom data-transform logic from the abandoned ",{"type":44,"tag":135,"props":1847,"children":1849},{"className":1848},[],[1850],{"type":50,"value":1851},"migration.ts",{"type":50,"value":1853}," into the new one — schema deltas are derived from the contract, but any hand-written ",{"type":44,"tag":135,"props":1855,"children":1857},{"className":1856},[],[1858],{"type":50,"value":1677},{"type":50,"value":1860}," operations are yours to carry across before applying. There is no separate \"revalidate\" step, no special \"diamond apply\" flow.",{"type":44,"tag":99,"props":1862,"children":1864},{"id":1863},"workflow-set-list-get-delete-refs",[1865],{"type":50,"value":1866},"Workflow — set, list, get, delete refs",{"type":44,"tag":57,"props":1868,"children":1869},{},[1870],{"type":50,"value":1871},"Refs are small artifacts. There's no per-environment lifecycle; you just point a name at a hash.",{"type":44,"tag":1466,"props":1873,"children":1875},{"className":1468,"code":1874,"language":1470,"meta":1471,"style":1471},"pnpm prisma-next ref set production \u003Ccontract-hash>\npnpm prisma-next ref list\n# `ref get` was removed — use `ref list` and filter by name\npnpm prisma-next ref list | grep production\npnpm prisma-next ref delete production\n",[1876],{"type":44,"tag":135,"props":1877,"children":1878},{"__ignoreMap":1471},[1879,1925,1946,1956,1992],{"type":44,"tag":1477,"props":1880,"children":1881},{"class":1479,"line":1480},[1882,1886,1890,1895,1900,1905,1910,1915,1920],{"type":44,"tag":1477,"props":1883,"children":1884},{"style":1484},[1885],{"type":50,"value":1487},{"type":44,"tag":1477,"props":1887,"children":1888},{"style":1490},[1889],{"type":50,"value":1493},{"type":44,"tag":1477,"props":1891,"children":1892},{"style":1490},[1893],{"type":50,"value":1894}," ref",{"type":44,"tag":1477,"props":1896,"children":1897},{"style":1490},[1898],{"type":50,"value":1899}," set",{"type":44,"tag":1477,"props":1901,"children":1902},{"style":1490},[1903],{"type":50,"value":1904}," production",{"type":44,"tag":1477,"props":1906,"children":1907},{"style":1521},[1908],{"type":50,"value":1909}," \u003C",{"type":44,"tag":1477,"props":1911,"children":1912},{"style":1490},[1913],{"type":50,"value":1914},"contract-has",{"type":44,"tag":1477,"props":1916,"children":1917},{"style":1527},[1918],{"type":50,"value":1919},"h",{"type":44,"tag":1477,"props":1921,"children":1922},{"style":1521},[1923],{"type":50,"value":1924},">\n",{"type":44,"tag":1477,"props":1926,"children":1928},{"class":1479,"line":1927},2,[1929,1933,1937,1941],{"type":44,"tag":1477,"props":1930,"children":1931},{"style":1484},[1932],{"type":50,"value":1487},{"type":44,"tag":1477,"props":1934,"children":1935},{"style":1490},[1936],{"type":50,"value":1493},{"type":44,"tag":1477,"props":1938,"children":1939},{"style":1490},[1940],{"type":50,"value":1894},{"type":44,"tag":1477,"props":1942,"children":1943},{"style":1490},[1944],{"type":50,"value":1945}," list\n",{"type":44,"tag":1477,"props":1947,"children":1949},{"class":1479,"line":1948},3,[1950],{"type":44,"tag":1477,"props":1951,"children":1953},{"style":1952},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1954],{"type":50,"value":1955},"# `ref get` was removed — use `ref list` and filter by name\n",{"type":44,"tag":1477,"props":1957,"children":1959},{"class":1479,"line":1958},4,[1960,1964,1968,1972,1977,1982,1987],{"type":44,"tag":1477,"props":1961,"children":1962},{"style":1484},[1963],{"type":50,"value":1487},{"type":44,"tag":1477,"props":1965,"children":1966},{"style":1490},[1967],{"type":50,"value":1493},{"type":44,"tag":1477,"props":1969,"children":1970},{"style":1490},[1971],{"type":50,"value":1894},{"type":44,"tag":1477,"props":1973,"children":1974},{"style":1490},[1975],{"type":50,"value":1976}," list",{"type":44,"tag":1477,"props":1978,"children":1979},{"style":1521},[1980],{"type":50,"value":1981}," |",{"type":44,"tag":1477,"props":1983,"children":1984},{"style":1484},[1985],{"type":50,"value":1986}," grep",{"type":44,"tag":1477,"props":1988,"children":1989},{"style":1490},[1990],{"type":50,"value":1991}," production\n",{"type":44,"tag":1477,"props":1993,"children":1995},{"class":1479,"line":1994},5,[1996,2000,2004,2008,2013],{"type":44,"tag":1477,"props":1997,"children":1998},{"style":1484},[1999],{"type":50,"value":1487},{"type":44,"tag":1477,"props":2001,"children":2002},{"style":1490},[2003],{"type":50,"value":1493},{"type":44,"tag":1477,"props":2005,"children":2006},{"style":1490},[2007],{"type":50,"value":1894},{"type":44,"tag":1477,"props":2009,"children":2010},{"style":1490},[2011],{"type":50,"value":2012}," delete",{"type":44,"tag":1477,"props":2014,"children":2015},{"style":1490},[2016],{"type":50,"value":1991},{"type":44,"tag":57,"props":2018,"children":2019},{},[2020,2025,2027,2032,2034,2039,2041,2046],{"type":44,"tag":135,"props":2021,"children":2023},{"className":2022},[],[2024],{"type":50,"value":1077},{"type":50,"value":2026}," writes a file at ",{"type":44,"tag":135,"props":2028,"children":2030},{"className":2029},[],[2031],{"type":50,"value":362},{"type":50,"value":2033}," carrying the hash and any required invariants. Refs are commit-friendly artifacts — keep them in git; the team agrees on what ",{"type":44,"tag":135,"props":2035,"children":2037},{"className":2036},[],[2038],{"type":50,"value":161},{"type":50,"value":2040}," points at the same way they agree on what ",{"type":44,"tag":135,"props":2042,"children":2044},{"className":2043},[],[2045],{"type":50,"value":140},{"type":50,"value":2047}," is.",{"type":44,"tag":99,"props":2049,"children":2051},{"id":2050},"workflow-apply-a-migration-against-an-environment",[2052],{"type":50,"value":2053},"Workflow — apply a migration against an environment",{"type":44,"tag":1466,"props":2055,"children":2057},{"className":1468,"code":2056,"language":1470,"meta":1471,"style":1471},"pnpm prisma-next migrate --to production --db \"$PRODUCTION_DATABASE_URL\"\n",[2058],{"type":44,"tag":135,"props":2059,"children":2060},{"__ignoreMap":1471},[2061],{"type":44,"tag":1477,"props":2062,"children":2063},{"class":1479,"line":1480},[2064,2068,2072,2077,2081,2085,2089,2093,2098],{"type":44,"tag":1477,"props":2065,"children":2066},{"style":1484},[2067],{"type":50,"value":1487},{"type":44,"tag":1477,"props":2069,"children":2070},{"style":1490},[2071],{"type":50,"value":1493},{"type":44,"tag":1477,"props":2073,"children":2074},{"style":1490},[2075],{"type":50,"value":2076}," migrate",{"type":44,"tag":1477,"props":2078,"children":2079},{"style":1490},[2080],{"type":50,"value":1508},{"type":44,"tag":1477,"props":2082,"children":2083},{"style":1490},[2084],{"type":50,"value":1904},{"type":44,"tag":1477,"props":2086,"children":2087},{"style":1490},[2088],{"type":50,"value":1518},{"type":44,"tag":1477,"props":2090,"children":2091},{"style":1521},[2092],{"type":50,"value":1524},{"type":44,"tag":1477,"props":2094,"children":2095},{"style":1527},[2096],{"type":50,"value":2097},"$PRODUCTION_DATABASE_URL",{"type":44,"tag":1477,"props":2099,"children":2100},{"style":1521},[2101],{"type":50,"value":1535},{"type":44,"tag":57,"props":2103,"children":2104},{},[2105],{"type":50,"value":2106},"The destination is the ref's hash; the origin is the production DB's live marker. The command computes the path between them and applies each pending migration in order, advancing the marker.",{"type":44,"tag":57,"props":2108,"children":2109},{},[2110,2115,2117,2122],{"type":44,"tag":135,"props":2111,"children":2113},{"className":2112},[],[2114],{"type":50,"value":434},{"type":50,"value":2116}," is the environment selection knob. ",{"type":44,"tag":135,"props":2118,"children":2120},{"className":2119},[],[2121],{"type":50,"value":401},{"type":50,"value":2123}," is the destination-hash knob. They're independent.",{"type":44,"tag":99,"props":2125,"children":2127},{"id":2126},"concept-ref-mismatch-on-ci-deploy",[2128],{"type":50,"value":2129},"Concept — ref-mismatch on CI \u002F deploy",{"type":44,"tag":57,"props":2131,"children":2132},{},[2133,2135],{"type":50,"value":2134},"CI reports: ",{"type":44,"tag":72,"props":2136,"children":2137},{},[2138,2140,2145],{"type":50,"value":2139},"\"the recorded ref ",{"type":44,"tag":135,"props":2141,"children":2143},{"className":2142},[],[2144],{"type":50,"value":161},{"type":50,"value":2146}," is at hash X; the live DB is at hash Y.\"",{"type":44,"tag":57,"props":2148,"children":2149},{},[2150,2152,2157],{"type":50,"value":2151},"The mismatch is a fact about ",{"type":44,"tag":72,"props":2153,"children":2154},{},[2155],{"type":50,"value":2156},"two pieces of state that disagree",{"type":50,"value":2158},". The investigation is the same regardless of which piece is wrong:",{"type":44,"tag":106,"props":2160,"children":2161},{},[2162,2180,2205],{"type":44,"tag":110,"props":2163,"children":2164},{},[2165,2170,2172,2178],{"type":44,"tag":61,"props":2166,"children":2167},{},[2168],{"type":50,"value":2169},"DB ahead of the ref.",{"type":50,"value":2171}," Someone applied a migration outside CI without updating the ref in git. Re-record the ref with ",{"type":44,"tag":135,"props":2173,"children":2175},{"className":2174},[],[2176],{"type":50,"value":2177},"prisma-next ref set \u003Cref-name> \u003Cdb-marker-hash>",{"type":50,"value":2179}," (commit + push); then audit how the out-of-band apply happened.",{"type":44,"tag":110,"props":2181,"children":2182},{},[2183,2188,2190,2196,2198,2203],{"type":44,"tag":61,"props":2184,"children":2185},{},[2186],{"type":50,"value":2187},"DB behind the ref.",{"type":50,"value":2189}," A previous deploy was rolled back, or the DB was restored from an older backup. Either re-apply forward with ",{"type":44,"tag":135,"props":2191,"children":2193},{"className":2192},[],[2194],{"type":50,"value":2195},"prisma-next migrate --to \u003Cref-name> --db $URL",{"type":50,"value":2197},", or re-route the ref backward to match what's actually deployed with ",{"type":44,"tag":135,"props":2199,"children":2201},{"className":2200},[],[2202],{"type":50,"value":2177},{"type":50,"value":2204},". The choice is the user's — name both options.",{"type":44,"tag":110,"props":2206,"children":2207},{},[2208,2213,2215,2221,2223,2229,2231,2237],{"type":44,"tag":61,"props":2209,"children":2210},{},[2211],{"type":50,"value":2212},"DB on a different branch.",{"type":50,"value":2214}," An out-of-band schema change (manual SQL, ad-hoc migration) wrote something the migration graph doesn't model. Run ",{"type":44,"tag":135,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":50,"value":2220},"prisma-next db verify",{"type":50,"value":2222}," to inspect the drift, then either ",{"type":44,"tag":135,"props":2224,"children":2226},{"className":2225},[],[2227],{"type":50,"value":2228},"prisma-next contract infer",{"type":50,"value":2230}," to re-derive the contract from the database, or edit the contract and run ",{"type":44,"tag":135,"props":2232,"children":2234},{"className":2233},[],[2235],{"type":50,"value":2236},"prisma-next migration plan",{"type":50,"value":2238}," so the database is the eventual destination.",{"type":44,"tag":57,"props":2240,"children":2241},{},[2242,2247],{"type":44,"tag":135,"props":2243,"children":2245},{"className":2244},[],[2246],{"type":50,"value":1077},{"type":50,"value":2248}," to silently align the ref with whatever the DB happens to be at is almost never the right move. It papers over drift that you'll pay for later.",{"type":44,"tag":99,"props":2250,"children":2252},{"id":2251},"workflow-ci-verify-a-branch-can-advance-the-target-environment",[2253],{"type":50,"value":2254},"Workflow — CI: verify a branch can advance the target environment",{"type":44,"tag":57,"props":2256,"children":2257},{},[2258,2260,2266,2268,2274,2276,2281,2283,2288],{"type":50,"value":2259},"The gate is ",{"type":44,"tag":135,"props":2261,"children":2263},{"className":2262},[],[2264],{"type":50,"value":2265},"migration status --to \u003Cenv> --db $URL",{"type":50,"value":2267},": it computes the path from the live marker to the ref and reports it, without mutating anything. There is no ",{"type":44,"tag":135,"props":2269,"children":2271},{"className":2270},[],[2272],{"type":50,"value":2273},"--dry-run",{"type":50,"value":2275}," flag on ",{"type":44,"tag":135,"props":2277,"children":2279},{"className":2278},[],[2280],{"type":50,"value":1084},{"type":50,"value":2282},"; the inspect \u002F gate step is ",{"type":44,"tag":135,"props":2284,"children":2286},{"className":2285},[],[2287],{"type":50,"value":501},{"type":50,"value":128},{"type":44,"tag":57,"props":2290,"children":2291},{},[2292,2294,2300,2302,2308],{"type":50,"value":2293},"For a human-readable ordered preview of the migration path before applying, use ",{"type":44,"tag":135,"props":2295,"children":2297},{"className":2296},[],[2298],{"type":50,"value":2299},"migrate --show --db $URL",{"type":50,"value":2301},". For applied history after a deploy, use ",{"type":44,"tag":135,"props":2303,"children":2305},{"className":2304},[],[2306],{"type":50,"value":2307},"migration log --db $URL",{"type":50,"value":2309}," (flat chronological table).",{"type":44,"tag":1466,"props":2311,"children":2315},{"className":2312,"code":2313,"language":2314,"meta":1471,"style":1471},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","- name: Verify staging is reachable\n  run: |\n    pnpm prisma-next migration status \\\n      --to staging --db \"$STAGING_DATABASE_URL\" --json > status.json\n    node -e '\n      const s = JSON.parse(require(\"fs\").readFileSync(\"status.json\", \"utf8\"));\n      const warns = (s.diagnostics ?? []).filter(d => d.severity === \"warn\");\n      if (warns.length) {\n        console.error(\"Blocking diagnostics:\", warns);\n        process.exit(1);\n      }\n    '\n- name: Apply\n  run: pnpm prisma-next migrate --to staging --db \"$STAGING_DATABASE_URL\"\n","yaml",[2316],{"type":44,"tag":135,"props":2317,"children":2318},{"__ignoreMap":1471},[2319,2343,2361,2369,2377,2385,2394,2403,2412,2421,2430,2439,2448,2469],{"type":44,"tag":1477,"props":2320,"children":2321},{"class":1479,"line":1480},[2322,2327,2333,2338],{"type":44,"tag":1477,"props":2323,"children":2324},{"style":1521},[2325],{"type":50,"value":2326},"-",{"type":44,"tag":1477,"props":2328,"children":2330},{"style":2329},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[2331],{"type":50,"value":2332}," name",{"type":44,"tag":1477,"props":2334,"children":2335},{"style":1521},[2336],{"type":50,"value":2337},":",{"type":44,"tag":1477,"props":2339,"children":2340},{"style":1490},[2341],{"type":50,"value":2342}," Verify staging is reachable\n",{"type":44,"tag":1477,"props":2344,"children":2345},{"class":1479,"line":1927},[2346,2351,2355],{"type":44,"tag":1477,"props":2347,"children":2348},{"style":2329},[2349],{"type":50,"value":2350},"  run",{"type":44,"tag":1477,"props":2352,"children":2353},{"style":1521},[2354],{"type":50,"value":2337},{"type":44,"tag":1477,"props":2356,"children":2358},{"style":2357},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[2359],{"type":50,"value":2360}," |\n",{"type":44,"tag":1477,"props":2362,"children":2363},{"class":1479,"line":1948},[2364],{"type":44,"tag":1477,"props":2365,"children":2366},{"style":1490},[2367],{"type":50,"value":2368},"    pnpm prisma-next migration status \\\n",{"type":44,"tag":1477,"props":2370,"children":2371},{"class":1479,"line":1958},[2372],{"type":44,"tag":1477,"props":2373,"children":2374},{"style":1490},[2375],{"type":50,"value":2376},"      --to staging --db \"$STAGING_DATABASE_URL\" --json > status.json\n",{"type":44,"tag":1477,"props":2378,"children":2379},{"class":1479,"line":1994},[2380],{"type":44,"tag":1477,"props":2381,"children":2382},{"style":1490},[2383],{"type":50,"value":2384},"    node -e '\n",{"type":44,"tag":1477,"props":2386,"children":2388},{"class":1479,"line":2387},6,[2389],{"type":44,"tag":1477,"props":2390,"children":2391},{"style":1490},[2392],{"type":50,"value":2393},"      const s = JSON.parse(require(\"fs\").readFileSync(\"status.json\", \"utf8\"));\n",{"type":44,"tag":1477,"props":2395,"children":2397},{"class":1479,"line":2396},7,[2398],{"type":44,"tag":1477,"props":2399,"children":2400},{"style":1490},[2401],{"type":50,"value":2402},"      const warns = (s.diagnostics ?? []).filter(d => d.severity === \"warn\");\n",{"type":44,"tag":1477,"props":2404,"children":2406},{"class":1479,"line":2405},8,[2407],{"type":44,"tag":1477,"props":2408,"children":2409},{"style":1490},[2410],{"type":50,"value":2411},"      if (warns.length) {\n",{"type":44,"tag":1477,"props":2413,"children":2415},{"class":1479,"line":2414},9,[2416],{"type":44,"tag":1477,"props":2417,"children":2418},{"style":1490},[2419],{"type":50,"value":2420},"        console.error(\"Blocking diagnostics:\", warns);\n",{"type":44,"tag":1477,"props":2422,"children":2424},{"class":1479,"line":2423},10,[2425],{"type":44,"tag":1477,"props":2426,"children":2427},{"style":1490},[2428],{"type":50,"value":2429},"        process.exit(1);\n",{"type":44,"tag":1477,"props":2431,"children":2433},{"class":1479,"line":2432},11,[2434],{"type":44,"tag":1477,"props":2435,"children":2436},{"style":1490},[2437],{"type":50,"value":2438},"      }\n",{"type":44,"tag":1477,"props":2440,"children":2442},{"class":1479,"line":2441},12,[2443],{"type":44,"tag":1477,"props":2444,"children":2445},{"style":1490},[2446],{"type":50,"value":2447},"    '\n",{"type":44,"tag":1477,"props":2449,"children":2451},{"class":1479,"line":2450},13,[2452,2456,2460,2464],{"type":44,"tag":1477,"props":2453,"children":2454},{"style":1521},[2455],{"type":50,"value":2326},{"type":44,"tag":1477,"props":2457,"children":2458},{"style":2329},[2459],{"type":50,"value":2332},{"type":44,"tag":1477,"props":2461,"children":2462},{"style":1521},[2463],{"type":50,"value":2337},{"type":44,"tag":1477,"props":2465,"children":2466},{"style":1490},[2467],{"type":50,"value":2468}," Apply\n",{"type":44,"tag":1477,"props":2470,"children":2472},{"class":1479,"line":2471},14,[2473,2477,2481],{"type":44,"tag":1477,"props":2474,"children":2475},{"style":2329},[2476],{"type":50,"value":2350},{"type":44,"tag":1477,"props":2478,"children":2479},{"style":1521},[2480],{"type":50,"value":2337},{"type":44,"tag":1477,"props":2482,"children":2483},{"style":1490},[2484],{"type":50,"value":2485}," pnpm prisma-next migrate --to staging --db \"$STAGING_DATABASE_URL\"\n",{"type":44,"tag":57,"props":2487,"children":2488},{},[2489,2494,2496,2501,2502,2507,2508,2513,2514,2519,2521,2527,2529,2535,2537,2543,2545,2550],{"type":44,"tag":135,"props":2490,"children":2492},{"className":2491},[],[2493],{"type":50,"value":501},{"type":50,"value":2495}," exits non-zero only on hard errors (unreadable migrations directory, unsatisfiable invariants, unreconstructable history). Diagnostics like ",{"type":44,"tag":135,"props":2497,"children":2499},{"className":2498},[],[2500],{"type":50,"value":783},{"type":50,"value":371},{"type":44,"tag":135,"props":2503,"children":2505},{"className":2504},[],[2506],{"type":50,"value":872},{"type":50,"value":371},{"type":44,"tag":135,"props":2509,"children":2511},{"className":2510},[],[2512],{"type":50,"value":913},{"type":50,"value":605},{"type":44,"tag":135,"props":2515,"children":2517},{"className":2516},[],[2518],{"type":50,"value":751},{"type":50,"value":2520}," are reported on the result envelope with ",{"type":44,"tag":135,"props":2522,"children":2524},{"className":2523},[],[2525],{"type":50,"value":2526},"severity: 'warn'",{"type":50,"value":2528}," but the process exits ",{"type":44,"tag":135,"props":2530,"children":2532},{"className":2531},[],[2533],{"type":50,"value":2534},"0",{"type":50,"value":2536}," — the agent (or a CI gate) must inspect ",{"type":44,"tag":135,"props":2538,"children":2540},{"className":2539},[],[2541],{"type":50,"value":2542},"diagnostics[]",{"type":50,"value":2544}," and fail the build itself. Use ",{"type":44,"tag":135,"props":2546,"children":2548},{"className":2547},[],[2549],{"type":50,"value":1396},{"type":50,"value":2551}," so the gate parses a structured shape rather than the human summary.",{"type":44,"tag":57,"props":2553,"children":2554},{},[2555,2560,2562,2567,2569,2574,2576,2581,2583,2588,2590,2595],{"type":44,"tag":135,"props":2556,"children":2558},{"className":2557},[],[2559],{"type":50,"value":1084},{"type":50,"value":2561}," is interactive-free and has no destructive-op confirmation prompt — the safety rails that prompt for destructive changes live on ",{"type":44,"tag":135,"props":2563,"children":2565},{"className":2564},[],[2566],{"type":50,"value":811},{"type":50,"value":2568}," (see the ",{"type":44,"tag":135,"props":2570,"children":2572},{"className":2571},[],[2573],{"type":50,"value":200},{"type":50,"value":2575}," skill). Whatever the planner put in the migration graph is what ",{"type":44,"tag":135,"props":2577,"children":2579},{"className":2578},[],[2580],{"type":50,"value":1084},{"type":50,"value":2582}," runs; review happens at ",{"type":44,"tag":135,"props":2584,"children":2586},{"className":2585},[],[2587],{"type":50,"value":931},{"type":50,"value":2589}," and at ",{"type":44,"tag":135,"props":2591,"children":2593},{"className":2592},[],[2594],{"type":50,"value":501},{"type":50,"value":2596}," time, before the apply step.",{"type":44,"tag":99,"props":2598,"children":2600},{"id":2599},"common-pitfalls",[2601],{"type":50,"value":2602},"Common Pitfalls",{"type":44,"tag":1542,"props":2604,"children":2605},{},[2606,2642,2671,2701,2729],{"type":44,"tag":110,"props":2607,"children":2608},{},[2609,2628,2630,2635,2636,2640],{"type":44,"tag":61,"props":2610,"children":2611},{},[2612,2614,2619,2621,2626],{"type":50,"value":2613},"Reading ",{"type":44,"tag":135,"props":2615,"children":2617},{"className":2616},[],[2618],{"type":50,"value":501},{"type":50,"value":2620}," without ",{"type":44,"tag":135,"props":2622,"children":2624},{"className":2623},[],[2625],{"type":50,"value":401},{"type":50,"value":2627}," for a deploy question.",{"type":50,"value":2629}," That asks ",{"type":44,"tag":72,"props":2631,"children":2632},{},[2633],{"type":50,"value":2634},"\"can this branch's contract reach the head?\"",{"type":50,"value":1640},{"type":44,"tag":72,"props":2637,"children":2638},{},[2639],{"type":50,"value":1620},{"type":50,"value":2641},". Always pass the ref when the question is about a specific environment.",{"type":44,"tag":110,"props":2643,"children":2644},{},[2645,2661,2663,2669],{"type":44,"tag":61,"props":2646,"children":2647},{},[2648,2649,2654,2655,2660],{"type":50,"value":2613},{"type":44,"tag":135,"props":2650,"children":2652},{"className":2651},[],[2653],{"type":50,"value":501},{"type":50,"value":2620},{"type":44,"tag":135,"props":2656,"children":2658},{"className":2657},[],[2659],{"type":50,"value":434},{"type":50,"value":2627},{"type":50,"value":2662}," Without a live DB, you have no origin. The output lists what's on disk; it can't say what's applied on the environment. Pass ",{"type":44,"tag":135,"props":2664,"children":2666},{"className":2665},[],[2667],{"type":50,"value":2668},"--db $URL",{"type":50,"value":2670}," for any high-stakes question.",{"type":44,"tag":110,"props":2672,"children":2673},{},[2674,2679,2681,2686,2688,2693,2694,2699],{"type":44,"tag":61,"props":2675,"children":2676},{},[2677],{"type":50,"value":2678},"Confusing the ref with a DB connection.",{"type":50,"value":2680}," ",{"type":44,"tag":135,"props":2682,"children":2684},{"className":2683},[],[2685],{"type":50,"value":420},{"type":50,"value":2687}," selects the destination hash, not the database. Pass both ",{"type":44,"tag":135,"props":2689,"children":2691},{"className":2690},[],[2692],{"type":50,"value":401},{"type":50,"value":1031},{"type":44,"tag":135,"props":2695,"children":2697},{"className":2696},[],[2698],{"type":50,"value":434},{"type":50,"value":2700}," explicitly.",{"type":44,"tag":110,"props":2702,"children":2703},{},[2704,2709,2711,2715,2717],{"type":44,"tag":61,"props":2705,"children":2706},{},[2707],{"type":50,"value":2708},"Treating diamond convergence as a special procedure.",{"type":50,"value":2710}," It's not. It's the normal ",{"type":44,"tag":72,"props":2712,"children":2713},{},[2714],{"type":50,"value":1826},{"type":50,"value":2716}," loop applied to the post-rebase state. The only extra step is ",{"type":44,"tag":72,"props":2718,"children":2719},{},[2720,2722,2727],{"type":50,"value":2721},"\"port any data-transform logic from your old ",{"type":44,"tag":135,"props":2723,"children":2725},{"className":2724},[],[2726],{"type":50,"value":1851},{"type":50,"value":2728}," over.\"",{"type":44,"tag":110,"props":2730,"children":2731},{},[2732,2744],{"type":44,"tag":61,"props":2733,"children":2734},{},[2735,2737,2742],{"type":50,"value":2736},"Running ",{"type":44,"tag":135,"props":2738,"children":2740},{"className":2739},[],[2741],{"type":50,"value":1077},{"type":50,"value":2743}," to silence a CI mismatch without understanding the cause.",{"type":50,"value":2745}," That can mask out-of-band changes or rollback drift. Investigate first.",{"type":44,"tag":99,"props":2747,"children":2749},{"id":2748},"what-prisma-next-doesnt-do-yet",[2750],{"type":50,"value":2751},"What Prisma Next doesn't do yet",{"type":44,"tag":106,"props":2753,"children":2754},{},[2755,2773],{"type":44,"tag":110,"props":2756,"children":2757},{},[2758,2763,2765,2771],{"type":44,"tag":61,"props":2759,"children":2760},{},[2761],{"type":50,"value":2762},"Per-environment migration ordering beyond the default chain.",{"type":50,"value":2764}," If you need staging to skip a migration that production requires (or vice versa), the supported path is to author the per-env divergence as separate migrations and gate them in your deploy script. If you want first-class per-env routing, file a feature request via the ",{"type":44,"tag":135,"props":2766,"children":2768},{"className":2767},[],[2769],{"type":50,"value":2770},"prisma-next-feedback",{"type":50,"value":2772}," skill.",{"type":44,"tag":110,"props":2774,"children":2775},{},[2776,2781,2783,2788,2790,2796,2798,2803,2805,2811,2813,2818],{"type":44,"tag":61,"props":2777,"children":2778},{},[2779],{"type":50,"value":2780},"A built-in side-by-side \"branch diff\" view.",{"type":50,"value":2782}," There is a full-graph render (",{"type":44,"tag":135,"props":2784,"children":2786},{"className":2785},[],[2787],{"type":50,"value":1037},{"type":50,"value":2789},") that shows branches, but no ",{"type":44,"tag":135,"props":2791,"children":2793},{"className":2792},[],[2794],{"type":50,"value":2795},"git diff",{"type":50,"value":2797},"-style comparison between two branches' migration sets. Workaround: run ",{"type":44,"tag":135,"props":2799,"children":2801},{"className":2800},[],[2802],{"type":50,"value":501},{"type":50,"value":2804}," on each branch and ",{"type":44,"tag":135,"props":2806,"children":2808},{"className":2807},[],[2809],{"type":50,"value":2810},"diff",{"type":50,"value":2812}," the output. If you want a built-in branch-comparison view, file a feature request via the ",{"type":44,"tag":135,"props":2814,"children":2816},{"className":2815},[],[2817],{"type":50,"value":2770},{"type":50,"value":2772},{"type":44,"tag":99,"props":2820,"children":2822},{"id":2821},"reference-files",[2823],{"type":50,"value":2824},"Reference Files",{"type":44,"tag":57,"props":2826,"children":2827},{},[2828,2830,2836,2837,2843,2844,2850,2852,2858],{"type":50,"value":2829},"This skill is intentionally body-only; the underlying CLI reference (",{"type":44,"tag":135,"props":2831,"children":2833},{"className":2832},[],[2834],{"type":50,"value":2835},"prisma-next migration status --help",{"type":50,"value":371},{"type":44,"tag":135,"props":2838,"children":2840},{"className":2839},[],[2841],{"type":50,"value":2842},"migrate --help",{"type":50,"value":371},{"type":44,"tag":135,"props":2845,"children":2847},{"className":2846},[],[2848],{"type":50,"value":2849},"ref --help",{"type":50,"value":2851},") is the authoritative surface for flag-level detail. When in doubt, run ",{"type":44,"tag":135,"props":2853,"children":2855},{"className":2854},[],[2856],{"type":50,"value":2857},"--help",{"type":50,"value":2859}," and read the actual command's description rather than guessing from this skill.",{"type":44,"tag":99,"props":2861,"children":2863},{"id":2862},"checklist",[2864],{"type":50,"value":2865},"Checklist",{"type":44,"tag":106,"props":2867,"children":2870},{"className":2868},[2869],"contains-task-list",[2871,2896,2912,2939,2955,2978,3001,3017,3061,3091,3115],{"type":44,"tag":110,"props":2872,"children":2875},{"className":2873},[2874],"task-list-item",[2876,2882,2884,2888,2890,2894],{"type":44,"tag":2877,"props":2878,"children":2881},"input",{"disabled":2879,"type":2880},true,"checkbox",[],{"type":50,"value":2883}," Named both the ",{"type":44,"tag":61,"props":2885,"children":2886},{},[2887],{"type":50,"value":252},{"type":50,"value":2889}," (live DB marker) and the ",{"type":44,"tag":61,"props":2891,"children":2892},{},[2893],{"type":50,"value":259},{"type":50,"value":2895}," (ref or contract head) for the question the user asked.",{"type":44,"tag":110,"props":2897,"children":2899},{"className":2898},[2874],[2900,2903,2905,2910],{"type":44,"tag":2877,"props":2901,"children":2902},{"disabled":2879,"type":2880},[],{"type":50,"value":2904}," Passed ",{"type":44,"tag":135,"props":2906,"children":2908},{"className":2907},[],[2909],{"type":50,"value":2668},{"type":50,"value":2911}," whenever the question involves a specific environment.",{"type":44,"tag":110,"props":2913,"children":2915},{"className":2914},[2874],[2916,2919,2920,2925,2927,2931,2933,2937],{"type":44,"tag":2877,"props":2917,"children":2918},{"disabled":2879,"type":2880},[],{"type":50,"value":2904},{"type":44,"tag":135,"props":2921,"children":2923},{"className":2922},[],[2924],{"type":50,"value":354},{"type":50,"value":2926}," whenever the question is about deploying ",{"type":44,"tag":72,"props":2928,"children":2929},{},[2930],{"type":50,"value":476},{"type":50,"value":2932}," a named environment, not just ",{"type":44,"tag":72,"props":2934,"children":2935},{},[2936],{"type":50,"value":468},{"type":50,"value":2938}," the current branch's head.",{"type":44,"tag":110,"props":2940,"children":2942},{"className":2941},[2874],[2943,2946,2948,2953],{"type":44,"tag":2877,"props":2944,"children":2945},{"disabled":2879,"type":2880},[],{"type":50,"value":2947}," Read the ",{"type":44,"tag":135,"props":2949,"children":2951},{"className":2950},[],[2952],{"type":50,"value":501},{"type":50,"value":2954}," header (it names config, ref, database) and the summary line (it names the origin\u002Fdestination distance) before reading the per-edge list.",{"type":44,"tag":110,"props":2956,"children":2958},{"className":2957},[2874],[2959,2962,2964,2969,2971,2976],{"type":44,"tag":2877,"props":2960,"children":2961},{"disabled":2879,"type":2880},[],{"type":50,"value":2963}," For concurrent-migration conflicts: re-applied the ",{"type":44,"tag":72,"props":2965,"children":2966},{},[2967],{"type":50,"value":2968},"core",{"type":50,"value":2970}," workflow (edit → plan → apply) rather than following a memorised \"diamond convergence\" procedure. Ported any data-transform logic from the abandoned ",{"type":44,"tag":135,"props":2972,"children":2974},{"className":2973},[],[2975],{"type":50,"value":1851},{"type":50,"value":2977}," over.",{"type":44,"tag":110,"props":2979,"children":2981},{"className":2980},[2874],[2982,2985,2987,2992,2994,2999],{"type":44,"tag":2877,"props":2983,"children":2984},{"disabled":2879,"type":2880},[],{"type":50,"value":2986}," For a ref-mismatch: investigated ",{"type":44,"tag":72,"props":2988,"children":2989},{},[2990],{"type":50,"value":2991},"which",{"type":50,"value":2993}," piece of state is wrong (DB ahead, DB behind, DB on a divergent branch). Did NOT ",{"type":44,"tag":135,"props":2995,"children":2997},{"className":2996},[],[2998],{"type":50,"value":1077},{"type":50,"value":3000}," to silence the mismatch.",{"type":44,"tag":110,"props":3002,"children":3004},{"className":3003},[2874],[3005,3008,3010,3015],{"type":44,"tag":2877,"props":3006,"children":3007},{"disabled":2879,"type":2880},[],{"type":50,"value":3009}," Surfaced the destructive-op count from ",{"type":44,"tag":135,"props":3011,"children":3013},{"className":3012},[],[3014],{"type":50,"value":501},{"type":50,"value":3016}," (the only operation class that warrants manual review pre-deploy) before the user merges or deploys.",{"type":44,"tag":110,"props":3018,"children":3020},{"className":3019},[2874],[3021,3024,3026,3032,3033,3038,3040,3046,3048,3053,3054,3059],{"type":44,"tag":2877,"props":3022,"children":3023},{"disabled":2879,"type":2880},[],{"type":50,"value":3025}," In CI: parsed ",{"type":44,"tag":135,"props":3027,"children":3029},{"className":3028},[],[3030],{"type":50,"value":3031},"migration status --json",{"type":50,"value":2680},{"type":44,"tag":135,"props":3034,"children":3036},{"className":3035},[],[3037],{"type":50,"value":2542},{"type":50,"value":3039}," and gated on ",{"type":44,"tag":135,"props":3041,"children":3043},{"className":3042},[],[3044],{"type":50,"value":3045},"severity === 'warn'",{"type":50,"value":3047},"; did NOT rely on a ",{"type":44,"tag":135,"props":3049,"children":3051},{"className":3050},[],[3052],{"type":50,"value":2273},{"type":50,"value":2275},{"type":44,"tag":135,"props":3055,"children":3057},{"className":3056},[],[3058],{"type":50,"value":1084},{"type":50,"value":3060}," (no such flag exists).",{"type":44,"tag":110,"props":3062,"children":3064},{"className":3063},[2874],[3065,3068,3070,3075,3077,3082,3084,3089],{"type":44,"tag":2877,"props":3066,"children":3067},{"disabled":2879,"type":2880},[],{"type":50,"value":3069}," Did NOT confuse ",{"type":44,"tag":135,"props":3071,"children":3073},{"className":3072},[],[3074],{"type":50,"value":401},{"type":50,"value":3076}," with database selection (",{"type":44,"tag":135,"props":3078,"children":3080},{"className":3079},[],[3081],{"type":50,"value":401},{"type":50,"value":3083}," picks the destination hash; ",{"type":44,"tag":135,"props":3085,"children":3087},{"className":3086},[],[3088],{"type":50,"value":434},{"type":50,"value":3090}," picks the database).",{"type":44,"tag":110,"props":3092,"children":3094},{"className":3093},[2874],[3095,3098,3100,3106,3108,3113],{"type":44,"tag":2877,"props":3096,"children":3097},{"disabled":2879,"type":2880},[],{"type":50,"value":3099}," Did NOT use ",{"type":44,"tag":135,"props":3101,"children":3103},{"className":3102},[],[3104],{"type":50,"value":3105},"--ref",{"type":50,"value":3107}," (removed; use ",{"type":44,"tag":135,"props":3109,"children":3111},{"className":3110},[],[3112],{"type":50,"value":401},{"type":50,"value":3114},").",{"type":44,"tag":110,"props":3116,"children":3118},{"className":3117},[2874],[3119,3122,3124,3130],{"type":44,"tag":2877,"props":3120,"children":3121},{"disabled":2879,"type":2880},[],{"type":50,"value":3123}," Did NOT confabulate a \"branch diff\" CLI subcommand, a ",{"type":44,"tag":135,"props":3125,"children":3127},{"className":3126},[],[3128],{"type":50,"value":3129},"migration revalidate",{"type":50,"value":3131}," step, or any other API the skill above doesn't reference.",{"type":44,"tag":3133,"props":3134,"children":3135},"style",{},[3136],{"type":50,"value":3137},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":3139,"total":3297},[3140,3155,3170,3182,3194,3207,3215,3225,3241,3254,3265,3281],{"slug":3141,"name":3141,"fn":3142,"description":3143,"org":3144,"tags":3145,"stars":26,"repoUrl":27,"updatedAt":3154},"prisma-next","guide Prisma Next project setup and usage","Route a vague Prisma Next prompt to the right specific skill. Use for \"help me with Prisma Next\", \"what is Prisma Next\", \"explain Prisma Next\", \"I'm new to PN\", \"where do I start\", \"what can I do with Prisma Next\", \"what can I do next with Prisma\", \"just ran createprisma\", \"tour of Prisma Next\", \"Prisma Next overview\", and comparison questions like \"Prisma Next vs Prisma 7\", \"PN vs Drizzle\", \"PN vs Kysely\", \"PN vs TypeORM\". Do NOT use when the prompt clearly matches a workflow skill — adoption \u002F quickstart \u002F first-touch orientation \u002F brownfield introspection, schema \u002F contract editing, migration authoring (db update \u002F migration plan \u002F migrate), migration review on deploy \u002F concurrent migrations, queries \u002F db.orm \u002F db.sql \u002F TypedSQL, Supabase \u002F RLS \u002F role binding, runtime \u002F db.ts \u002F middleware wiring, build \u002F Vite plugin \u002F Next.js plugin, debug \u002F structured error envelopes \u002F PN-* error codes, or feedback \u002F bug report \u002F feature request — load that sibling skill directly.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3146,3147,3150,3151],{"name":17,"slug":18,"type":15},{"name":3148,"slug":3149,"type":15},"Next.js","next-js",{"name":9,"slug":8,"type":15},{"name":3152,"slug":3153,"type":15},"TypeScript","typescript","2026-07-17T05:32:04.322957",{"slug":3156,"name":3156,"fn":3157,"description":3158,"org":3159,"tags":3160,"stars":26,"repoUrl":27,"updatedAt":3169},"prisma-next-build","integrate Prisma Next into build systems","Wire Prisma Next into the project's build system with the right build-tool plugin — Vite today via @prisma-next\u002Fvite-plugin-contract-emit (Vite 7 \u002F 8); Next.js \u002F Webpack \u002F esbuild \u002F Rollup \u002F Turbopack are named as gaps rather than fabricated. Always offers the Vite plugin proactively when the project is using Vite. Use for vite plugin, vite-plugin, vite.config.ts, prismaVitePlugin, contract emit on save, HMR, hot reload contract, dev server, Next.js plugin, next plugin, withPrismaNext, webpack plugin, esbuild plugin, rollup plugin, build integration, dev server plugin, vite 7, vite 8.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3161,3164,3165,3166],{"name":3162,"slug":3163,"type":15},"Deployment","deployment",{"name":3148,"slug":3149,"type":15},{"name":9,"slug":8,"type":15},{"name":3167,"slug":3168,"type":15},"Vite","vite","2026-07-02T07:31:36.108254",{"slug":232,"name":232,"fn":3171,"description":3172,"org":3173,"tags":3174,"stars":26,"repoUrl":27,"updatedAt":3181},"edit Prisma Next data contracts and models","Edit the Prisma Next data contract — add models, fields, relations, indexes, enums, value objects (composite types), type aliases, namespaces (Postgres schemas), cross-contract foreign keys (cross-space FK), polymorphic types (`@@discriminator` \u002F `@@base`), use extension namespaces (`pgvector.Vector(...)`, `cipherstash.EncryptedString(...)`), wire `prisma-next.config.ts` with `defineConfig` from the `@prisma-next\u002F\u003Ctarget>\u002Fconfig` façade, and run `prisma-next contract emit`. Use for schema, models, fields, attributes, soft delete, paranoid, scopes, validations, callbacks, prisma schema, PSL, contract.prisma, contract.ts, contract.json, contract.d.ts, `@prisma-next\u002Fpostgres\u002Fconfig`, `@prisma-next\u002Fpostgres\u002Fcontract-builder`, `@prisma-next\u002Fpostgres\u002Fcontrol`, `@prisma-next\u002Fmongo\u002Fconfig`, `@prisma-next\u002Fmongo\u002Fcontract-builder`, `extensions:`, pgvector, cipherstash, postgis, paradedb, supabase, `@prisma-next\u002Fextension-supabase`, `@@control`, control policy, managed, tolerated, external, observed.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3175,3178,3179,3180],{"name":3176,"slug":3177,"type":15},"Data Modeling","data-modeling",{"name":17,"slug":18,"type":15},{"name":9,"slug":8,"type":15},{"name":3152,"slug":3153,"type":15},"2026-07-30T05:30:10.426962",{"slug":219,"name":219,"fn":3183,"description":3184,"org":3185,"tags":3186,"stars":26,"repoUrl":27,"updatedAt":3193},"debug and recover from Prisma Next errors","Read a Prisma Next structured error envelope and route to the right recovery — code, domain, severity, why, fix, meta. Use for error, exception, my emit failed, my query won't typecheck, my query crashed, my migration won't apply, MIGRATION.HASH_MISMATCH, BUDGET.ROWS_EXCEEDED, BUDGET.TIME_EXCEEDED, RUNTIME.ABORTED, PLAN.HASH_MISMATCH, CONTRACT.MARKER_MISSING, PN-RUN-3001, PN-RUN-3002, PN-RUN-3030, PN-MIG-2001, PN-CLI-4011, PN-SCHEMA-0001, drift, capability missing, planner conflict, prisma studio, EXPLAIN, query log, db.end, db.close, script won't exit, hangs, close connection, pool.end, client is closed.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3187,3188,3191,3192],{"name":17,"slug":18,"type":15},{"name":3189,"slug":3190,"type":15},"Debugging","debugging",{"name":3148,"slug":3149,"type":15},{"name":9,"slug":8,"type":15},"2026-07-24T05:37:10.436314",{"slug":2770,"name":2770,"fn":3195,"description":3196,"org":3197,"tags":3198,"stars":26,"repoUrl":27,"updatedAt":3206},"report Prisma Next issues and feedback","Hand a Prisma Next question or report off to the team — file a GitHub issue (bug or feature request), or route Q&A \u002F design discussion \u002F direct-team-contact to the Prisma Discord at pris.ly\u002Fdiscord. Use for bug, bug report, file an issue, report a bug, feature request, missing feature, this should be a feature, file this, this is a bug, this is broken, surprising behaviour, this doesn't work, file feedback, send feedback, capability gap, file via prisma-next-feedback, ask the team, talk to the team, talk to the Prisma team, talk to Prisma, Discord, Prisma Discord, Q&A, design feedback, is this the intended way, how should I do X, extension author question, extension author needs help.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3199,3202,3205],{"name":3200,"slug":3201,"type":15},"Documentation","documentation",{"name":3203,"slug":3204,"type":15},"GitHub","github",{"name":9,"slug":8,"type":15},"2026-07-02T07:31:34.870809",{"slug":4,"name":4,"fn":5,"description":6,"org":3208,"tags":3209,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3210,3211,3212,3213,3214],{"name":24,"slug":25,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":9,"slug":8,"type":15},{"slug":200,"name":200,"fn":3216,"description":3217,"org":3218,"tags":3219,"stars":26,"repoUrl":27,"updatedAt":3224},"author and manage Prisma Next migrations","Author Prisma Next migrations — choose db update vs migration plan, edit the framework-rendered migration.ts (replace placeholder sentinels with dataTransform closures), recover from MIGRATION.HASH_MISMATCH or PN-MIG-2001 unfilled placeholder. Use for prisma migrate dev, prisma migrate deploy, prisma db push, db update, db update --dry-run, migration plan, migrate, migration new, migration show, db verify, db sign, data migration, this.dataTransform, dataTransform, placeholder, generated migration.ts, edit migration.ts, MIGRATION.HASH_MISMATCH, schema drift.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3220,3221,3222,3223],{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":9,"slug":8,"type":15},{"name":3152,"slug":3153,"type":15},"2026-07-24T05:37:13.469138",{"slug":3226,"name":3226,"fn":3227,"description":3228,"org":3229,"tags":3230,"stars":26,"repoUrl":27,"updatedAt":3240},"prisma-next-queries","write Prisma Next queries for database operations","Write Prisma Next queries for Postgres, SQLite, or Mongo — pick a lane (Postgres\u002FSQLite `db.orm.\u003CModel>` + `db.sql.\u003Ctable>`; Mongo `db.orm.\u003Croot>` + `db.query.from(...)` pipeline builder), filter \u002F project \u002F sort \u002F paginate, eager-load with `.include(...)`, Postgres\u002FSQLite `db.transaction(...)`, Postgres\u002FSQLite ORM `.aggregate(...)`, Mongo aggregations via query builder, namespace-aware accessors (`db.orm.\u003Cns>.\u003CModel>`, `db.sql.\u003Cns>.\u003Ctable>`). Triggers: query, where, match, select, project, orderBy, take, skip, include, lookup, first, all, count, aggregate, group, create, update, delete, upsert, returning, transaction, db.close, script teardown, variant, polymorphism, drizzle-style, kysely-style. Notes: `.all()` is a Thenable (just `await` it), iterators are single-use (`RUNTIME.ITERATOR_CONSUMED`), Postgres `count` is `number` while sum\u002Favg\u002Fmin\u002Fmax are `number | null`, ranges use chained `.where()` or `and(...)` (no `.between(...)`).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3231,3232,3233,3236,3237],{"name":17,"slug":18,"type":15},{"name":3148,"slug":3149,"type":15},{"name":3234,"slug":3235,"type":15},"PostgreSQL","postgresql",{"name":9,"slug":8,"type":15},{"name":3238,"slug":3239,"type":15},"SQL","sql","2026-07-17T05:32:03.35373",{"slug":3242,"name":3242,"fn":3243,"description":3244,"org":3245,"tags":3246,"stars":26,"repoUrl":27,"updatedAt":3253},"prisma-next-quickstart","adopt Prisma Next in projects","Adopt Prisma Next into a new project, onto an existing database, or as the first move after a bootstrap tool dropped you into a scaffold. Use for \"what can I do with Prisma Next\", \"what can I do next with Prisma\", \"where do I start\", \"what should I do first\", \"just ran createprisma\", \"createprisma\", \"npx createprisma\", \"npx create-prisma\", \"first steps\", \"first query\", \"I have a scaffolded Prisma Next project what now\"; for `pnpm dlx prisma-next init` greenfield setup; and for `prisma-next contract infer` + `db sign` against an existing database. Also covers the connect-write-read first-arc orientation, the day-to-day commands (`contract emit`, `db init`, `db update`, `migration plan`, `migrate`, `db schema`, `db verify`), and routing to `prisma-next-contract` \u002F `prisma-next-queries` \u002F `prisma-next-runtime` for the next move. Flags: --target, --authoring, --schema-path, --probe-db, --output.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3247,3248,3251,3252],{"name":17,"slug":18,"type":15},{"name":3249,"slug":3250,"type":15},"ORM","orm",{"name":9,"slug":8,"type":15},{"name":3152,"slug":3153,"type":15},"2026-07-24T05:37:12.462072",{"slug":3255,"name":3255,"fn":3256,"description":3257,"org":3258,"tags":3259,"stars":26,"repoUrl":27,"updatedAt":3264},"prisma-next-runtime","configure Prisma Next runtime and database connections","Wire the Prisma Next runtime — `db.ts` setup using `postgres\u003CContract>(...)` from `@prisma-next\u002Fpostgres\u002Fruntime`, `sqlite\u003CContract>(...)` from `@prisma-next\u002Fsqlite\u002Fruntime`, or `mongo\u003CContract>(...)` from `@prisma-next\u002Fmongo\u002Fruntime`; middleware composition (telemetry from `@prisma-next\u002Fmiddleware-telemetry`; lints and budgets), `DATABASE_URL` config, per-environment branching, switching between Postgres, SQLite, and Mongo façades. Use for db.ts, postgres(), sqlite(), mongo(), middleware, telemetry, lints, budgets, DATABASE_URL, .env, connection pool, poolOptions, dev vs prod config, transactions, db.transaction, read replicas, multi-database, script won't exit, hangs, close connection, db.end, db.close, pool.end, [Symbol.asyncDispose], await using.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3260,3261,3262,3263],{"name":17,"slug":18,"type":15},{"name":3148,"slug":3149,"type":15},{"name":3234,"slug":3235,"type":15},{"name":9,"slug":8,"type":15},"2026-07-17T05:32:05.347316",{"slug":3266,"name":3266,"fn":3267,"description":3268,"org":3269,"tags":3270,"stars":26,"repoUrl":27,"updatedAt":3280},"prisma-next-supabase","integrate Prisma with Supabase","Use Prisma Next with a Supabase project via `@prisma-next\u002Fextension-supabase` — wire `extensions: [supabasePack]`, declare cross-space FKs to `supabase:auth.AuthUser`, author RLS policies (`policy_select` \u002F `policy_update` \u002F `@@rls`, `auth.uid()` predicates), build `db.ts` with the `supabase()` factory, bind roles per request (`asUser(jwt)` \u002F `asAnon()` \u002F `asServiceRole()`), query `auth.*` \u002F `storage.*` via the `db.asServiceRole().supabase` admin root, and validate JWTs (`jwksUrl` for current projects \u002F `jwtSecret` for legacy HS256). Use for supabase, RLS, row level security, policy, role binding, anon, authenticated, service_role, auth.users, auth.uid(), JWT, JWKS, SUPABASE_JWKS_URL, SUPABASE_JWT_SECRET, SUPABASE.JWT_INVALID, SUPABASE.CONFIG_INVALID, RoleBoundDb, session pooler, supabase:auth.AuthUser, @prisma-next\u002Fextension-supabase.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3271,3274,3275,3276,3277],{"name":3272,"slug":3273,"type":15},"Auth","auth",{"name":3249,"slug":3250,"type":15},{"name":3234,"slug":3235,"type":15},{"name":9,"slug":8,"type":15},{"name":3278,"slug":3279,"type":15},"Supabase","supabase","2026-07-30T05:30:11.065251",{"slug":3282,"name":3282,"fn":3283,"description":3284,"org":3285,"tags":3286,"stars":3294,"repoUrl":3295,"updatedAt":3296},"prisma-cli","run Prisma CLI commands","Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, studio, validate, format, debug, and mcp. Use for ORM\u002Fdatabase CLI workflows, not Prisma Compute app deployment. For Prisma Compute, `@prisma\u002Fcli app deploy`, `compute:deploy`, `create-prisma --deploy`, apps, deployments, logs, or domains, use the `prisma-compute` skill instead. Triggers on \"prisma init\", \"prisma generate\", \"prisma migrate\", \"prisma db\", \"prisma studio\", \"prisma mcp\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3287,3290,3291,3292,3293],{"name":3288,"slug":3289,"type":15},"CLI","cli",{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":3249,"slug":3250,"type":15},{"name":9,"slug":8,"type":15},44,"https:\u002F\u002Fgithub.com\u002Fprisma\u002Fskills","2026-04-06T18:48:29.140467",21,{"items":3299,"total":2432},[3300,3307,3314,3321,3328,3334,3342],{"slug":3141,"name":3141,"fn":3142,"description":3143,"org":3301,"tags":3302,"stars":26,"repoUrl":27,"updatedAt":3154},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3303,3304,3305,3306],{"name":17,"slug":18,"type":15},{"name":3148,"slug":3149,"type":15},{"name":9,"slug":8,"type":15},{"name":3152,"slug":3153,"type":15},{"slug":3156,"name":3156,"fn":3157,"description":3158,"org":3308,"tags":3309,"stars":26,"repoUrl":27,"updatedAt":3169},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3310,3311,3312,3313],{"name":3162,"slug":3163,"type":15},{"name":3148,"slug":3149,"type":15},{"name":9,"slug":8,"type":15},{"name":3167,"slug":3168,"type":15},{"slug":232,"name":232,"fn":3171,"description":3172,"org":3315,"tags":3316,"stars":26,"repoUrl":27,"updatedAt":3181},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3317,3318,3319,3320],{"name":3176,"slug":3177,"type":15},{"name":17,"slug":18,"type":15},{"name":9,"slug":8,"type":15},{"name":3152,"slug":3153,"type":15},{"slug":219,"name":219,"fn":3183,"description":3184,"org":3322,"tags":3323,"stars":26,"repoUrl":27,"updatedAt":3193},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3324,3325,3326,3327],{"name":17,"slug":18,"type":15},{"name":3189,"slug":3190,"type":15},{"name":3148,"slug":3149,"type":15},{"name":9,"slug":8,"type":15},{"slug":2770,"name":2770,"fn":3195,"description":3196,"org":3329,"tags":3330,"stars":26,"repoUrl":27,"updatedAt":3206},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3331,3332,3333],{"name":3200,"slug":3201,"type":15},{"name":3203,"slug":3204,"type":15},{"name":9,"slug":8,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":3335,"tags":3336,"stars":26,"repoUrl":27,"updatedAt":28},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3337,3338,3339,3340,3341],{"name":24,"slug":25,"type":15},{"name":13,"slug":14,"type":15},{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":9,"slug":8,"type":15},{"slug":200,"name":200,"fn":3216,"description":3217,"org":3343,"tags":3344,"stars":26,"repoUrl":27,"updatedAt":3224},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[3345,3346,3347,3348],{"name":17,"slug":18,"type":15},{"name":20,"slug":21,"type":15},{"name":9,"slug":8,"type":15},{"name":3152,"slug":3153,"type":15}]