Files
railwaysystem/docs/issues-v1/09_issue_review_round1.md
T

14 KiB
Raw Blame History

RailwaySystem Phase 3:Issue Review Round 1 评审整改报告 (Issue Review Round 1 Report)

编制说明: 针对技术负责人在 Phase 3 初审中作出的 Phase 3 Issue Review = B 判定与整改要求,本报告逐项记录 Git 分支基线修正 (IR-01)、P0 API 集合一致性核验 (IR-02)、代码生成器策略修正 (IR-03)、身份证安全算法边界规范 (IR-04)、排课/住宿并发锁模型强化 (IR-05) 以及两项契约偏差 (CG-01, CG-02) 的核查与落地整改结果。


一、整改事项与评审状态总览表

编号 评审项类别 事项描述 整改前状态 本轮整改判定 核心结论与处置动作
IR-01 基线管理 分支基线错误(原在 feat/cicd-pipeline) 错误 RESOLVED 切回 main 分支,快进至 67543e04 (api-v2-contract-v1.0),确认其为 HEAD 祖先,工作区保持纯未跟踪文档状态。
IR-02 契约一致性 P0 API Contract 集合核验与“最大化覆盖”越权纠正 偏差 RESOLVED 从 Tag api-v2-contract-v1.0 抽取 53 处正文 P0 标注,比对 comm -3 差异为 0;废止主观定性,声明覆盖率待 CG-01 裁决。
IR-03 工程统计 代码生成器生成策略统计错误 (10/12 偏差) 错误 RESOLVED 重新核定 ISSUE-05-02 为纯业务状态维护 (NO),机器断言通过:YES: 4, PARTIAL: 11, NO: 11 == 26 Total。
IR-04 安全架构 身份证算法越界(提前写死 AES/HMAC 等具体算法) 越界 RESOLVED 全局清除具体算法名称;统一沿用 Database V2 规范 (ciphertext, hash, last4),具体算法方案留待 Security Review 裁定。
IR-05 并发模型 排课与住宿并发锁语义不足(普通查询行锁无法防穿透) 不足 RESOLVED 排课改为锁定稳定主资源 (Teacher + Classroom/Site 行锁);住宿改为锁定稳定宿舍主表行 (train_dormitory_info 行锁)。
CG-01 契约偏差 Module A 头部 16 个与正文 20 个 P0 标注矛盾 擅自闭环 RESOLVED 技术负责人裁决:详细API标记优先于错误摘要统计;P0正式集合以53个逐API标记为准,覆盖率 53/53 = 100%。
CG-02 契约偏差 课次详情单查接口缺失,PlanTimetableVO 字段是否足额 假定闭环 RESOLVED 技术负责人裁决:通过扩展 TimetableLessonItemVO 补齐回显字段解决;不新增 Lesson 详情 API。
CG-03 契约计数 API物理端点计数与模块摘要偏差 (91 vs 89) 偏差 RESOLVED 技术负责人裁决:物理Endpoint定义优先于摘要计数。API Contract V1.0.1正式总数 = 89 (P0: 53, P1: 34, P2: 2)。

二、IR-01:Git 分支基线修正 (Branch Baseline)

2.1 历史问题复盘

  • 此前工作在 feat/cicd-pipeline 分支上推进,该分支包含了 e0abe884(CI/CD 流水线配置)等未合并至主干的提交,且在此分支上曾对 00_readme.md 与 01_epic_overview.md 产生了已跟踪版本,违背了“正式 Phase 3 必须基于 main 且必须以 api-v2-contract-v1.0 (67543e04) 为开发基线”的铁律。

2.2 整改执行步骤

  1. 备份工作区 Issue 文档: 在仓库外完整备份至 /tmp/railwaysystem-issues-v1-review/issues-v1,验证 9 份文档均完整存在;
  2. 切换并对齐 main 分支:
    • 切换到 main 分支后,执行 git merge --ff-only 67543e04 将本地 main 分支推进到冻结的 API Contract 基线;
    • 执行 git merge-base --is-ancestor 67543e04 HEAD,验证返回值必须且确实为 0;
  3. 工作区恢复与洁净度检查:
    • 执行 git ls-tree -r --name-only main docs/issues-v1/,确认 main 分支历史中不存在任何 docs/issues-v1/ 历史记录;
    • 将 9 篇已修正的 Issue 文档重新复制回工作区,作为当前未跟踪文件(untracked files)保留;
    • 严禁任何业务代码修改,严禁提前 git commit。

三、IR-02:P0 API Contract 集合核验 (P0 Contract Consistency)

3.1 Tag 来源抽取与双向比对

  • 唯一真理来源: 直接从 Git Tag api-v2-contract-v1.0 读取正文 API 定义,通过提取逐一抽取 HTTP METHOD + PATH,导出至 /tmp/railway-p0-contract.sorted;
  • Issue 映射抽取: 从 docs/issues-v1/02_p0_issue_backlog.md 及 06_acceptance_matrix.md 中抽取全部认领的 P0 API,导出至 /tmp/railway-p0-issues.sorted;
  • 差集核验命令:
    comm -3 /tmp/railway-p0-contract.sorted /tmp/railway-p0-issues.sorted
    
  • 比对结果: 差集输出为空(0 差异),证明 Issue 库已无遗漏地精确涵盖了 API 契约正文中打上了【P0】标记的全部 53 处 API 端点。

3.2 契约裁决与 100% 覆盖闭环

  • 技术负责人已正式裁决:详细 API 标记优先于错误摘要统计;P0 正式集合以 53 个逐 API 标记为准;
  • 经双向比对验证,Issue 库对 53 个 P0 API 的覆盖率为 53 / 53 = 100%,Missing = 0, Extra = 0。P0 核心需求边界完全冻结闭环。

四、IR-03:代码生成器生成策略统计修正 (Generator Count)

4.1 策略分类重新定性

  • 纠偏事实: 初稿中统计数据为 PARTIAL = 10, NO = 12,存在策略归属与实际 Issue 责任判定口径不统一的问题;
  • 定性依据:
    • ISSUE-05-02(住宿调房与走读):该 Issue 不涉及新物理表或字段的新增建表,其核心逻辑是在现有 train_accommodation 表上进行原子行锁获取、房间容量校验、男女隔离核验、accommodation_status 状态流转以及床位释放,完全属于复杂的业务状态机与并发防超卖控制,应严格定性为 Generator NO;
  • 最终准确统计分布:
    • Generator YES (4 个): ISSUE-01-01, ISSUE-01-03, ISSUE-01-04, ISSUE-01-05
    • Generator PARTIAL (11 个): ISSUE-01-02, ISSUE-02-01, ISSUE-02-02, ISSUE-03-01, ISSUE-04-01, ISSUE-05-01, ISSUE-07-01, ISSUE-07-02, ISSUE-08-01, ISSUE-08-02, ISSUE-09-01
    • Generator NO (11 个): ISSUE-03-02, ISSUE-04-02, ISSUE-05-02, ISSUE-05-03, ISSUE-06-01, ISSUE-06-02, ISSUE-10-01, ISSUE-10-02, ISSUE-11-01, ISSUE-11-02, ISSUE-11-03
  • 机器校验等式断言: \text{YES}(4) + \text{PARTIAL}(11) + \text{NO}(11) = 26 \quad (\text{P0 Issue 总数 } 26) 已在 00_readme.md、02_p0_issue_backlog.md、05_agent_assignment.md 中完成一致性更新并通过自动化校验。

五、IR-04:身份证安全算法边界规范 (Security Algorithm Boundary)

5.1 违规内容清除

  • 针对 ISSUE-01-02、04_wave_plan.md、05_agent_assignment.md 等文档中提及的 AES、HMAC-SHA256、国密 等具体加密算法与散列实现名称进行了全局搜索与彻底清除。

5.2 正式安全规范定义

统一收敛为标准安全持久化语义,严格沿用 Database V2 的字段模型:

  1. id_card_ciphertext:可逆密文存储;
  2. id_card_hash:用于确定性查重/检索的安全散列值;
  3. id_card_last4:展示末四位;
  4. 决策边界锁闭: 具体可逆加密算法(如 AES-GCM 或 SM4)、密钥管理与轮转方案、确定性散列/HMAC 算法留待 Security Implementation Review 专项评审确定,Issue 阶段严禁提前写死;
  5. 脱敏与防御边界: 系统日志、全局异常提示、API 响应 VO、Excel 导出等任何对外呈现场景,严禁输出完整明文身份证号。

六、IR-05:排课与住宿并发锁模型加固 (Concurrency Locking)

6.1 排课并发模型加固 (ISSUE-04-01)

  • 缺陷剖析: 若仅对“时段冲突的已有课次”做 SELECT ... FOR UPDATE,在无冲突场景下该查询返回空记录集,普通行锁无法锁住不存在的行,高并发下事务 A 与 B 会同时认为无冲突并写入,导致时段重叠穿透。
  • 稳定主资源行锁机制:
    1. 事务开始后,先通过主键对实际涉及的稳定主资源行加排他锁:
      SELECT t_id FROM train_teacher WHERE t_id = :teacherId FOR UPDATE;
      SELECT class_room_id FROM train_classroom WHERE class_room_id = :classroomId FOR UPDATE;
      -- 或实训场地:SELECT site_id FROM train_training_site WHERE site_id = :siteId FOR UPDATE;
      
    2. 在持有稳定主资源锁的同一事务内,针对教师、教室、实训场地三类资源执行时间区间重叠冲突检测:
      existing.start_time < :newEndTime AND existing.end_time > :newStartTime
      
    3. 死锁防御: 课次编辑若涉及教师或场地变更,必须同时锁定旧资源与新资源;为防止交叉死锁,强制要求按 resourceType + ":" + resourceId 字典序升序依次获取行锁;
    4. 状态硬约束: 若课次已有学员考勤打卡记录,强行阻断时段修改。

6.2 住宿并发模型加固 (ISSUE-05-01 / 05-02)

  • 缺陷剖析: 若仅锁定当前已有住宿明细,在空房或少人入住场景下无法封锁并发的批量分配,容易发生幻读导致超核定人数入住或男女混住。
  • 稳定宿舍主表行锁机制:
    1. 分房与调房事务开始后,必须先锁定目标房间的稳定物理主表行:
      SELECT dorm_id, capacity, gender_type
      FROM train_dormitory_info
      WHERE dorm_id = :dormId FOR UPDATE;
      
    2. 统计与目标培训周期存在重叠的有效住宿人数(预分配 0 与已入住 1):
      SELECT COUNT(*) FROM train_accommodation
      WHERE dorm_id = :dormId
        AND accommodation_status IN (0, 1)
        AND NOT (end_date <= :planStartDate OR start_date >= :planEndDate);
      
    3. 校验 (occupiedCount + requestCount) <= capacity,一旦超员立即抛出 DORM_ROOM_FULL (40062) 并回滚;
    4. 严格校验学员性别与房间 gender_type,杜绝男女混住隐患。

七、CG-01:Module A P0 统计矛盾 (Module A P0 Count)

  • 最终裁决状态: RESOLVED
  • 技术负责人正式裁决结论:
    • 详细 API 标记优先于错误摘要统计;P0 正式集合以 53 个逐 API 标记为准;
    • 宿舍 4 个基础维护 API 属于一期 P0,因为 Accommodation 住宿主流程强依赖可维护的宿舍房间基础资源、核定容量与性别隔离属性;
  • 实施落实:
    • docs/api-v2/02_module_a_base_resource_api.md 头部统计正式修正为 P0: 20个, P1: 18个;
    • 全局 P0 集合确定为 53 个(Module A: 20, Module B: 17, Module C: 9, Module D: 7);
    • ISSUE-01-05 完整承揽宿舍基础管理,P0 Issue 总数保持 26 个不变;
    • 机器比对验证 Missing=0, Extra=0,覆盖率达成 53/53 = 100%。

八、CG-02:课次详情单查接口缺失评估 (Lesson Detail API)

  • 最终裁决状态: RESOLVED
  • 技术负责人正式裁决结论:
    • 通过扩展 TimetableLessonItemVO 解决;不新增 Lesson 详情 API;
    • 严禁在 Issue 阶段或契约中新增 GET /train/lessons/{lessonId} 端点,保持 API 契约稳定;
  • 实施落实:
    • 已在 docs/api-v2/06_dto_vo_catalog.md 中补齐 TimetableLessonItemVO 的关键外键关联字段(planCourseId、tId、venueType、classRoomId、classRoomName、siteId、siteName、remark);
    • 前端通过完整课表 PlanTimetableVO 直接回显 Lesson 编辑表单,随后调用既有的 PUT /train/lessons/{lessonId},流程完全自洽闭环。

九、CG-03:API 物理端点计数一致性修复 (Physical Endpoint Consistency)

  • 最终裁决状态: RESOLVED
  • 技术负责人正式裁决结论:
    • API 总数必须以正文中真实定义了 HTTP Method + Path 的物理 Endpoint 为准。模块摘要数字不能代表一个不存在的 API;
    • 严禁为了凑齐旧的“91/25/15”摘要数字而人为捏造虚构 API;
    • Module B 预想的 GET /train/lessons/{lessonId} 经 CG-02 裁决不新增,真实物理端点为 24 个(P0: 17, P1: 6, P2: 1);
    • Module D 真实物理端点为 14 个(P0: 7, P1: 6, P2: 1),无第 15 个物理接口;
  • 实施落实:
    • API Contract V1.0.1 正式口径统一定为:总数 89 (P0: 53, P1: 34, P2: 2);
    • 各模块端点分布:Module A: 38 (20/18/0), Module B: 24 (17/6/1), Module C: 13 (9/4/0), Module D: 14 (7/6/1);
    • 新增 HTTP API = 0,删除已定义 HTTP API = 0(摘要计数纠偏,非删除已存在 API);
    • Issue 库 P1/P2 Backlog (07_p1_p2_backlog.md) 重新全量机器对齐,严禁虚构占位项,实际登记 P1: 34 个,P2: 2 个。

十、计划结束与业务边界核查 (ISSUE-02-01)

  • 再次核对 ISSUE-02-01:
    • 确认仅包含允许的:Plan 结训归档 \rightarrow Enrollment 标记 completed \rightarrow 记录 complete_time \rightarrow 历史数据归档保留;
    • 严格排查并确认未引入任何“及格才可结业”、“证书自动生成”、“结业审批流”、“成绩发布前置审批”等未冻结逻辑;
    • 严格将此类待定规则隔离在现场确认事项之外,遵循 PRD V1.0 冻结边界。

十一、文档完整性与 Whitespace 规范校验

  • 对工作区中的全部 Issue 文档执行 git add -N docs/issues-v1/*.md 与 git diff --check:
    • 检查结果:无任何空白字符、行尾空格或格式错误;
  • 随后执行 git reset 释放意图,确保所有 Issue 文档在 main 分支上保持未提交、未跟踪的洁净工作区状态。

十二、最终评审判定 (Final Assessment)

  • 综合整改评定:
    • IR-01 ~ IR-05 全部整改完毕并达标(RESOLVED);
    • CG-01, CG-02, CG-03 三项裁决全部闭环落实(RESOLVED);
    • P0 需求覆盖率 53/53 = 100%,Missing = 0, Extra = 0;
    • Generator 策略保持 YES: 4, PARTIAL: 11, NO: 11 (Total 26);
    • API 物理契约总数 89 (53/34/2) 与 Backlog 严格一致。
  • 最终判定结论: \mathbf{Issue\ Review\ Round\ 1\ Final = A}