Close the getContext no-transaction documentation gap - #1552
Conversation
#1262 fixed the constant-false transaction-opener probe, but left the path that lets a caller rebuild the same silent shape by hand: getContext(config, requireOrmHandle(config, db.orm), session) type-checks, runs, and drops the write's rollback guarantee with no warning. - context.db writes now warn once per (list, operation) via console.warn when the context has neither an enclosing transaction to join nor its own opener, instead of staying silent (packages/core/src/context/write-pipeline.ts) - getContext's `client` parameter and requireOrmHandle's docblocks now say omitting the client costs the write transaction, not only context.unsafe - packages/core/README.md already documents the current getContext(session?) form, not the stale three-argument one — verified, no change needed - Amended the still-unreleased eager-writes-open changeset: corrected the "now says so" claim for a plain write (it now genuinely does, via the new warning) and recorded OrmHandleUnresolvableError's blast-radius change from a per-list lazy error to a build-time refusal for the whole context Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AB3Ru72ye9FoGjBMq4bDAo
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
| Name | Type |
|---|---|
| @opensaas/stack-core | Minor |
| @opensaas/stack-cli | Minor |
| @opensaas/stack-auth | Minor |
| @opensaas/stack-rag | Minor |
| @opensaas/stack-storage | Minor |
| @opensaas/stack-tiptap | Minor |
| @opensaas/stack-ui | Minor |
| @opensaas/stack-storage-s3 | Minor |
| @opensaas/stack-storage-vercel | Minor |
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
The Both files are already on Proposed patch (for whoever owns that renumbering): rename I'll keep watching this PR and re-check once Generated by Claude Code |
Code review (medium-high effort)Reviewed the diff directly against The gate condition is correct
No false positives (warning on a legitimately joined write) or false negatives (missing the truly-no-capability case) found. Docblock accuracy — one confusing sentence
"silently" is immediately undercut by the parenthetical describing the very warning this PR adds. It's readable in context (the writes still aren't stopped, i.e. nothing changes about atomicity), but a reader skimming just the main clause gets the opposite of what the parenthetical says. Worth tightening, e.g. "...with no rollback guarantee — exactly the defect #1205 fixed, undiagnosed until now (a The Reuse: a second copy of the warn-once pattern
Relatedly: the I also checked whether this creates test-order fragility in Changeset amendment — accurateChecked the "before" claim against git history and the "after" claim against current code:
Nothing else stood out as a correctness bug. Overall this is a solid, narrowly-scoped documentation/diagnostics follow-up with no functional risk beyond the minor doc wording nit above. Generated by Claude Code |
- Share the warn-once-per-key mechanism between select-ignored and no-transaction-capability diagnostics instead of two copies of the same Set<string>/has/add pattern, each namespaced so their keys can't collide - Reword the client parameter docblock: it previously said the write fails "silently" in the same sentence that describes the new console.warn Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AB3Ru72ye9FoGjBMq4bDAo
|
Addressed both review points in d2ff73a:
Still blocked on the unrelated Generated by Claude Code |
Coverage Report for Core Package Coverage (./packages/core)
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||
Coverage Report for UI Package Coverage (./packages/ui)
File CoverageNo changed files found. |
Coverage Report for CLI Package Coverage (./packages/cli)
File CoverageNo changed files found. |
Coverage Report for Auth Package Coverage (./packages/auth)
File CoverageNo changed files found. |
Coverage Report for Storage Package Coverage (./packages/storage)
File CoverageNo changed files found. |
Coverage Report for RAG Package Coverage (./packages/rag)
File CoverageNo changed files found. |
Coverage Report for Storage S3 Package Coverage (./packages/storage-s3)
File CoverageNo changed files found. |
Coverage Report for Storage Vercel Package Coverage (./packages/storage-vercel)
File CoverageNo changed files found. |
Summary
#1262 fixed the mechanism (the write pipeline's constant-false transaction probe), but left open the documented path that lets a caller rebuild the same silent no-transaction shape by hand:
getContext(config, requireOrmHandle(config, db.orm), session)type-checks, runs, and drops the write's rollback guarantee without saying anything.context.dbwrites now warn once per(list, operation)viaconsole.warnwhen the context has neither an enclosing transaction to join nor an opener of its own — instead of silently writing outside a transaction.context.transaction()already refused this shape (TransactionUnavailableError); a plain write has no such terminal to refuse from, so it still runs, but no longer silently (packages/core/src/context/write-pipeline.ts).getContext'sclientparameter docblock now states that omitting it costs the write transaction, not only that it powerscontext.unsafe.requireOrmHandle's docblock now says what the returned handle does not carry (no transaction capability, no Unsafe surface — both come only from the client itself).packages/core/README.md: it already teaches the currentgetContext(session?)form, not the stale three-argument one, so no change was needed there.eager-writes-openchangeset (for fix(core): every write opens a real Prisma 8 transaction (#1205) #1262, not yet published to a changelog): corrected the "now says so" claim for a plain write — it now genuinely does, via the new warning — and recordedOrmHandleUnresolvableError's blast-radius change from a per-list lazy error to a build-time refusal for the whole context, which no changeset previously called out.Note: the issue text says this targets a
prisma-8integration branch rather thanmain. That branch no longer exists and the code in question (requireOrmHandle, the Prisma 8 client threading) is already present onmain, confirming the integration branch was already merged — so this PR targetsmainas it should.Test plan
context.db.User.create()on a clientless context runs (with no rollback guarantee) but warns exactly once viaconsole.warn, and doesn't warn again for a second write to the same list/operation (packages/core/src/context/interactive-transaction.test.ts)pnpm build(root) passespnpm testinpackages/core— 1695 passed, 7 skipped, no regressionspnpm lintpassespnpm manypkg fix/pnpm format— no changes neededCloses #1273
🤖 Generated with Claude Code
https://claude.ai/code/session_01AB3Ru72ye9FoGjBMq4bDAo
Generated by Claude Code