记录 36b949ec 门禁与发布结果(09-17-company-loan-principal-repayment)

- 正式门禁 PASS:84 迁移、服务端 4670 通过/1 跳过、浏览器 372 全过
- 发布窗口重复组合 0 组;按唯一待执行迁移部署,未做快照
- 构建阶段 SSH 断开但远端完成;部署后 pending=none、唯一索引存在、公网构建号一致
- AC59 勾选;登录后线上冒烟未做

Co-Authored-By: Claude Opus 5.5 <[email protected]>
这个提交包含在:
2026-10-11 14:41:47 +08:00
共同撰写人 Claude Opus 5.5
父节点 36b949ecf6
当前提交 3a4a5969bb
共修改 2 个文件,包含 15 行新增和 3 行删除
@@ -1,4 +1,16 @@
## 2026-10-11 F:员工与公司组合唯一约束——实施(用户已批准;未提交)
## 2026-10-11 `36b949ec` 已发布(含迁移 84;未做快照)
用户授权提交、推送并部署,明确不做快照。部署前生产只读核对:重复组合仍为 0 组(出借人 1 条),13 项部署前检查通过;发布来源检查要求候选已推送且工作区干净,故先暂存本记录、以 HEAD=`36b949ec` 推送(`4a5cd8f2..36b949ec`)和部署,部署后再提交记录(提交记录会改变 HEAD、使门禁回执不再匹配)。
- 部署:`EXPECTED_PENDING_MIGRATIONS=20261011010000_loan_lender_employee_unique`;生产迁移对账 `pending=` 正好该迁移,回滚窗口 OPEN。构建 init 镜像阶段 SSH 被远端关闭,本地脚本以 `DEPLOY_EXISTING_FAILED` 退出 1;远端部署继续完成,未重试部署。
- 部署后只读核对:迁移完成且未回滚,已应用迁移 84;唯一索引 `loan_lenders_legal_entity_id_employee_id_key` 存在;服务端容器 `BUILD_SHA=36b949ec…`;补跑只读 preflight `pending=none`,13 项 PASS。公网 `/ready` 200 且 `buildSha=36b949ecf6a3`,首页 200、前端包含同一构建号;`/login` 以浏览器 `Accept: text/html` 访问 200(无该头时为接口 404,属路由设计)。
- 日志 `artifacts/qa-flow/loan-lender-employee-unique-20261011/deploy-36b949ec.log`、`postdeploy-36b949ec.log`。本次未做登录后线上冒烟;借款新行为需随 N5/N6 真实办理或另行授权的线上冒烟验收。
## 2026-10-11 发布候选 `36b949ec` 正式门禁 PASS
用户授权开始门禁。干净工作区、独占浏览器副本运行 `verify-candidate`:84 个迁移全部应用;服务端 230 文件 4670 通过/1 项既有跳过,另 2 文件 74 通过;本地浏览器 372 全部通过(27.1 分钟),零失败;离线 `release-gate-result.mjs require` 通过,`status=PASS`、`deploymentEligible=true`。回执 `artifacts/release-gate/release-36b949ec-20261011/`,日志 `artifacts/qa-flow/loan-lender-employee-unique-20261011/gate-36b949ec.log`;浏览器副本已删除。候选包含 `91fe31f0`、`3c5cc544`、`36b949ec` 三处线上行为变化,待执行迁移仅 `20261011010000_loan_lender_employee_unique`。推送、部署、发布窗口 AC59 重复计数与生产只读核对均待另行授权;快照由用户决定。
## 2026-10-11 F:员工与公司组合唯一约束——实施(用户已批准;已本地提交 `36b949ec`)
- 迁移 `20261011010000_loan_lender_employee_unique`(迁移总数 83→84):`CREATE UNIQUE INDEX "loan_lenders_legal_entity_id_employee_id_key" ON loan_lenders(legal_entity_id, employee_id)`;Prisma `@@unique([legal_entity_id, employee_id])`。普通唯一约束,归档行计入、空 `employee_id` 互不冲突,与现行代码规则一致;不改数据、不回填。
- 冲突提示:新增 `isEmployeeLenderUniqueViolation`(同时识别 `meta.target` 与驱动适配器的约束字段/名称)。从员工创建路径先判它再判请求键重复;旧“确认出借人身份”入口在事务外映射。触到约束时返回原有 409 `loan.employee_lender_conflict`,不报 500,也不误报为 `loan.duplicate_registration`。原员工行锁与代码检查保持不变。
@@ -1,13 +1,13 @@
# 公司借款台账与本金归还
## 2026-10-11 F:员工与公司组合数据库唯一约束(已实施、本地验证与只读复核完成;未提交)
## 2026-10-11 F:员工与公司组合数据库唯一约束(已发布 `36b949ec`)
生产只读排查重复组合为 0 组后,用户批准把“同一公司与员工最多一个出借人(归档计入)”落到数据库。结果见 implement 顶部 F 节。
- [x] AC56:数据库拒绝同一公司与员工的第二个出借人,含归档行;空员工的手工出借人可多条共存。
- [x] AC57:应用触到约束时返回原有“出借人冲突”提示,不报 500、不误报请求重复;代码检查与员工行锁保持。
- [x] AC58:借款完整回归通过,并经独立只读复核(涉及迁移)。两轮完整回归各 84 迁移、12 阶段、去重 247 项通过;另一会话只读复核无阻断项、20 个内存探针通过,唯一 P2(缺本迁移回退说明)已在下方补齐。
- [ ] AC59:发布窗口重跑存量重复计数为 0,并按 1 个待执行迁移部署。
- [x] AC59:发布窗口重跑存量重复计数为 0,并按 1 个待执行迁移部署(2026-10-11:重复 0 组;迁移对账仅该迁移,部署后 pending=none、唯一索引存在)。
### 迁移回退说明(`20261011010000_loan_lender_employee_unique`)