# 实施计划 ## 1. Schema 与迁移 - [x] 在 `ContractRegistry` 增加 `terminated_at/reason/by`、terminator 关系,在 `Employee` 增加反向关系。 - [x] `terminated_reason` 限制 1000,`terminated_by` 使用 `onDelete: Restrict`;按查询需要添加索引。 - [x] 生成纯增量 migration,检查只有可空列、外键/索引,无历史回填、drop 或状态改写。 - [x] 运行 `cd server && npm run prisma:format && npm run prisma:validate && npm run prisma:generate`。 ## 2. 状态与服务端不变量 - [x] 持久/筛选状态加入 `terminated`,一般 create/PATCH 可写状态仍排除 terminated。 - [x] 增加 terminated 筛选、effective status、expiring 排除和 renew 拒绝测试。 - [x] 增加详情 GET,按列表相同范围查询 owner/project/terminator/document refs,并投影安全 history。 - [x] 增加专用 terminate schema 和接口,reason trim 后 10–1000。 - [x] 终止 transaction 原子写三字段、status 和 required audit;模拟 audit failure 证明全回滚。 - [x] 阻止 archived/terminated 普通字段覆盖与终止绕过;导入脚本也拒绝终止状态和覆盖既有终止合同。 - [x] 归档/恢复改为 required audit;实现归档后追加修正记录,不覆盖主合同;修正使用 `updated_at` 乐观保护。 - [x] 保持续约 active/expired 语义和事务审计,并覆盖续约审计失败回滚。 ## 3. 客户端 API 与状态映射 - [x] 客户端合同类型加入 `terminated` 与三个终止字段、terminator、document refs、history DTO。 - [x] `contractStatusLabel` 增加“已终止”,未知兜底为“未知状态”而非原值。 - [x] 增加 fetch detail、terminate、correction 等必要 API 函数,不暴露 raw audit/document path。 ## 4. 列表、详情和表单 - [x] 合同列表移除内联 editor,仅保留筛选、提醒、导出、状态和查看详情。 - [x] 新建合同详情路由和页面元数据,权限 guard 与现有列表一致。 - [x] 建设状态/下一步、摘要、证据区、历史和动作面板;窄屏复用共享底部动作容器,并隐藏 PC 管理动作。 - [x] 证据区展示归档位置、离线档案号、涉密资料索引和强制引导文案;不显示空附件区或附件完整性列。 - [x] 迁移编辑、续约、归档/恢复;按动作矩阵隐藏或禁用。 - [x] 终止输入持续显示至少 10 字要求;禁用时显示原因;确认包含合同编号、相对方、金额和后果。 - [x] 归档后只提供授权修正追加入口,不覆盖普通字段。 - [x] 只展示真实 project 摘要与跳转;采购/付款无稳定关联时不渲染。 ## 5. 后端与迁移验证 - [x] `cd server && node --check src/routes/contractsRegistry.js`(并检查 `src/scripts/import-project-ledgers.js`)。 - [x] `cd server && npm test -- tests/unit/routes/contractsRegistry.test.js tests/unit/routes/exports.contractsRegistry.test.js tests/unit/scripts/import-project-ledgers.test.js --run`:25 passed。 - [x] `cd server && npm run prisma:validate`。 - [x] `cd server && npx prisma migrate status`(只读;不得未经批准 deploy/reset):65 migrations,`Database schema is up to date!`。 - [x] 检查生成 migration SQL 和既有数据兼容,记录应用回滚前/后首次终止写入的不同边界。 ## 6. 前端与交互验证 - [x] `cd client && npm run typecheck`。 - [x] `cd client && npm run build`。 - [x] 增加合同详情聚焦 Playwright:列表进入、深链刷新、无权限/不存在、dirty guard、涉密引导、无附件区。 - [x] 覆盖终止原因不足、确认摘要、成功状态、重复终止、审计失败和窄屏动作安全区;合同详情 + Wave3 共 12 passed。 - [x] 覆盖归档锁定、修正追加、恢复、续约和未知状态兜底。 ## 7. 只读 Review 与治理 - [x] 实施完成后启动只读 reviewer,按 design 第 9 节逐项审查,明确 reviewer 不改代码;首轮 finding 已记录并修复。 - [x] 主会话修复 finding 后重新运行聚焦测试并请求只读复查;最终结论 `PASS`。 - [x] 运行 task validate、process contract、docs registry、Trellis governance、敏感内容检查和 `git diff --check`。 - [x] 将终态字段、required audit、导入写路径和修正乐观保护沉淀到 `.trellis/spec/hyb-oa/backend-fastify-prisma.md`,不新建平行文档。 ## 8. 提交、部署与回滚 - [x] 使用中文 commit message 并引用 `08-05-contract-detail-workspace`。 - [ ] 本地实现提交不等于批准生产 migration 或部署。 - [ ] 生产发布另行获批后,显式验证 migration status、`/ready`、合同详情和权限负向路径。 - [ ] 首次生产终止写入前保留应用回滚窗口;产生 terminated 行后优先 roll-forward,不自动 drop 列或回退到不识别 terminated 的旧应用。 ## 实施证据与边界(2026-08-07) - migration SQL 为三个可空列、一个 `Restrict` 外键和索引;未执行生产 migration、reset、db push、resolve 或手工 DDL。 - 只读迁移原始结论:`Datasource=hyb_oa_regression at localhost:5432`;`65 migrations found`;`Database schema is up to date!`。 - 合同聚焦后端 25/25 passed;合同详情与受影响 Wave3 Playwright 12/12 passed;client typecheck/build、Prisma validate、node syntax、task/process/governance/sensitive/flow/route-manifest gates 均通过。 - 仓库全量 Vitest 结果为 179 个文件(177 passed、2 failed)、1248 个测试(1245 passed、3 failed);失败仅为既有付款批次/BIFF8 模板环境问题(`paymentBatches.reimbursement.test.js` 1 条、`paymentOrderXls.test.js` 2 条),不属于本合同任务改动,未通过改页面或数据库掩盖。 - 本地 `127.0.0.1:3000/ready` 返回 200;企业微信真机、生产/公网部署仍未验证,不能据此宣称用户可测试。 - 首轮只读 reviewer 结论为 `PASS_WITH_FINDINGS`;主会话修复并补测后,最终只读复查结论为 `PASS`,reviewer 未修改代码、未写数据库。