比较提交

...
2 次代码提交
作者 SHA1 备注 提交日期
wangsli 492920cd75 docs: 补齐财务身份验收窗口规约(09-05-error-explainability-payment-readiness)
ci-minimal / check-minimal (push) Canceled after 0s
ci-e2e / e2e (push) Canceled after 0s
2026-09-05 22:04:32 +08:00
wangsli a43df86712 docs: 保存复核后的交接笔记(09-05-error-explainability-payment-readiness) 2026-09-05 21:31:48 +08:00
共修改 2 个文件,包含 67 行新增和 0 行删除
@@ -2807,6 +2807,9 @@ helper dry-run -> actions=[] and safe target
- Required evidence fields: `stage`, `loginAttempts`, `loginHttpStatus`,
`sampleCategory`, `sampleCount`, `businessMutationCount`, and the relevant
endpoint-specific request count such as `terminatePostCount`.
- A finance smoke window additionally records `authorizationRef`, `accountAlias`,
`observedRoleCodes`, `disableReason`, `disableAuditRef` and `postDisableStatus`.
Use aliases and redacted references, never credentials or full identifiers.
### 3. Contracts
@@ -2834,10 +2837,60 @@ helper dry-run -> actions=[] and safe target
- Recheck any state-based rollback window before and after the browser run.
Missing samples and a still-open window remain independent facts.
#### Finance-role acceptance checklist
1. Resolve exactly one configured OA-only finance smoke in the isolated test
department. Before login, read its `status`, `employment_status`,
`archived_at`, `last_working_date`, lock state and effective role grants.
Require exactly `employee + finance`, with no extra roles or wildcard grant.
The database uses `status=archived` for disabled accounts; employees have no
`left_at` field. A disabled account is a blocked acceptance prerequisite,
not permission to weaken the login guard.
2. Obtain explicit authorization for the complete enable -> acceptance ->
disable window before any account write. Record the operator alias, purpose,
deadline and abort/cleanup responsibility. Re-read status and role grants
after enabling. Neither an earlier window nor an unexpectedly active account
grants permission for a new window or permanent activation.
3. Run the approved checks as that finance actor. Administrator results prove
only administrator behavior: wildcard privileges cannot establish finance
visibility, projections or action boundaries. A different read-only actor
likewise cannot replace exact finance-role acceptance. Stop at the precise
failed stage; do not replace the actor and mark the finance criterion PASS.
4. Immediately disable the smoke through the approved account-management path
when checks finish or abort. Read back `status=archived`, non-null
`archived_at` and target session revocation, and link the disable audit event.
A failed cleanup or missing verification leaves the window unclosed and must
be handed off explicitly; it is not a successful closeout. Do not submit an
extra login merely to prove that disabling worked.
- Record a concrete disable reason, such as `finance_acceptance_complete` or
`finance_acceptance_aborted`, linked to the authorization and disable event.
Current `server/src/routes/users.js` writes `SYSTEM_USER_DISABLED` with
`extra: {}`: audit-native reason persistence is **not implemented**. Until a
separately approved code change adds it, retain the reason in controlled
acceptance evidence linked to the audit reference, operator alias and event
time. Do not claim the audit row contains a reason, invent historical reasons,
or directly patch audit rows to satisfy this checklist.
- Do not treat a permanently active read-only finance account as an account-only
shortcut. Current grants are fixed by `RoleCode`/`EmployeeRole` and
`resolvePermissionsForRoles`, not arbitrary per-account permission strings;
there is no finance-read-only role, and `employee` itself includes writes.
Both payment candidates and combination readiness require
`payment.batch.manage`; `expense.view_all` alone cannot cover them. A future
read/write permission split needs separate approval and projection/denial
verification. Read-only access still exposes confidential financial data and
is not a zero-risk standing identity.
### 4. Validation & Error Matrix
- Login fails once -> stop with the authentication stage and re-read lock/failure
state; no second login.
- Finance smoke is disabled -> record the prerequisite as
`PAUSED(finance_account_disabled)`; finance-role acceptance remains unverified.
If login was attempted, distinguish `403/AUTH_003` at `/api/auth/login` from
`403/PERM_001` at a later protected endpoint; never infer the layer from 403 alone.
- Disable reason, linked audit reference or post-disable state proof is missing
-> acceptance-window closeout is incomplete, even when all UI checks passed.
- Login succeeds but the required sample count is zero -> authentication PASS,
sample-dependent UI checks `PAUSED`, mutation counters must remain zero.
- Runner label differs from the current shared product mapping -> runner
@@ -2875,6 +2928,9 @@ helper dry-run -> actions=[] and safe target
and mutation listeners installed before the first application navigation.
- Evidence review must reconcile login attempts with session/audit changes and
reconcile every unexecuted UI assertion with its sample count and stage.
- For a finance window, verify the unique actor and exact grants before login,
and the reason/audit linkage, disabled state and session revocation afterward.
Administrator or alternative-role checks must not satisfy finance-role criteria.
- Production execution still requires explicit approval, pre/post rollback
window snapshots, sensitive-content scanning and a read-only reviewer.
@@ -162,3 +162,14 @@
- 所有公网探针仅输出状态码、原因码和布尔断言;未保存 token、真实银行资料、原始业务响应或包含真实业务内容的截图。临时浏览器均已关闭。
- AC12 已凭上述真实负向证据勾选。0014 仍需业务人员补所属公司、确认真实开户行并录入真实资料;非建行停止,不得伪填。合同只读超时仍为未归因事项,由 `shunli` 在下次合同域验证前安排独立复现并归类,不计入本轮通过,不以本次发布关闭。
- 本 task 发布验收完成,未获归档授权,保留 `in_progress` 和现有目录;Trellis 升级继续留在独立 worktree,未审、未提交、未部署。
## 12. 用户复核后的交接与待规划事项(2026-09-05)
- 用户确认部署后复核 PASS:线上 `/ready=a83791263833`,复核时工作区干净且 HEAD 与 origin/main 一致。
- 公司使用事实:用户明确本系统仅供本公司内部使用。付款主体字段用于确定对公付款账户归属,不等同于为外部公司提供多租户服务;是否存在多个付款主体不能仅由“内部使用”推导,后续方案以用户确认的单主体业务事实及有效配置为准。
- 待规划建议(未批准实施):单公司模式下,在主体归属唯一且有效时自动采用默认主体,保留现有账户归属结构;没有有效主体、多主体或员工已有显式归属冲突时不得猜测、覆盖或按首条记录取值。员工创建时赋值与付款时解析默认值是不同的数据合同,须先选定方案;付款事实加载、账户查询、候选/组合/事务须保持一致,不能只在页面隐藏缺项或只消除 blocker。当前付款路径仍读取员工的主体归属,尚未实现此建议;未全面审计所有员工写入入口,不宣称“全系统没有自动赋值”。
- 该建议可与单主体体验盘点一起收集,但不作为统一待办实现的前置条件或顺带改动;成本中心、单据分类仅列为待核查项,未确认其冗余,也不删除或擅自隐藏。
- 0014 当前仍由授权业务人员按顺序补所属公司、向本人确认真实开户行及卡号并直接录入系统;资料不发聊天,非建行停止,不伪填。完成后由业务人员走创建并提交复核、经理/CEO 复核、财务登记付款。本会话不执行这些真实业务动作。
- 下一项统一待办需求仅以该真实流程的三个交接观察为输入:交给财务组批、交给经理/CEO 复核、交回财务登记付款;每处记录谁交给谁、接收人通过什么现有入口或提醒知道轮到自己、是否需要口头催办。尚未发生的交接不预填结论,不记录真实银行资料。
- 独立待办仍保留:财务测试账号 403 需要单独解决并补财务身份真实验收(管理员代验不等于该角色验收);合同只读超时需单独复现归因,不计入通过;“三张单的答复”仅作为用户提醒保留,未明确具体单据和答复内容,不自行推断或代答。
- Trellis 升级另行审查:逐条核对 workflow.md 与 project-governance.md 删除或弱化的规则及理由,独立检查 hooks 行为变化;不以模型升级为整批删除保障的理由。本次仅记录后续事项,不启动新产品任务、不修改配置或真实资料、不自动提交、部署或归档。