Skip to content

Commit de6fbd4

Browse files
test(qa-scenarios): add the requisition_to_receipt mid-tier scenario card (#30703)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} --> _Requested by **Elon** · [project thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DGZeuomThCs6PH2x2FrJR8Q)_ Fixes #30480 Clause-②: no Metadata-protocol: none ## 维护者速读 - **改了什么**:新增「采购申请到收货」中档场景卡(8 个对象、按金额 5000 / 30000 分三档的多级审批、3 个角色其中 2 个按行限定、1 个采购支出报表、120 张采购申请跨 7–10 月、10 道问数、6 个写操作、5 个 agent 动作),并配一份只属于这张卡的真值测试。 - **为什么改**:落实 cloud#3600 九个场景中的采购场景,让 AI 建应用、问数、代办写操作都有一张能用代码判分的采购卡。 - **风险与回滚**:只加测试数据和测试,所在包私有、不发布,运行时零改动;回滚即删两个新文件。 - **先看**:① `docs/qa/scenarios/requisition_to_receipt.json` 的 `run.questions` 与 `run.operations`;② `packages/qa/scenarios/test/requisition-to-receipt.test.ts` 的 `EXPECTED_TRUTHS` 及旁边的手算推导;③ 同一文件里的种子一致性用例。 - **两分钟验证**:`pnpm --filter @objectstack/scenarios test`,预期 5 个测试文件、69 个用例全绿。 - **需要你做的**:无,席位落地。 ## What changes - `docs/qa/scenarios/requisition_to_receipt.json` (new): the 采购申请到收货 requisition-to-receipt mid-tier card. - Eight objects: `department`, `employee`, `supplier`, `purchase_requisition` (the main object), `approval_step`, `purchase_order`, `po_line` and `goods_receipt`. - The amount-threshold approval: `approval_levels` is 1 up to 5,000, 2 up to 30,000 and 3 above (a formula on the amount). Level 1 goes to the requester's department manager, level 2 to the finance controller, level 3 to the general manager. The seed holds all three levels, including a requisition of exactly 5,000 at one level. - Three personas: `requester` (own rows) and `dept_manager` (own department) carry a row scope on all five transactional objects; `buyer` is organization-wide. Department budgets are hidden from the requester and the buyer, supplier bank accounts from the requester and the manager. - Seed: 120 requisitions dated July to October 2026, plus 184 approval steps, 90 purchase orders, 117 order lines and 97 goods receipts. The arithmetic rule that generated it is stated in the card's `$comment`, so every truth can be worked by hand. - Run half: 10 questions, 6 operations and 5 agent actions (one confirm-gated); `iterate` adds supplier invoices with a three-way match. - `packages/qa/scenarios/test/requisition-to-receipt.test.ts` (new): this card's own test file. - It pins all 10 computed truths and the 6 per-persona truths against hand-worked values, with the derivations written next to the pins. - It asserts the mid-tier floor and the seed's own consistency: a line is quantity times unit price, an order totals its lines and equals its requisition, the approval levels follow the thresholds, each level routes to its approver, the steps match the status, and a received order has every line fully received. - It shows that a wrong seed cell or a wrong truth spec in a fixture copy goes red against those pins. ## Why The card is one of the six mid-tier scenarios ruled on objectstack-ai/cloud#3600 (Q1 = v3). It gives the procurement domain a scenario whose answers, permission boundaries and write outcomes are graded by code. ## Tests `pnpm --filter @objectstack/scenarios test`: 5 files, 69 tests passed. `pnpm --filter @objectstack/scenarios typecheck`: exit 0, after building the closure with `pnpm --filter '@objectstack/scenarios^...' build`; `tsc --listFiles` includes the new test file. ## Acceptance notes - **File name.** The card is `requisition_to_receipt.json`, not `requisition-to-receipt.json` as the issue spells it. A card's `id` must be a snake_case machine name equal to the file's basename, so a hyphenated basename cannot load. The schema is unchanged. - **`library.test.ts` untouched.** It names only the three control cards and asserts the rest by "no refusal", so this card needs no line there. - **No schema field for some floor items.** As on the travel-expense card, three floor items have no field in the schema: an approval or automation flow as a structural expectation, "declarative preferred", and a report as distinct from a dashboard. The card states them in `prompt.detailed` (zh and en) and in `capabilities`, seeds `approval_step` as an expected object, and declares the report under `expect.dashboards`. Nothing in the loader grades them. - **Seven operation kinds, six operations.** `raise_po_from_text` covers two of them: entry from free text with lines, and the multi-step chain (raise the order, add two lines, send it, and the requisition becomes ordered). `manager_approves_level_one` carries the workflow step and its progress query in one ask; `pr_0111_waiting_on` asks the same requisition's progress before the step. - **Free-text lines matched by price.** The two lines `raise_po_from_text` creates are matched by quantity and unit price (41,500 and 6,500 are on no seeded line), not by the item text, so an agent that spells the item differently still matches. - **A value no seed row carries.** `cancel_sent_po` writes `status: cancelled`. `expect.selectFields` asks `purchase_order.status` for at least four options (draft, sent, received, cancelled); the loader checks only that the field exists. - **Capability tags.** The loader checks only the area half. The names follow the travel-expense card; `approvals.dynamic-approver-routing` is also a checklist item. - **Reference not read.** `objectstack-ai/templates` is outside this session's repository scope. The domain is designed from the card text alone, and the rulings are applied as the card states them. - **Seed generator.** The seed was generated by a scratch script kept out of the PR. Its rule is the card's `$comment`. The pinned truths were worked from that rule (the derivations are in the test file) and cross-checked by an independent count. The loader matched every pin on its first run. ## Verification <details> <summary>scenarios test + typecheck (head 1590b31)</summary> ``` Test Files 5 passed (5) Tests 69 passed (69) > tsc --noEmit os-verify-lock: VERDICT command-exit 0 ``` </details> <details> <summary>dispatch-gates --commands (50 commands, local, head 1590b31)</summary> All 50 derived commands exit 0. The `--ran` reconciliation reads: 50 derived, 50 run, 0 NOT-MEASURED, 0 UNRUN, a derived zero because every line recorded its exit code. The first sweep, on the pre-merge head 3d37abf, had four non-zero exits, all from the local tree rather than the diff. Each cleared before the second sweep: - `check-plugin-teardown-shape.mjs --self-test` exit 3: the shallow clone could not reach its pinned fixture commit; cleared by `git fetch --unshallow origin main`. - `check:doc-formula-expressions` exit 3 and `check:dual-build-cjs-loads` exit 3 (PREREQUISITE NOT MET): a dist was not built; cleared by a whole-tree `turbo run build` (119/119). - `check:dts-closure` exit 1: it ran while a closure build of mine was rebuilding `@objectstack/metadata`, so its declarations were briefly absent; exit 0 once no build was running. Changed lines: 1332 (+1332 / -0, 2 files), under the 3000 threshold. `origin/main` was merged at `b77c160a02` before this PR opened; the delta against `main` is still exactly the two new files. </details> ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (No schema touched.) - [x] 2. Every name I added uses the casing for its kind. - [x] 3. No formatter ran; `pnpm lint` passes (the new test file lints clean with the repo config; the repo-wide run is CI's). - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (Nothing publishes: `@objectstack/scenarios` is private, so `skip-changeset`.) - [x] 6. `packages/spec` touched: its generated artifacts are regenerated and committed. (Not touched.) - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English. - [x] The *Before Submitting* list in CONTRIBUTING.md is done. --- _Generated by [Claude Code](https://claude.ai/code/session_016WV4cwyCQLVbmVSgGXVBhc)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent bfb6e15 commit de6fbd4

2 files changed

Lines changed: 1332 additions & 0 deletions

File tree

0 commit comments

Comments
 (0)