Skip to content

fix(cli): bind db update consent to the printed plan with --plan <id> - #1777

Merged
borisno2 merged 2 commits into
mainfrom
fix/issue-1660-db-update-plan-id
Oct 7, 2026
Merged

borisno2 merged 2 commits into
mainfrom
fix/issue-1660-db-update-plan-id

Conversation

@borisno2

@borisno2 borisno2 commented Oct 7, 2026

Copy link
Copy Markdown
Member

Summary

  • A parked destructive plan is printed with a short plan id (hash of its operations) and the remedy pnpm db:update --plan <id>, which runs as written.
  • opensaas db update --plan <id> re-plans as a dry run. It applies only a destructive plan whose id matches, passing Prisma the consent token for the database actually connected (Dev database or the DATABASE_URL database name). Otherwise it prints the new plan and id and changes nothing.
  • A destructive plan with no --plan, or with nothing parked, is refused and printed first. Non-destructive plans apply with plain pnpm db:update.
  • --confirm is removed from opensaas db update. Root/starter/rag CLAUDE.md, READMEs and docs updated.

Test plan

  • Unit test: no id and wrong id refuse without applying; matching id applies with consent
  • Integration tests (tests/staged-reconcile.test.ts) use the printed id
  • pnpm lint, pnpm format
  • Escape-only test against a Postgres not named postgres (not added; needs a live DATABASE_URL)

Closes #1660

🤖 Generated with Claude Code

https://claude.ai/code/session_01F2unpL2YeNYqQ2XBeVkFnm


Generated by Claude Code

@changeset-bot

changeset-bot Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: b98bb70

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 10 packages
Name Type
@opensaas/stack-cli Minor
create-opensaas-app Patch
@opensaas/stack-auth Minor
@opensaas/stack-core Minor
@opensaas/stack-rag Minor
@opensaas/stack-storage-s3 Minor
@opensaas/stack-storage-vercel Minor
@opensaas/stack-storage Minor
@opensaas/stack-tiptap Minor
@opensaas/stack-ui Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
stack-docs Ready Ready Preview Oct 7, 2026 11:43am UTC

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T11:42:36.533259Z 6787a65 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

borisno2 commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

Code review: PR #1777 (db update --plan <id>, closes #1660)

Changes requested. The first two items undermine the purpose of the PR, which is binding consent to the printed plan.

Requested changes

  1. planId does not cover the plan's statements (packages/cli/src/dev/staged-reconcile.ts:296). It hashes only each operation's class and label. If the printed plan says "Alter type of X.col" and the SQL later changes (a different target type or USING cast) with the same label, the old id still matches and the new statements run under the old consent. Hash the statements too.
  2. The apply step never re-checks the id (packages/cli/src/commands/dev.ts:524). The id is checked against a dry-run plan. The apply then re-plans with the database-name token as blanket consent. If the database or refs change in between, operations the user never saw can run. Recompute the id from the apply's own plan and abort on a mismatch. The apply should also confirm it plans against the generation that was printed.
  3. --confirm is removed outright and the changeset is a patch (packages/cli/src/commands/db.ts:44). opensaas db update --confirm postgres in scripts or CI now fails with "unknown option". Either keep a deprecation path or mark the changeset as breaking.
  4. consentToken parses the database name from the URL (dev.ts:515). It takes the last path segment. That can be empty or wrong for socket-style URLs (postgres:///?host=...) or when Prisma resolves the name from current_database(). The user then cannot apply, whereas before they could pass the token themselves. Handle the missing-token case, or take the name from the connection.
  5. Docs and README text is stale or inaccurate:
    • docs/content/how-to/installation.md:101: still describes the "token is the database name" right after the --plan <id> command. The same stale text is in docs/content/how-to/migrate.md and packages/cli/CLAUDE.md.
    • examples/rag-openai-chatbot/README.md:549: this block quotes Prisma's own error. It was edited to say "pass --plan ", but Prisma actually prints --confirm postgres. Restore the verbatim output.

Non-blocking

  • Extra planning pass (dev.ts:389): every db update now runs a dry-run plan first, and a non-destructive change is then planned again to apply. Consider reusing the dry-run result, or checking the id only when the first apply refuses.
  • Re-park on mismatch (dev.ts:502): on an id mismatch, parkedPlanId is overwritten with the new id. The only notice is a single reply line. Make the "new id is B" message prominent, and log it in the loop output.
  • Test coverage (dev.test.ts:340): only the happy path is covered. Please add tests for a token-less URL, a plan id that changes between park and apply, and an unneeded --plan on a non-destructive plan.

Generated by Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6787a656d6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +298 to +301
const content = plan.operations.map(
(operation) => `${operation.operationClass}:${operation.label}`,
)
return createHash('sha256').update(JSON.stringify(content)).digest('hex').slice(0, 12)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Hash the SQL that the user reviewed

When an extension or custom migration is changed after the plan is printed while retaining the same operation labels and classes, the old --plan value still passes this check even though describePlan displayed different SQL statements. The loop then supplies Prisma’s --confirm automatically and can execute destructive SQL the user never reviewed. Include plan.statements—or another canonical representation of the complete printed plan—in the digest.

Useful? React with 👍 / 👎.

Comment thread examples/rag-openai-chatbot/README.md Outdated
Comment on lines +547 to +549
"Apply 1 destructive operation(s) to postgres? Data they remove cannot be recovered:
- Alter type of "KnowledgeBase"."contentEmbedding" to vector(3072)" requires explicit
consent, and the session is not interactive. Grant it by passing --confirm postgres.
consent, and the session is not interactive. Grant it by passing --plan <id>.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve Prisma's actual --confirm diagnostic

This fence is presented as output from a non-interactive Prisma db update, but the pinned command’s --help states that non-interactive consent comes from --confirm <database>, and Prisma still emits that flag in this diagnostic. The OpenSaaS wrapper emits its own plan-ID error before invoking the destructive update; it does not rewrite Prisma’s message. Keeping --plan <id> inside the quoted Prisma output therefore gives users an output example they cannot actually encounter.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Core Package Coverage (./packages/core)

Status Category Percentage Covered / Total
🟢 Lines 94.54% (🎯 81%) 3814 / 4034
🟢 Statements 92.84% (🎯 76%) 4337 / 4671
🟢 Functions 96.09% (🎯 78%) 861 / 896
🟢 Branches 88.42% (🎯 71%) 2948 / 3334
File CoverageNo changed files found.
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for UI Package Coverage (./packages/ui)

Status Category Percentage Covered / Total
🔵 Lines 78.7% 244 / 310
🔵 Statements 78.43% 251 / 320
🔵 Functions 69.81% 74 / 106
🔵 Branches 67.51% 160 / 237
File CoverageNo changed files found.
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for CLI Package Coverage (./packages/cli)

Status Category Percentage Covered / Total
🔵 Lines 82.21% 2076 / 2525
🔵 Statements 81.98% 2230 / 2720
🔵 Functions 87.4% 354 / 405
🔵 Branches 75.47% 1114 / 1476
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/cli/src/commands/dev.ts 83.84% 76.66% 75% 86.07% 52, 57, 87-88, 190, 200, 224-225, 227, 228, 235-237, 298-299, 359-362, 391-394, 417-419, 426-429, 442, 460, 485, 514-516, 520, 528, 556
packages/cli/src/dev/control.ts 87.31% 75% 92.3% 90.75% 97, 102, 105, 112-114, 138, 142, 155-156, 173-174, 180-181, 254, 272, 277
packages/cli/src/dev/staged-reconcile.ts 92.78% 86.04% 93.75% 97.53% 71, 74, 79, 138, 140, 278, 292
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Auth Package Coverage (./packages/auth)

Status Category Percentage Covered / Total
🔵 Lines 83.33% 405 / 486
🔵 Statements 82.19% 457 / 556
🔵 Functions 86.2% 100 / 116
🔵 Branches 78.28% 375 / 479
File CoverageNo changed files found.
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Storage Package Coverage (./packages/storage)

Status Category Percentage Covered / Total
🔵 Lines 96.97% 417 / 430
🔵 Statements 96.02% 459 / 478
🔵 Functions 98.36% 120 / 122
🔵 Branches 93.43% 427 / 457
File CoverageNo changed files found.
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for RAG Package Coverage (./packages/rag)

Status Category Percentage Covered / Total
🔵 Lines 88.79% 634 / 714
🔵 Statements 88.19% 695 / 788
🔵 Functions 95.48% 127 / 133
🔵 Branches 85.03% 449 / 528
File CoverageNo changed files found.
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Storage S3 Package Coverage (./packages/storage-s3)

Status Category Percentage Covered / Total
🔵 Lines 100% 47 / 47
🔵 Statements 100% 48 / 48
🔵 Functions 100% 10 / 10
🔵 Branches 96.87% 31 / 32
File CoverageNo changed files found.
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for Storage Vercel Package Coverage (./packages/storage-vercel)

Status Category Percentage Covered / Total
🔵 Lines 100% 74 / 74
🔵 Statements 100% 78 / 78
🔵 Functions 100% 16 / 16
🔵 Branches 96.55% 56 / 58
File CoverageNo changed files found.
Generated in workflow #2991 for commit b98bb70 by the Vitest Coverage Report Action

@borisno2
borisno2 merged commit e27eb08 into main Oct 7, 2026
9 checks passed
@borisno2
borisno2 deleted the fix/issue-1660-db-update-plan-id branch October 7, 2026 20:13

This branch was successfully deployed

1 active deployment
Preview — b98bb701 Deployed Oct 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

db update consent: the parked-change message names a remedy Prisma refuses, and --confirm is not bound to the printed plan

2 participants