Skip to content

Commit b3ec89f

Browse files
docs(qa): wave-3 accuracy slice S1 — records-forms.json (#28352)
Part of #27377 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:平台测试清单 `docs/qa/platform-checklist/areas/records-forms.json` 里 19 个条目和 1 个区域配方的文字,按 18.3.0 第三波跑测记录(#27441、#27438、#27481)的勘误改成与当前代码一致;每个条目 revision +1,main 的 history 原样保留并追加一行。 - 为什么改:#27377 的提取义务——跑测发现的清单准确性问题要落回账本,否则下一轮跑测会照着过时步骤把正常产品判红或判阻塞(例如去找已删除的 Related 页签、已退役的 split 表单)。 - 风险与回滚:只改 docs/qa 下一个 JSON,不发布、不动产品代码;条款只变得更精确或更强(form-view-gallery 新增 acceptance[5] 拒收条款,追加在末尾不挪编号),回滚即 revert 本 PR。 - 先看:form-view-gallery(删 split 变体、新增拒收条款)、related-list-server-pagination(改指记录页 v3 的正文表格与侧栏卡片)、record-discussion-mentions(流的排序方向、单库成员的 sys_comment 授权)。 - 两分钟验证:`pnpm check:platform-checklist`,预期末行为 `check-platform-checklist: OK — 16 areas, 352 items`。 - 需要你做的:无,席位落地。 ## What changes One file, `docs/qa/platform-checklist/areas/records-forms.json`. Each touched item: `revision` +1, main's `history` kept as an exact prefix, one appended row citing its run record and #27377. Every edit re-verified against origin/main `a0f865491d` (the census compared at `501c864dd5`). The row numbers are the seat census's. | item | census row | old → new, in brief | record | |---|---|---|---| | form-view-gallery r5→r6 | 98 | `split` variant, and "an overlaid drawer/modal renders simple" → form `type` is simple/tabbed/wizard since 18.3.0 (ADR-0050, #27305); split, drawer and modal are refused by name, scored by steps[3] and a new acceptance[5]; presentations stay on task-desk.page.ts | #27441 | | record-discussion-mentions r12→r13 | 100, 101, 201, 202 | "oldest-first"; four FeedFilterMode values "on the record detail"; no sys_comment grant on the single boot → "in time order", newest-first on the v3 stream and oldest-first on an authored `record:discussion` panel; the filter is driven on Project Detail's panel; the single-boot member gets the grant too | #27441 (also #27438) | | action-location-matrix r16→r17 | 102 | visible `'!record.done'`; showcase_reopen_task unnamed → `has(record.done) && record.done != true`; Reopen listed as Mark Done's mirror | #27441 | | field-group-visible-when r10→r11 | 103 | no pre-fill → pre-fill a member value (details `hideEmpty` defaults to true) | #27441 | | field-unique-enforcement r12→r13 | 171 | `PUT /api/v1/meta/object/qa_unique` → `qauniq_item` under a package declaring namespace `qauniq`, install spelled | #27438 | | comment-reactions-and-edit-stamps r4→r5 | 172 | "through the metadata door" → `PUT /api/v1/meta/permission/NAME` with the sys_comment / sys_comment_reaction grants, then the bind | #27438 | | delete-behavior-matrix r4→r5 | 173 | zoo row without its required `f_master_detail` → a third account and a project parent first | #27438 | | predicate-relationship-traversal r5→r6 | 174 | "none can be provisioned" → the runtime-only scratch substitute spelled, with the member's 403 parent read as control | #27438 | | list-view-capabilities r7→r8 | 194, 195 | string sort `'estimate_hours desc'` → the array sort reaching `sort=-estimate_hours`; select not-done rows for Mark Done | #27438 | | related-list-server-pagination r10→r11 | 196 | shared Related tab, page size 5, "Page 1 of 6" → body tables + compact cards at the column tiers; paging in the enlarged view, 25 a page, "Page 1 of 2" | #27438 | | gantt-interactions r7→r8 | 197 | locked-leaf drag "not run-proven, blocked(fixture)" → the run-proven `lockField: 'done'` overlay recipe; only the auto-schedule half stays blocked | #27438 | | conditional-rules-grid r10→r11 | 199, 200 | amount "client-computed, stored as sent"; "flip to paid and save" → amount is server-computed; lock/unlock driven on the unsaved header Status | #27438 | | form-dirty-guard r6→r7 | 203 | "11 it() cases" → 11 literals, 14 tests (a describe.each over two forms) | #27438 | | conditional-rules-header r7→r8 | 204, 205 | "open INV-1003 (paid) … tax_rate read-only"; N1 unscoped → the lock is read on INV-1001's form with Status set to Paid, unsaved; N1 scoped to a PATCH that leaves status paid | #27438 | | action-param-widgets r5→r6 | 206, 207 | richtext→editor, date→date input → RichTextField's textarea; the date-picker widget | #27438 | | encrypted-field-behavior r6→r7 (steps[0] only) | 213 | "provider-wired boot (`os serve`)" → `os dev` (spawns `serve --dev`) wires LocalCryptoProvider too | #27438 | | field-type-constraints r5→r6 | 211, 212 | string length with no carrier; lookupFilters as the boundary carrier → `name` (maxLength 200); the dependsOn carrier shows the existence-only boundary | #27438 | | field-type-matrix r7→r8 | 215 | "47 on the form"; location "structured inputs" → 47 TYPES over 49 f_* fields plus `name`; location's single `latitude, longitude` input | #27438 | | v18-semantic-defaults r5→r6 | 216 | `pnpm dev -- --fresh`; no seeding step → any own-port boot (`objectstack dev --fresh --no-compile` for a shared tree); seed more than 50 rows first | #27438, #27481 | | area recipe `qa-crm-import-console` | 208 | teardown "delete ui/e2e/live/.auth/" → plus the one-state-path-per-tree warning; the change is recorded in the recipe's `provenance` (recipes carry no revision) | #27438 | ## Tests No product code and no test changed, so no package test is owed. The ledger gate and the derived local gate families ran on the final head `6ccf9e18a9`; see Verification. ## Acceptance notes - **Held, not raced: `records-forms.crud-roundtrip` steps[6] (census row 137).** Open PR #28116 edits crud-roundtrip steps[5], which is the line next to steps[6], plus record-edit-undo and field-history-tracking. Bumping crud-roundtrip here would race it textually. The finding still holds at `a0f865491d`; it can land after #28116. - **#28116 will re-stale two items edited here.** It retires the column tiers, the tab tier and the related rail, and moves the timeline stream into a 动态 panel and tab. When it lands, record-discussion-mentions steps[5]/[11] and related-list-server-pagination steps[1]–[3] need another re-point. They describe origin/main today. - **Skipped by order (UNCLEAR in the census):** form-view-gallery steps[0] and steps[6] (row 99, waits on a re-measure after #28066); encrypted-field-behavior A3/N1 (row 209, a RUNNER rule-6 ruling); bulk-select-all-matching (row 161, a UX ruling). FIXED upstream, skipped: rows 136, 166, 210, 214. - **GAP rows left parked:** 135, 153, 154, 155, 156. Row 157 (write-time-option-and-element-shape-judgement): the `OS_ALLOW_UNLINTED_METADATA_WRITES=1` recipe is already in its requires[2], so no edit. Row 158: the seeding allowance was already in requires[2]; the v18 edit now names the seeding step. - **Where the edit departs from the record's suggested wording, source decided:** - import-console teardown: the record suggested a copied config with its own storageState. At `a0f865491d` that cannot work: `ui/e2e/live/global-setup.ts` writes the fixed `e2e/live/.auth/state.json` with no env override. The teardown prescribes one runner per tree instead. - conditional-rules-header N1: the record said the lock is "judged on the stored row". `isReadonlyWhenLocked` binds the merged record, and the item says that. - related-list-server-pagination: a compact card names 3 rows at `a0f865491d` (5 at the run's `c4c515ad`). - **Observation, not filed:** `docs/adr/0050-form-layout-vs-presentation.md`'s status line still reads Proposed, while `view.zod.ts` cites the acceptance ruling 6464210455. This is documentation lag with no runtime reach. ## Verification All on head `6ccf9e18a9` (branch merged with origin/main). Exit codes were captured before any pipe. <details><summary>pnpm check:platform-checklist: exit 0</summary> ```text check-platform-checklist: OK — 16 areas, 352 items (347 active, 1 planned); coverage: 40 kinds mapped, 3 waived; traps: 19 documented, 19 in use; provisioning: 10 area recipes, 15 item references resolved (2 area-qualified), 10/10 recipes referenced; ... symbol anchors: 1068/1078 (10 on the named residual), 18 file floors held ``` </details> <details><summary>dispatch-gates derived families (16): all exit 0, reconciled with --ran</summary> ```text node scripts/check-adr-links.mjs :: exit 0 node scripts/check-adr-links.mjs --self-test :: exit 0 node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 (first run exit 3, prerequisite: formula + lint unbuilt; built, re-run) pnpm check:ci-filter-parity :: exit 0 pnpm check:cross-package-test-inputs :: exit 0 pnpm check:doc-authoring :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:gitlink-declared :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:platform-checklist :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:watch-hint-literal :: exit 0 ✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED (a DERIVED zero — all 16 recorded an exit code and none of them is 3). ``` </details> <details><summary>NOT MEASURED</summary> form-dirty-guard's 14-test count comes from source: 8 it() literals plus a 3-case describe.each over two forms. The run's 14/14 is the record's. A local `pnpm exec vitest run packages/plugin-form/src/discardGuard.test.tsx` from ui/ exited 1 before any test ran ("Failed to resolve import @objectstack/spec/data" — spec dist not built in this worktree). That is a prerequisite miss, not a test result. </details> --- _Generated by [Claude Code](https://claude.ai/code/session_01QSeKYmTYfaPbLQD4BJfomW)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent a7bdac4 commit b3ec89f

1 file changed

Lines changed: 217 additions & 98 deletions

File tree

0 commit comments

Comments
 (0)