Repository navigation
fix(cli): os migrate record-currency-codes judges --code before the probe, prompt and boot; document the command and the record-mode switch - #28416
Conversation
…e record-currency-codes A code outside ISO 4217 is refused with the backfill's INVALID_FIELD / 400 envelope before the occupancy probe, the --apply prompt and bootSchemaStack. The engine-side check is unchanged. Document the command in cli.mdx and the record-mode switch (409 destructive_change, dry run, --apply) in currency.mdx. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3BvyNBMezKJUd7aydyG
📓 Docs Drift CheckThis PR changes 1 package(s): 22 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 5 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 35 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 26835f90ed1dccbd03482071841990652992392a && git checkout 26835f90ed1dccbd03482071841990652992392a
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin af6ca001b6ce63e4aef0ac3237b1e23d1f77e29f 2a029310c284aae891814fa8a823d28d190624cb && git checkout -B drift-repro af6ca001b6ce63e4aef0ac3237b1e23d1f77e29f && git merge --no-ff 2a029310c284aae891814fa8a823d28d190624cb
node scripts/docs-audit/affected-docs.mjs --json af6ca001b6ce63e4aef0ac3237b1e23d1f77e29f
|
…cord-currency-codes section The currency-mode closure pin (rule A) reds a defaultCurrency sentence that does not carry the fixed condition. Name the field's defaultCurrency as the one it had under fixed. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QUs3BvyNBMezKJUd7aydyG
Requested by Sam · project thread
Fixes #28168
Clause-②: no
Metadata-protocol: none
维护者速读
os migrate record-currency-codes现在一进来就判--code,不在 ISO 4217 里的码在探库、--apply确认提示和 boot 之前就以INVALID_FIELD/ 400 退出;CLI 文档和 Currency 文档页补上这条命令、切换时的 409 与 dry run /--apply两步。--apply的 boot 会先建表建列;文档里兄弟命令都有条目,唯独这条没有。isValueDomainMember('iso_4217_currency', …),引擎侧检查原样保留;回滚即 revert 本 PR。packages/cli/src/commands/migrate/record-currency-codes.ts(新函数与run()开头那段),其测试文件新增的 describe,content/docs/data-modeling/currency.mdx新增小节。pnpm --filter @objectstack/cli exec vitest run --project integration src/commands/migrate/record-currency-codes.test.ts,预期 12 个用例全绿,含「坏码不探库、不弹提示、不 boot」两条。What changes
packages/cli/src/commands/migrate/record-currency-codes.ts.run()now judges--codefirst, right after the header and before the occupancy probe, the--applyconfirmation prompt andbootSchemaStack. The predicate is the onebackfillRecordCurrencyCodesapplies,isValueDomainMember('iso_4217_currency', code)from@objectstack/spec/shared(a light import;@objectstack/objectqlstays lazily loaded). The error is the engine's envelope:code: 'INVALID_FIELD',statusandhttpStatus400, so--jsonanswers{ error, code: 'INVALID_FIELD', httpStatus: 400 }and exit 1, as it did after the boot. The human face prints the message and exits 1.[record-currency-backfill] 'usd' is not an ISO 4217 currency code, so … would refuse it: give the uppercase alphabetic code of the currency these amounts are in (for example USD).One part cannot match word for word: the engine names the code field ('opportunity.currency_code'), which is read from the object's declaration, and that is not loaded before the boot. The early refusal names the amount instead (the currency code field of 'opportunity.amount') and endsRefused before the database was opened or any row was read.packages/objectql/src/record-currency-backfill.tsis untouched and keeps its own check for every other caller. The CLI's post-boot catch comment now says the code is judged before the boot.--codeflag description now says a non-ISO code is refused before the database is opened.content/docs/deployment/cli.mdx. A row in the data-migrations table, aftersummary-nulls, and a#### os migrate record-currency-codessection shaped likesummary-nulls: why the rows owe a code, the three invocations, the code is the operator's and never derived, the early--coderefusal and the post-bootOBJECT_NOT_FOUND/INVALID_FIELDrefusals, writes through the engine, idempotent, no flag.content/docs/data-modeling/currency.mdx. A### Switching a field that already holds rowssection under the record mode: the 409destructive_changewith findingcurrency_mode_to_record, lifted by re-submitting withforce(?force=trueonPUT /api/v1/meta/:type/:name), then the dry run and--apply. It says the code is the one given with--codeand is never derived, and links to the CLI section. Both pages are hand-written trees under AGENTS.md's Documentation Guardrails, not release-owned..changeset/28168-record-currency-code-before-boot.md:@objectstack/clipatch, both declaration lines.Tests
packages/cli/src/commands/migrate/record-currency-codes.test.ts(integration tier, as the file already was):a code outside ISO 4217 is refused before the probe, the prompt and the boot:--json --applywithusdand no--yes: exit 1, the envelope isINVALID_FIELD/ 400 (the samecodeandhttpStatusas the real engine's refusal of the same code, which the test produces), neverconfirmation_required; the message's leading clause equals the engine's;bootSchemaStack,probeMigrationTargetand the backfill are never called.--applyon a terminal (stdin.isTTYtrue) withEURO: exit 1, the engine's leading clause is printed, no readline prompt is opened, and neither the boot nor the probe is called.USD) still reaches the boot and the backfill.INVALID_FIELD/ 400 / the message reaching--json.Acceptance notes
'OBJECT.FIELD''s code field instead of the code field by name (reason above). The envelope (code,httpStatus) and every other sentence are the engine's.Verification
All readings at head
738019ef.Tests and typecheck
pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 src/commands/migrate/record-currency-codes.test.ts: Test Files 1 passed, Tests 12 passed; lock VERDICT command-exit 0.pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2 test/migrate-confirmation-exit.pin.test.ts: Tests 38 passed.pnpm --filter @objectstack/cli typecheck: exit 0 (tsc, then check:test-typecheck OK).Ablation
node scripts/ablation-replace.mjsreplaced the callrefuseNonMemberCurrencyCode(flags.object, flags.field, flags.code);with a marker (anchor 1 to 0, blob 6bf55f78 to 9501b58a), then ran the test file: the two new refusal cases failed (Tests 2 failed, 10 passed) and the control passed. Restored: the file's blob equals HEAD's (6bf55f78) andgit diff HEADis empty. The command imports fromsrc, so no rebuild was involved.Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 93 families. All 93 ran, each recorded asCOMMAND :: exit N. Five (check:skill-examples,check:dual-build-cjs-loads,check:i18n,check:i18n-coverage,check:i18n-walk-parity) first exited 3 (PREREQUISITE NOT MET); after a fullpnpm build(lock VERDICT command-exit 0, Tasks 116 successful of 116) all five exited 0.dispatch-gates --ran: 93 derived, 93 run, 0 NOT-MEASURED, 0 UNRUN, exit 0.pnpm lint: exit 0.Human Minimum
packages/specholds no runtime logic. (Not touched.)pnpm lintpasses.main, one pull request.packages/spectouched: not touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01QUs3BvyNBMezKJUd7aydyG