回填10-05到期例外的73文件分流台账 [09-05-error-explainability-payment-readiness]
从孤儿 worktree(artifacts/isolated-worktrees/20260909-ops-preparation)合并 回填 2026-09-09 从未提交的到期豁免分流工作: - 对 591 条错误原因码豁免基线(scripts/qa/error-reason-legacy-baseline.json, 全部 2026-10-05 到期)做完整 AST inventory 核对:673 条基线、695 次调用、 73 文件,逐条 observedCount 与基线一致、0 漂移。 - 73 文件按 A(16 文件/优先迁移)/B(25 文件/待确认业务影响)/C(32 文件/ 逐模块审查延期理由)三档分流,逐文件列出指纹与调用数,均未裁决。 - 首批 4 个具体调用已设计好迁移方案(AP 台账开关/查询校验、todo 开关、 portal 开关的 reasonCode 与中文文案),尚未落码。 - 明确 09-11/09-18/09-25/09-30/10-02 的分阶段裁决节奏;10-05 00:00 UTC (北京时间 08:00)即为门禁到期时点。 无产品代码改动、无原因码源码/注册表变更;仅补齐分流台账文档,为处理 10-05 到期风险提供已有基础,避免从零重新盘点 73 个文件。 Co-Authored-By: Claude Sonnet 5 <[email protected]>
这个提交包含在:
@@ -124,3 +124,10 @@ POST create
|
||||
- 无 migration/schema/seed/flag/routing。生产资料补录不属于部署步骤。
|
||||
- 建议按“原因码/parity、首批迁移、付款 readiness/UI”形成逻辑提交;付款提交可独立回滚且无数据库补偿。
|
||||
- 部署另行批准;公网只用合成 fixture 验证。不得自动创建、复核或付款 0014。
|
||||
|
||||
|
||||
## 8. 到期清单的后续分流合同(2026-09-09)
|
||||
|
||||
按已有 scanner 输出的 file/operation/fingerprint/count 与源文件摘要建立逐条台账,文件表仅作索引。未知使用状况记为待复核,不推导无需维护或默认低频;未证明删除/迁移成功的记录不得核销。保留原 expiresOn 与 owner,不把新 reviewDue 当作门禁新期限;拟延期日期和批准记录必须独立且逐模块说明。
|
||||
|
||||
共用 validation builder 的一个指纹可能影响多个业务分支,迁移必须在调用语义层选择原因;不能批量将所有旧错误映射成一个“通用参数错误”或只更新计数。每个获批迁移分支先定位入口与旧 HTTP status/code/details,再增加精确 reasonCode/中文及失败副作用断言。当前只完成清单,不新增迁移范围或任何线上行为。
|
||||
|
||||
@@ -243,6 +243,142 @@ R1包及其manifest不变;本轮代码已偏离R1,必须重冻R2后交增量
|
||||
- 下一项统一待办需求仅以该真实流程的三个交接观察为输入:交给财务组批、交给经理/CEO 复核、交回财务登记付款;每处记录谁交给谁、接收人通过什么现有入口或提醒知道轮到自己、是否需要口头催办。尚未发生的交接不预填结论,不记录真实银行资料。
|
||||
- 独立待办仍保留:财务测试账号 403 需要单独解决并补财务身份真实验收(管理员代验不等于该角色验收);合同只读超时需单独复现归因,不计入通过;“三张单的答复”仅作为用户提醒保留,未明确具体单据和答复内容,不自行推断或代答。
|
||||
- Trellis 升级另行审查:逐条核对 workflow.md 与 project-governance.md 删除或弱化的规则及理由,独立检查 hooks 行为变化;不以模型升级为整批删除保障的理由。本次仅记录后续事项,不启动新产品任务、不修改配置或真实资料、不自动提交、部署或归档。
|
||||
|
||||
|
||||
## 13. 2026-09-09 到期豁免后续阶段:清单落地(本地阶段已批准)
|
||||
|
||||
用户在综合任务规划后回复“开始实施”。本阶段复用原 task,仅在独立准备 worktree 落地豁免台账和恢复准备;不修改原因码源码、线上配置、基线日期或门禁逻辑,不与 AP/付款产品 diff 混合。责任人沿用原基线 owner,不擅自重新指派;主会话负责技术分流与后续迁移,延期须用户逐模块裁决。
|
||||
|
||||
### 已完成和未完成
|
||||
|
||||
- 已通过实际 AST inventory 按 file + operation + fingerprint 对照 673 条基线、695 次调用、73 文件;每条 observedCount 与 count 一致,0 漂移。baseline SHA-256:`ddeeaadfcc8ac267b23159c5803cd6b21f282329ecbd8847a2f79551198f441f`。
|
||||
- 原因码合同 PASS,20 项 self-test PASS;原 2026-10-05 日期全部保留,主链路零豁免规则不变。所有条目当前仍在源码,没有证据支持本轮直接核销;不把“没有文件漂移”当成每个错误文案已合格。
|
||||
- 文件级初分:A:16 文件 / 179 指纹 / 192 次调用;B:25 文件 / 277 指纹 / 280 次调用;C:32 文件 / 217 指纹 / 223 次调用。A 是优先审查与选取迁移,B 是需确认使用/影响,C 是逐模块审查拟延期;三者都不是已批准延期。清单覆盖所有记录,但尚未逐条完成业务语义复核,不冒充 673 条都已裁决。
|
||||
- 每条指纹在 `artifacts/qa-flow/project-roadmap-execution-20260909/error-disposition.json` 保留原 owner、reason、operation、count、到期日、sourceSha256,以及 lane/reviewDue/decision;proposedExpiresOn 全为空、deferralApproved 全为 false。该路径相对于原主工作区,不是这个隔离工作树内的文件。
|
||||
- 已核对首批小范围候选:AP 开关关闭及台账查询参数校验、todo 开关关闭、portal 开关关闭(4 个具体 legacy 调用);它们只作迁移设计候选,不改权限及状态规则,不宣称已迁移。用户资料/审批等高频分支按同一表继续细分,不能被这 4 条代替。
|
||||
- 特别限制:`paymentAccounts.js` 的唯一登记是 `function:validationError` 共享 builder,覆盖多个实际调用原因。不能因“只有 1 条”就在 builder 里硬塞同一个固定 reasonCode;需先区分各调用的业务含义。指纹数不是工作量或用户错误数。
|
||||
|
||||
### 日期和延期裁决
|
||||
|
||||
09-11 前逐模块确认本期分支名单;09-18 验证首批迁移;09-25 复审容量;09-30 前逐模块确定是否延期及各自新日期;10-02 查剩余到期项。门禁按 UTC 日期,10-05 00:00 UTC(北京时间 08:00)即判当天到期,不到午夜再处理。不能因为完成这份台账就把日期延长;每份延期需写业务影响、现有兜底、未迁移原因、负责人和新复审日期并获批,不能整包统一延期。
|
||||
|
||||
### 全量文件处置入口
|
||||
|
||||
A=优先审查/选迁移;B=业务影响复核;C=延期理由逐模块交审(并非已延期)。所有行原到期日均为 2026-10-05,裁决均未完成;下面数量是指纹条数/实际调用数。
|
||||
|
||||
| 文件 | 指纹 / 调用 | 分流 | 原 owner | 首次复核 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `server/src/plugins/auth.js` | 1 / 1 | A | shunli | 09-11 |
|
||||
| `server/src/routes/ai.js` | 1 / 1 | C | shunli | 09-11 |
|
||||
| `server/src/routes/announcements.js` | 9 / 9 | C | shunli | 09-11 |
|
||||
| `server/src/routes/apOperations.js` | 2 / 2 | A | shunli | 09-11 |
|
||||
| `server/src/routes/approvalRules.js` | 6 / 6 | B | shunli | 09-11 |
|
||||
| `server/src/routes/assetMovements.js` | 11 / 11 | C | shunli | 09-11 |
|
||||
| `server/src/routes/assets.js` | 28 / 29 | C | shunli | 09-11 |
|
||||
| `server/src/routes/attendance.js` | 10 / 10 | C | shunli | 09-11 |
|
||||
| `server/src/routes/audit.js` | 2 / 2 | C | shunli | 09-11 |
|
||||
| `server/src/routes/auth.js` | 15 / 15 | A | shunli | 09-11 |
|
||||
| `server/src/routes/budgetControlRules.js` | 6 / 6 | B | shunli | 09-11 |
|
||||
| `server/src/routes/budgets.js` | 13 / 14 | B | shunli | 09-11 |
|
||||
| `server/src/routes/confidentialDocRefs.js` | 4 / 4 | C | shunli | 09-11 |
|
||||
| `server/src/routes/configRead.js` | 2 / 2 | C | shunli | 09-11 |
|
||||
| `server/src/routes/contractsRegistry.js` | 10 / 10 | B | shunli | 09-11 |
|
||||
| `server/src/routes/cutover.js` | 4 / 4 | C | shunli | 09-11 |
|
||||
| `server/src/routes/dashboard.js` | 2 / 2 | C | shunli | 09-11 |
|
||||
| `server/src/routes/delegations.js` | 17 / 17 | C | shunli | 09-11 |
|
||||
| `server/src/routes/departments.js` | 14 / 14 | B | shunli | 09-11 |
|
||||
| `server/src/routes/employees.js` | 25 / 31 | A | shunli | 09-11 |
|
||||
| `server/src/routes/expenseStandards.js` | 11 / 11 | B | shunli | 09-11 |
|
||||
| `server/src/routes/expenseTypes.js` | 6 / 6 | B | shunli | 09-11 |
|
||||
| `server/src/routes/exports.js` | 9 / 9 | B | shunli | 09-11 |
|
||||
| `server/src/routes/featureFlags.js` | 8 / 8 | C | shunli | 09-11 |
|
||||
| `server/src/routes/feeControl.js` | 2 / 2 | C | shunli | 09-11 |
|
||||
| `server/src/routes/integrations.js` | 22 / 22 | C | shunli | 09-11 |
|
||||
| `server/src/routes/inventoryChecks.js` | 11 / 14 | C | shunli | 09-11 |
|
||||
| `server/src/routes/invoicePool.js` | 29 / 30 | A | shunli | 09-11 |
|
||||
| `server/src/routes/invoicePool/read.js` | 7 / 7 | A | shunli | 09-11 |
|
||||
| `server/src/routes/invoicePool/shared/schemas.js` | 1 / 1 | A | shunli | 09-11 |
|
||||
| `server/src/routes/invoicePool/verification.js` | 7 / 7 | A | shunli | 09-11 |
|
||||
| `server/src/routes/leave-types.js` | 6 / 6 | C | shunli | 09-11 |
|
||||
| `server/src/routes/masterData.js` | 25 / 25 | B | shunli | 09-11 |
|
||||
| `server/src/routes/masterDataHolidayCalendars.js` | 15 / 15 | B | shunli | 09-11 |
|
||||
| `server/src/routes/masterDataSuppliers.js` | 11 / 11 | B | shunli | 09-11 |
|
||||
| `server/src/routes/me.js` | 2 / 2 | C | shunli | 09-11 |
|
||||
| `server/src/routes/migrationRuns.js` | 5 / 5 | C | shunli | 09-11 |
|
||||
| `server/src/routes/notifications.js` | 7 / 7 | A | shunli | 09-11 |
|
||||
| `server/src/routes/paymentAccounts.js` | 1 / 1 | A | shunli | 09-11 |
|
||||
| `server/src/routes/payroll.js` | 17 / 18 | C | shunli | 09-11 |
|
||||
| `server/src/routes/performance.js` | 12 / 12 | C | shunli | 09-11 |
|
||||
| `server/src/routes/portal.js` | 2 / 2 | A | shunli | 09-11 |
|
||||
| `server/src/routes/presence.js` | 3 / 3 | C | shunli | 09-11 |
|
||||
| `server/src/routes/projects.js` | 6 / 6 | B | shunli | 09-11 |
|
||||
| `server/src/routes/purchaseRequests.js` | 50 / 52 | B | shunli | 09-11 |
|
||||
| `server/src/routes/reimbursementTemplates.js` | 6 / 6 | B | shunli | 09-11 |
|
||||
| `server/src/routes/riskFlags.js` | 5 / 5 | C | shunli | 09-11 |
|
||||
| `server/src/routes/search.js` | 3 / 3 | C | shunli | 09-11 |
|
||||
| `server/src/routes/systemWorkspace.js` | 2 / 2 | C | shunli | 09-11 |
|
||||
| `server/src/routes/todos.js` | 5 / 5 | A | shunli | 09-11 |
|
||||
| `server/src/routes/travelAuthorizations.js` | 5 / 5 | B | shunli | 09-11 |
|
||||
| `server/src/routes/travelOrders.js` | 9 / 9 | B | shunli | 09-11 |
|
||||
| `server/src/routes/travelReconciliation.js` | 12 / 12 | B | shunli | 09-11 |
|
||||
| `server/src/routes/travelRequests.js` | 21 / 21 | B | shunli | 09-11 |
|
||||
| `server/src/routes/travelTransactions.js` | 7 / 7 | B | shunli | 09-11 |
|
||||
| `server/src/routes/users.js` | 35 / 40 | A | shunli | 09-11 |
|
||||
| `server/src/routes/wecomAuth.js` | 7 / 8 | A | shunli | 09-11 |
|
||||
| `server/src/routes/weeklyReports.js` | 7 / 7 | C | shunli | 09-11 |
|
||||
| `server/src/routes/workflow.js` | 20 / 20 | A | shunli | 09-11 |
|
||||
| `server/src/routes/workflowDefinitions.js` | 11 / 11 | B | shunli | 09-11 |
|
||||
| `server/src/services/ai/suggestions.js` | 1 / 1 | C | shunli | 09-11 |
|
||||
| `server/src/services/attendance.js` | 8 / 9 | C | shunli | 09-11 |
|
||||
| `server/src/services/budgetPool.js` | 7 / 7 | B | shunli | 09-11 |
|
||||
| `server/src/services/contractRegistryFilters.js` | 4 / 4 | B | shunli | 09-11 |
|
||||
| `server/src/services/cutover.js` | 1 / 1 | C | shunli | 09-11 |
|
||||
| `server/src/services/documentSequence.js` | 5 / 5 | B | shunli | 09-11 |
|
||||
| `server/src/services/employeeDirectoryFilters.js` | 3 / 3 | C | shunli | 09-11 |
|
||||
| `server/src/services/feeControl.js` | 3 / 3 | C | shunli | 09-11 |
|
||||
| `server/src/services/presenceHistory.js` | 3 / 3 | C | shunli | 09-11 |
|
||||
| `server/src/services/purchaseBudget.js` | 3 / 3 | C | shunli | 09-11 |
|
||||
| `server/src/services/travelPayments.js` | 2 / 2 | B | shunli | 09-11 |
|
||||
| `server/src/services/travelReconciliation.js` | 6 / 6 | B | shunli | 09-11 |
|
||||
| `server/src/utils/workflow.js` | 15 / 15 | A | shunli | 09-11 |
|
||||
|
||||
### 四项状态
|
||||
|
||||
| 代码 | 发布 | 业务验收 | 等谁/下一步 |
|
||||
| --- | --- | --- | --- |
|
||||
| 原功能已交付;本阶段只有台账,没有新产品改动 | 本轮未发布 | 台账核对通过,不等于真人错误处理验收 | 先等待 T0 两笔收口的提交授权;分支细分不需生产访问;延期名单交用户裁决 |
|
||||
|
||||
|
||||
## 14. 2026-09-09 首批具体分支与验证要求
|
||||
|
||||
用户采纳“推进最小恢复授权,同时完成错误豁免分支清单”的建议。本轮只细化清单,不将该回复扩大为ARM真实恢复、延期审批或产品发布授权。主仓已是b918530;73文件的源码摘要与原清单仍全部一致,清单没有因两笔提交失效。准备worktree仍基于58dcee0,未来实际写代码前须迁移到当时最新已提交基线,不能在旧基线上实施后覆盖已提交的CEO修订。
|
||||
|
||||
### 第一批四个明确调用
|
||||
|
||||
下面均为已有legacy调用,原到期日2026-10-05不变,reasonCode/文案为具体迁移方案,尚未修改源码或注册表。不将“功能开关关闭”改成“无权限”,不调整守卫顺序,也不自动开启开关。
|
||||
|
||||
| 文件 / operation | 指纹短标识 | HTTP保持 | 拟原因码 | 拟用户文案 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `server/src/routes/apOperations.js` / `function:ensureFeatureEnabled` | `48951ae2ad49` | 409 | `ap_operations.feature_disabled` | 应付账款暂未开放,请联系管理员确认处理方式。 |
|
||||
| `server/src/routes/apOperations.js` / `/ap-operations/reimbursement-ledger` | `4673e0a3f7e9` | 400 | `ap_operations.query_invalid` | 查询条件不符合要求,请检查筛选条件后重试。 |
|
||||
| `server/src/routes/todos.js` / `function:ensureFeatureEnabled` | `309a572d3996` | 409 | `todo.feature_disabled` | 待办功能暂未开放,请联系管理员确认处理方式。 |
|
||||
| `server/src/routes/portal.js` / `function:ensureFeatureEnabled` | `de0048472baa` | 409 | `portal.feature_disabled` | 工作台暂未开放,请联系管理员确认处理方式。 |
|
||||
|
||||
### 每个分支的结束判据
|
||||
|
||||
- AP关闭:两个GET以及带筛选查询均保持409和原VALID_001/featureFlag/reason,增加精确reasonCode;业务财务查询次数为0。开启时继续验证CEO/manager无权403、finance等合法身份可读,原权限矩阵不退步。
|
||||
- AP查询非法:开启功能且有读取权限时无效查询保持400、保留原校验details,增加精确reasonCode,台账业务查询为0;合法查询200,无权身份不因参数非法绕过或改变原403守卫。
|
||||
- todo关闭:覆盖所有消费同一guard的入口,不只GET;409、旧details和新增原因码一致,业务读写均不发生;开关开启原合法路径正常。必须补对应路由注入覆盖,本次未发现已有按todos命名的专门路由测试,不能拿portal测试代替。
|
||||
- portal关闭:沿已有portal路由测试补精确原因码和业务查询零调用断言;开启后原首页查询不退步,不新增通知或待办业务行为。
|
||||
- 前端三个页面已消费统一resolveErrorMessage,仍需用实际ApiError路径断言四句中文,而不只检查注册表有四个字符串;未知原因保留安全兜底,不把details或内部开关名展示给员工。
|
||||
- AP现有权限测试的自定义error handler只返回code,不能用它证明details.reasonCode;需使用生产等价响应处理或另建原因码测试,保留原权限断言,不为了绿改成宽泛message匹配。
|
||||
- 注册表、客户端映射、中文fixture与真实分支测试必须同步。只移除这四个精确file/operation/fingerprint记录,不按文件删除基线,不改其余expiry。若仅本批四次调用迁移完成且无其他并发变更,预期残余669条记录/691次调用;这个数是未来验收预期,不是当前成果。
|
||||
|
||||
### 尚待细分的部分
|
||||
|
||||
第一批只解决四个具体分支,不等于73文件都已形成迁移决定。员工资料、登录、审批解析、票据等优先域继续按真实业务影响细分;paymentAccounts共享validationError需先追到实际调用语义,不能套一个固定原因码完成所谓“1条迁移”。余下记录仍须在既定日期逐模块确认迁移或提出有理由延期;本轮未批准任何延期。
|
||||
|
||||
完整四分支记录见原主工作区artifacts/qa-flow/project-roadmap-execution-20260909/error-first-batch-branches.json;原始673条台账不覆盖,保留当前与未来验收预期的区别。
|
||||
# 2026-09-16 上线后契约补强
|
||||
|
||||
后续日期批次方案:共享date工具新增纯isValidDateOnlyString谓词(严格YYYY-MM-DD、有限UTC日期、回读同日),保持旧parseDateOnlyString行为以免无关服务突然抛500;先接报销/付款/差旅申请/资产四路由的既有Zod日期schema,optional/nullable外层语义不变,失败沿原输入错误合同且写入前拒绝。催办复用前端displayFormat的Asia/Shanghai格式并明确“北京时间”,旧details分支也校验UTC形状/有限性,不回显任意字符串。验证单测正反边界、各域实际入口/解析器、无副作用及前端typecheck/build;采购、合同、考勤等剩余消费者继续单列,不冒称所有日期解析债务清零。不迁移或改生产历史日期,不提交/部署本轮未审代码。
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# 错误可解释性与付款就绪治理
|
||||
|
||||
|
||||
## 2026-09-09 追加阶段
|
||||
|
||||
用户已批准综合任务安排的本地实施。复用本 task 管理 10-05 到期豁免分流,不改变原功能验收。当前交付是 73 文件/673 指纹全量核对与分流台账(implement.md §13);未迁移原因码、未修改基线日期,不把 file 级分类冒充逐调用业务裁决。新分支迁移沿原 status/code/details 兼容与精确测试合同;须先完成既有两笔隔离提交,不能在原脏树叠第三笔产品代码。延期、提交、推送、部署各守明确授权。
|
||||
|
||||
|
||||
## Goal
|
||||
|
||||
把“系统知道为什么不能继续、真人只看到参数校验失败”的缺陷从逐页补文案改成可持续的错误合同,并以付款批次为第一个完整样板:财务在点击前就知道付款资料是否齐全、缺什么、由谁补;点击后的服务端二次校验与页面提示必须来自同一份实时判断。
|
||||
|
||||
在新工单中引用
屏蔽一个用户