docs(issues): 冻结一期P0 Epic与Issue Backlog V1.0

This commit is contained in:
wangzhibiao committed 2026-09-14 10:07:14 +08:00
1 parent 4873e5f555
commit 7fcaea29b8
10 files changed
+2448

No files matched your search

+121
View File
@@ -0,0 +1,121 @@
# RailwaySystem Phase 3:P0 Epic / Issue 任务拆分总纲
> **阶段状态:** Phase 3 任务分解完成稿 (正式基线)
> **业务最高基线:** `doc/RailwaySystem 智慧培训系统一期 PRD V1.0.md`
> **数据库基线:** `db-v2-migration-passed-20260914` (21张表 KingbaseES 物理迁移验证通过)
> **代码生成器基线:** `generator-v2-ready-20260914` (Kingbase 只读验证通过)
> **API 契约基线:** `api-v2-contract-v1.0.1` (89 个物理 API 端点,P0: 53, P1: 34, P2: 2)
> **审查基线:** `docs/issues-v1/09_issue_review_round1.md` (Review Round 1 Final = A)
> **实施策略:** 严格以 PRD V1.0 业务闭环为主线,以 Database V2 为持久化底座,聚焦 P0 最小闭环。
---
## 1. 拆分目标与核心原则
本阶段旨在将 `api-v2-contract-v1.0.1` 中的 **53 个 P0 API** 以及支撑业务运转的核心基础设施,转化为**可独立开发、可代码审查 (Review)、可自动化测试、可业务验收**的 Epic 与 Issue。
本阶段**严禁编写任何业务代码**,所有拆解严格以 `api-v2-contract-v1.0`(commit `67543e04`)及 V1.0.1 修订为基线展开。
### 1.1 核心原则与硬约束
1. **业务能力驱动,拒绝单表 CRUD:** 严禁以数据库物理表为单位拆分 Issue(如禁止设立“开发 train_lesson CRUD”),必须按“可独立交付与验收的业务动作/能力”进行拆分(如“实现课次排课与三类资源冲突检测”);
2. **只拆 P0,严格范围控制:**
- 锁定 53 个 P0 API 作为本轮研发唯一核心目标;
- 34 个 P1 辅助 API 与 2 个 P2 远期 API 仅在 [`07_p1_p2_backlog.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/07_p1_p2_backlog.md) 中登记备查,不计入开发排期。
3. **主数据最小必要集合原则:**
- 基础主数据不作为全量阻塞项,仅建设支撑主业务链路所必需的最小集合(Teacher, Student, Course, Classroom, TrainingSite, Dormitory)。
4. **不变量与并发控制强行绑定:**
- 5 大跨表业务硬不变量(INV-01 ~ INV-05)与 1 项报到生命周期策略,责任落实到唯一的责任 Issue;
- 排课并发冲突(教师/教室/场地/班级)与宿舍分配防超卖(行锁 `SELECT FOR UPDATE` + 性别隔离),必须在 Issue 中明确 SQL 与锁策略。
5. **外部对接 Mock 优先与事务轻量解耦:**
- 外部硬件系统(班牌、门禁、VR/3D)一期一律采用 SPI + Mock 桩实现,严禁引入 MQ、Kafka、RabbitMQ、Outbox 等重型中间件;
- 外部调用一律置于数据库本地事务之外,通过事务提交后(`afterCommit`)轻量解耦触发,外部失败绝不回滚已提交的业务数据,支持手动重试。
---
## 2. 主链路业务开发优先级
系统的所有 Issue 依赖与开发批次(Wave),均严格围绕以下**最短业务闭环主链路**展开推进:
```mermaid
flowchart TD
M1[基础数据: 教师 / 学员 / 课程 / 空间] --> M2[创建培训计划 Plan]
M2 --> M3[配置本期课程 PlanCourse]
M3 --> M4[添加参训名单 Enrollment]
M4 --> M5[课次排课与冲突检测 Lesson]
M5 --> M6[聚合生成完整课表 Timetable]
M4 --> M7[住宿批量预分配 Accommodation]
M7 --> M8[学员报到确认 Report]
M5 --> M9[电子班牌打卡考勤 Attendance]
M8 --> M9
M9 --> M10[成绩项目与打分台账 Score]
M4 --> M11[外部实训记录接入 StudyRecord]
M10 --> M12[培训综合统计与工作台 Statistics/Workbench]
M11 --> M12
M12 --> M13[结束培训计划 Complete Plan]
style M1 fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
style M2 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style M4 fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style M5 fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style M7 fill:#e0f2f1,stroke:#00796b,stroke-width:2px
style M9 fill:#fbe9e7,stroke:#d84315,stroke-width:2px
style M10 fill:#fffde7,stroke:#fbc02d,stroke-width:2px
style M13 fill:#ede7f6,stroke:#512da8,stroke-width:2px
```
---
## 3. 全局核心统计指标
经严密分解与审查,Phase 3 输出的核心统计指标如下:
| 统计维度 | 指标数值 | 备注说明 |
|:---|:---|:---|
| **Epic 总数** | **12 个** | 覆盖主数据、核心计划、排课、住宿、门禁、考勤、成绩、学习、统计、权限字典与端到端验收 |
| **P0 Issue 总数** | **26 个** | 每个 Issue 为 0.5~2 个开发日的独立可验收业务能力 |
| **P0 API 覆盖率** | **53 / 53 (100%)** | 契约逐条提取 53 个 P0 API 全量映射闭环,无遗漏无多余 |
| **Contract Gap 状态** | **CG-01: RESOLVED<br/>CG-02: RESOLVED** | CG-01 采纳 53 个逐 API 正式口径;CG-02 扩展 VO 回显字段闭环 |
| **开发 Wave 数量** | **8 个** | Wave 0 (准备) ~ Wave 7 (验收),层层递进 |
| **首批可立即开发 Issue** | **8 个** | Wave 0 (3个) + Wave 1 中不依赖 Plan 的基础数据 (5个) |
| **必须等待 Module B 的 Issue** | **13 个** | 涵盖排课、住宿分配、报到、考勤、成绩配置/录入、学习记录、工作台与端到端验收 |
| **Generator 策略分布** | **YES: 4, PARTIAL: 11, NO: 11** | 机器校验:4 + 11 + 11 = 26 (符合 P0 Issue 总数 26) |
| **Recommended Agent 分工** | **Gemini: 11, Codex: 15** | Gemini 负责基础 CRUD/VO/权限字典;Codex 负责高并发锁/复杂事务/不变量/端到端 |
---
## 4. 契约偏差审查与裁决落地 (Contract Gap Analysis)
在对齐 `api-v2-contract-v1.0` 与 Issue 拆分过程中登记的 2 项契约偏差,技术负责人已作出正式裁决并全部闭环:
### 4.1 CG-01:Module A P0 统计数字与逐 API 标注矛盾【状态:RESOLVED】
- **裁决结论:** **详细 API 标记优先于错误摘要统计;P0 正式集合以 53 个逐 API 标记为准。**
- **落地执行:**
- 宿舍 4 个基础维护 API(列表、详情、新增、选项)属于一期 P0,因为 Accommodation 住宿主流程强依赖可维护的宿舍房间基础资源、核定容量与性别隔离属性;
- Module A P0 确认为 20 个,全局 P0 集合确定为 53 个(Module A: 20, Module B: 17, Module C: 9, Module D: 7);
- 由 `ISSUE-01-05` 完整承揽,P0 覆盖率正式达成 **53/53 (100%)**。
### 4.2 CG-02:课次编辑所需字段与单查接口缺失【状态:RESOLVED】
- **裁决结论:** **通过扩展 TimetableLessonItemVO 解决;不新增 Lesson 详情 API。**
- **落地执行:**
- 严禁在 Issue 阶段或契约中新增 `GET /train/lessons/{lessonId}` 端点,保持 API Contract 接口数量稳定;
- 在 `docs/api-v2/06_dto_vo_catalog.md` 中补齐 `TimetableLessonItemVO` 的关键外键关联字段(`planCourseId`、`tId`、`venueType`、`classRoomId`、`classRoomName`、`siteId`、`siteName`、`remark`);
- 前端通过完整课表 `PlanTimetableVO` 直接回显 Lesson 编辑表单,随后调用既有的 `PUT /train/lessons/{lessonId}`,流程完全自洽闭环。
---
## 5. 文档索引导航 (docs/issues-v1/)
本套 Issue 任务分解规范包含以下 10 篇文档:
| 序号 | 文档名称 | 核心内容 |
|:---|:---|:---|
| 00 | [`00_readme.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/00_readme.md) | 阶段总纲、最高原则、主链路、统计总览、Contract Gap 分析与文档索引 |
| 01 | [`01_epic_overview.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/01_epic_overview.md) | 12 个业务 Epic 概览、目标、业务边界与包含的 Issue 对应清单 |
| 02 | [`02_p0_issue_backlog.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/02_p0_issue_backlog.md) | 26 个 P0 Issue 详细技术卡片(严格包含 22 项技术定义与 Given/When/Then 验收准则) |
| 03 | [`03_dependency_graph.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/03_dependency_graph.md) | Mermaid DAG 依赖图,清晰展示串行依赖与并行泳道 |
| 04 | [`04_wave_plan.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/04_wave_plan.md) | Wave 0 ~ Wave 7 开发推进批次计划、进入条件、产出目标与退出准则 |
| 05 | [`05_agent_assignment.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/05_agent_assignment.md) | Gemini Flash 与 Codex 研发分工建议及 Generator (YES/PARTIAL/NO) 执行策略 |
| 06 | [`06_acceptance_matrix.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/06_acceptance_matrix.md) | 全链路追踪矩阵 (UC → API → Issue → Test) 及 5 大 Invariant / 1 项生命周期策略归属矩阵 |
| 07 | [`07_p1_p2_backlog.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/07_p1_p2_backlog.md) | 34 个 P1 辅助 API 与 2 个 P2 远期 API 的统一登记与后续演进规划 |
| 08 | [`08_risk_register.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/08_risk_register.md) | 技术风险登记册、稳定资源锁策略、外部 Mock 隔离与 CG-01 裁决辅助表 |
| 09 | [`09_issue_review_round1.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/09_issue_review_round1.md) | Phase 3 Issue Review Round 1 审查整改记录与结论报告 |
+235
View File
@@ -0,0 +1,235 @@
# RailwaySystem Phase 3:Epic 架构概览 (Epic Overview)
> **设计基线:** 紧扣 PRD V1.0 业务闭环与 API Contract V1.0,严禁按 21 张数据库表机械建 Epic。
> **Epic 规划原则:** 每一个 Epic 代表一个**高内聚、有明确业务价值、对主链路有明确支撑的业务能力域**。
---
## 1. Epic 汇总视图
系统一期 P0 研发共划分为 **12 个核心 Epic**,覆盖从基础设施、主数据、开班排课、过程执行、效果评估到端到端验收的完整闭环:
```mermaid
flowchart TB
subgraph CoreBase["支撑基线与基础数据"]
E11[EPIC-11 权限/字典/系统基线]
E01[EPIC-01 基础主数据必要集合]
E06[EPIC-06 门禁与外部设备Mock]
end
subgraph PlanCore["开班与排课核心"]
E02[EPIC-02 培训计划与本期课程]
E03[EPIC-03 参训人员管理]
E04[EPIC-04 排课与课表管理]
end
subgraph Execution["过程执行支撑"]
E05[EPIC-05 住宿与报到管理]
E07[EPIC-07 课次考勤管理]
E09[EPIC-09 外部学习记录接入]
end
subgraph Assessment["效果评估与结训"]
E08[EPIC-08 成绩项目与成绩台账]
E10[EPIC-10 计划统计与综合工作台]
end
subgraph Acceptance["端到端验收"]
E12[EPIC-12 P0端到端业务闭环验收]
end
E11 --> E01
E06 --> E05
E06 --> E07
E06 --> E09
E01 --> E02
E02 --> E03
E02 --> E04
E03 --> E05
E04 --> E07
E05 --> E07
E07 --> E08
E03 --> E09
E08 --> E10
E07 --> E10
E02 --> E10
E10 --> E12
style CoreBase fill:#f5f5f5,stroke:#9e9e9e,stroke-width:1px
style PlanCore fill:#e8f5e9,stroke:#4caf50,stroke-width:1px
style Execution fill:#e1f5fe,stroke:#03a9f4,stroke-width:1px
style Assessment fill:#fff8e1,stroke:#ffc107,stroke-width:1px
style Acceptance fill:#fce4ec,stroke:#e91e63,stroke-width:2px
```
---
## 2. Epic 详细定义
### EPIC-01 基础主数据必要集合 (Base Master Data)
- **Epic ID:** `EPIC-01`
- **业务目标:** 为整个智慧培训业务链路提供最小必需的师资、人员、课程、教室、场地和宿舍主数据底座,支撑后续计划选课、排课冲突校验与住宿分配。
- **包含 P0 Issue:**
- `ISSUE-01-01`: 师资主数据管理能力 (Teacher CRUD)
- `ISSUE-01-02`: 学员主档建档与安全脱敏管理 (Student Security & Masking)
- `ISSUE-01-03`: 课程库基础资料管理 (Course Base CRUD)
- `ISSUE-01-04`: 教学空间资源维护(普通教室与实训场地) (Classroom & Site)
- `ISSUE-01-05`: 宿舍房间与楼宇基础数据维护 (Dormitory Info & Cascading Options)
- **对应 P0 API:**
- `GET /train/teacher/list`, `GET /train/teacher/{tId}`, `POST /train/teacher`, `PUT /train/teacher/{tId}`
- `GET /train/student/list`, `GET /train/student/{sId}`, `POST /train/student`
- `GET /train/course/list`, `GET /train/course/{cId}`, `POST /train/course`
- `GET /train/classroom/list`, `GET /train/classroom/{classRoomId}`, `POST /train/classroom`
- `GET /train/training-site/list`, `GET /train/training-site/{siteId}`, `POST /train/training-site`
- `GET /train/dormitory/list`, `GET /train/dormitory/{dormId}`, `POST /train/dormitory`, `GET /train/dormitory/options`
- **涉及数据表:** `train_teacher`, `train_student`, `train_course`, `train_classroom`, `train_training_site`, `train_dormitory_info`
- **明确不做什么:** 不做教师资质多版本审批、不做学员主档多机构合并、不做课程版本流转、不做独立教学资源管理与班牌注册管理(属于 P1)。
---
### EPIC-02 培训计划与本期课程 (Plan & Plan-Course)
- **Epic ID:** `EPIC-02`
- **业务目标:** 实现培训班级项目的立项、编辑、周期维护与结训归档,并支撑本期教学课程的选定与课时引入。
- **包含 P0 Issue:**
- `ISSUE-02-01`: 培训计划全生命周期创建与管理 (Plan Lifecycle)
- `ISSUE-02-02`: 本期培训课程引入与配置 (Plan-Course Mapping)
- **对应 P0 API:**
- `GET /train/plans`, `POST /train/plans`, `GET /train/plans/{planId}`, `PUT /train/plans/{planId}`, `POST /train/plans/{planId}/complete`
- `GET /train/plans/{planId}/courses`, `POST /train/plans/{planId}/courses`
- **涉及数据表:** `train_class_plan`, `train_plan_course`
- **明确不做什么:** 不做多级立项审批流;一期结训不设考核不及格阻断结业的强制卡点(Review Round 1 明确剔除)。
---
### EPIC-03 参训人员管理 (Enrollment Lifecycle)
- **Epic ID:** `EPIC-03`
- **业务目标:** 建立特定培训计划与学员的强业务绑定关系(形成 `enrollment_id`),支持单名录入与 Excel 批量解析导入,提供参训全景档案查询。
- **包含 P0 Issue:**
- `ISSUE-03-01`: 本期参训名单维护与单条录入 (Enrollment Core & Detail)
- `ISSUE-03-02`: 参训人员 Excel 批量导入与防重校验 (Batch Enrollment Import)
- **对应 P0 API:**
- `GET /train/plans/{planId}/enrollments`, `POST /train/plans/{planId}/enrollments`, `GET /train/enrollments/{enrollmentId}`
- `POST /train/plans/{planId}/enrollments/batch`
- **涉及数据表:** `train_enrollment`, `train_student`
- **明确不做什么:** 不做复杂的退宿连带手续审批(仅做参训状态变更);批量导入错误行不引入异步消息通知,直接返回同步解析结果列表。
---
### EPIC-04 排课与课表管理 (Scheduling & Timetable)
- **Epic ID:** `EPIC-04`
- **业务目标:** 支撑培训班课程的教学时段排定,实现教师、普通教室、实训场地、班级时段四维冲突检测与数据库行级排他锁保护,聚合生成本班完整课程表。
- **包含 P0 Issue:**
- `ISSUE-04-01`: 课次编排与多维度排课并发冲突检测 (Lesson Scheduling & Conflict Lock)
- `ISSUE-04-02`: 培训计划完整课程表聚合展示 (Plan Timetable Aggregation)
- **对应 P0 API:**
- `POST /train/plans/{planId}/lessons`, `PUT /train/lessons/{lessonId}`, `POST /train/lessons/check-conflict`
- `GET /train/plans/{planId}/timetable`
- **涉及数据表:** `train_lesson`, `train_plan_course`, `train_teacher`, `train_classroom`, `train_training_site`
- **明确不做什么:** 不做遗传算法自动智能排课;不做复杂的周循环与双周排课规则;教师个人课表属于 P1。
---
### EPIC-05 住宿与报到管理 (Accommodation & Report)
- **Epic ID:** `EPIC-05`
- **业务目标:** 管理学员参训期间的生活保障与入班核验,包含批量智能预分房(严格按性别隔离与行锁防超卖)、单人调房、走读设定,以及学员现场报到与生命周期时限告警控制。
- **包含 P0 Issue:**
- `ISSUE-05-01`: 批量住宿智能预分配与防超卖控制 (Batch Accommodation Allocation)
- `ISSUE-05-02`: 住宿人工调房、走读设置与住宿安排查看 (Accommodation Adjustment & Roster)
- `ISSUE-05-03`: 学员报到确认与生命周期时限控制 (Student Report & Lifecycle Policy)
- **对应 P0 API:**
- `POST /train/plans/{planId}/accommodations/preallocate`
- `PUT /train/enrollments/{enrollmentId}/accommodation`, `PUT /train/enrollments/{enrollmentId}/accommodation/day-student`, `GET /train/plans/{planId}/accommodations`
- `POST /train/enrollments/{enrollmentId}/report`
- **涉及数据表:** `train_accommodation`, `train_report_record`, `train_dormitory_info`, `train_enrollment`
- **明确不做什么:** 不做水电费计量结算;房态实时网格看板属于 P1;报到逾期不做硬阻断数据库约束,采用弹性时限告警策略。
---
### EPIC-06 门禁与外部设备Mock (Device Integration & Mock)
- **Epic ID:** `EPIC-06`
- **业务目标:** 建立防腐适配器体系 (SPI),提供电子班牌人脸考勤、智能门禁授权、外部 VR/3D 学习记录对接的 Mock 实现与测试桩,并通过事务提交后(`afterCommit`)轻量解耦触发门禁同步,支持失败重试。
- **包含 P0 Issue:**
- `ISSUE-06-01`: 外部设备适配器 SPI 体系与 Mock 桩实现 (Adapter SPI & Mocks)
- `ISSUE-06-02`: 门禁授权事务后解耦下发与失败手工重试 (Door Auth After-Commit & Manual Retry)
- **对应 P0 API:**
- `POST /train/accommodations/{accommodationId}/auth/sync`
- **涉及数据表:** `train_dorm_auth`, `train_accommodation`, `train_student`
- **明确不做什么:** 严禁对接真实厂家硬件私有协议;严禁引入 MQ、Kafka、RabbitMQ、Outbox 等重型中间件;门禁授权下发流水查询属于 P1。
---
### EPIC-07 课次考勤管理 (Lesson Attendance)
- **Epic ID:** `EPIC-07`
- **业务目标:** 围绕具体课次 (`lesson_id`) 与参训档案 (`enrollment_id`) 开展出勤管理,支撑班牌刷脸打卡签到/签退、任课教师实时查看课次考勤明细,以及异常出勤的人工修正与留痕。
- **包含 P0 Issue:**
- `ISSUE-07-01`: 课次班牌打卡签到签退与跨班不变量防护 (Check-in/Check-out & Invariant INV-01)
- `ISSUE-07-02`: 课次考勤名单查看与人工考勤状态修正 (Lesson Attendance Roster & Manual Rectification)
- **对应 P0 API:**
- `POST /train/attendance/sign-in`, `POST /train/attendance/sign-out`
- `GET /train/lessons/{lessonId}/attendance`, `PUT /train/attendance/{checkinId}`
- **涉及数据表:** `train_attendance_record`, `train_lesson`, `train_enrollment`
- **明确不做什么:** 不做基于 GPS 地理围栏的移动端打卡;人工补录未打卡记录属于 P1;不变量 INV-01(课次所属班级 == 学员参训班级)在此强制阻断。
---
### EPIC-08 成绩项目与成绩台账 (Score Management)
- **Epic ID:** `EPIC-08`
- **业务目标:** 实现培训班成绩考核科目与百分制权重配置,支持教师对单学员或批量录入成绩,强校验满分上限与跨班归属,生成全班加权综合得分台账大表与单人成绩单。
- **包含 P0 Issue:**
- `ISSUE-08-01`: 本期成绩考核项与权重配置 (Score Items & Weight Config, Invariant INV-04)
- `ISSUE-08-02`: 学员成绩录入、上限校验与全班成绩台账大表 (Score Entry, Matrix VO, Invariant INV-02 & INV-05)
- **对应 P0 API:**
- `GET /train/plans/{planId}/score-items`, `POST /train/plans/{planId}/score-items`
- `POST /train/scores/entry`, `GET /train/plans/{planId}/scores/matrix`, `GET /train/enrollments/{enrollmentId}/scores`
- **涉及数据表:** `train_score_item`, `train_student_score`, `train_enrollment`
- **明确不做什么:** 不做成绩发布审批流程;Excel 批量导入成绩属于 P1;严禁硬编码及格线与不合格阻断(仅计算 `weightedTotalScore`)。
---
### EPIC-09 外部学习记录接入 (External Learning Records)
- **Epic ID:** `EPIC-09`
- **业务目标:** 对接高铁驾驶模拟舱、VR 实训室、3D 拆装等外部专业设备推送的学习学时流水,提供防重复推送的唯一幂等处理与三态响应。
- **包含 P0 Issue:**
- `ISSUE-09-01`: 外部实训系统自主学习流水幂等接入 (Learning Record Ingestion & Invariant INV-03)
- **对应 P0 API:**
- `POST /train/study-records/receive`
- **涉及数据表:** `train_study_duration`, `train_enrollment`, `train_plan_course`
- **明确不做什么:** 不对接大文件视频播放断点与心跳上报;自主学习记录分页检索与单人流水详情属于 P1。
---
### EPIC-10 计划统计与综合工作台 (Plan Workbench & Statistics)
- **Epic ID:** `EPIC-10`
- **业务目标:** 为培训管理人员提供开班期间的“一站式计划综合工作台”与结训阶段的“计划综合统计概览”,聚合展示报到率、出勤率、课表进度、成绩分布与自主学时。
- **包含 P0 Issue:**
- `ISSUE-10-01`: 培训计划综合工作台聚合服务 (Plan Workbench Aggregation)
- `ISSUE-10-02`: 培训计划综合成效统计概览 (Plan Statistics Aggregation)
- **对应 P0 API:**
- `GET /train/plans/{planId}/workbench`
- `GET /train/plans/{planId}/statistics/overview`
- **涉及数据表:** 跨表只读聚合查询(`train_class_plan`, `train_enrollment`, `train_lesson`, `train_attendance_record`, `train_student_score`, `train_study_duration`)
- **明确不做什么:** 不做复杂的多维 OLAP 钻取报表;不引入 Elasticsearch / ClickHouse 等外部大数据分析引擎;多维度成绩下钻图表属于 P2。
---
### EPIC-11 权限字典与系统基线支撑 (RBAC, Dict & System Baseline)
- **Epic ID:** `EPIC-11`
- **业务目标:** 夯实系统运行底座,全面统一以 `train:*` 为前缀的 RBAC 菜单与按钮授权体系,规范化分类梳理 16 组培训业务字典,消除旧系统权限混乱扩散。
- **包含 P0 Issue:**
- `ISSUE-11-01`: RuoYi RBAC 权限体系与按钮授权集成 (RBAC Migration & Train Permissions)
- `ISSUE-11-02`: 培训业务数据字典与参数配置初始化方案 (Dictionary & SysConfig Strategy)
- **对应 P0 API:**
- 支撑全部 53 个 P0 API 的鉴权拦截与前端按钮 `v-hasPermi` 显隐控制。
- **涉及数据表:** `sys_menu`, `sys_role_menu`, `sys_dict_type`, `sys_dict_data`, `sys_config`
- **明确不做什么:** 本轮严禁执行 `007_dicts.sql` 物理入库;不做动态自定义数据权限过滤规则(一期采用基于角色的标准 RBAC)。
---
### EPIC-12 P0端到端业务闭环验收 (End-to-End Acceptance)
- **Epic ID:** `EPIC-12`
- **业务目标:** 串联 17 个 P0 核心用例(UC-01 ~ UC-29),构建完整的端到端自动化测试链路与基线集成回归用例,确保最小业务闭环能够流畅无缝运转。
- **包含 P0 Issue:**
- `ISSUE-12-01`: 智慧培训全生命周期主链路端到端集成测试与验收 (End-to-End Acceptance Suite)
- **对应 P0 API:**
- 贯穿覆盖全部 53 个 P0 API 的链路式调用与数据验证。
- **业务价值:** 彻底杜绝“各个单接口测试通过,连起来无法走通完整培训班”的集成陷阱,作为 Phase 3 研发交付的最终质量闸门。
File diff suppressed because it is too large. Load diff
+176
View File
@@ -0,0 +1,176 @@
# RailwaySystem Phase 3:Issue 依赖关系有向无环图 (Dependency DAG)
> **设计目标:** 明确各 Issue 之间的前后置依赖关系,清晰识别哪些任务必须串行推进、哪些任务可以无阻塞并行开发,指导团队实现资源利用率最大化。
---
## 1. Issue 全景依赖拓扑图 (Mermaid DAG)
```mermaid
flowchart TB
subgraph Wave0["Wave 0:基线支撑 (可立即无前置并行启动)"]
I1101["ISSUE-11-01<br/>RBAC权限体系"]
I1102["ISSUE-11-02<br/>字典配置方案"]
I0601["ISSUE-06-01<br/>外部Adapter SPI与Mock"]
end
subgraph Wave1["Wave 1:基础主数据与计划立项 (可立即并行启动)"]
I0101["ISSUE-01-01<br/>教师主数据"]
I0102["ISSUE-01-02<br/>学员主档与脱敏"]
I0103["ISSUE-01-03<br/>课程库资料"]
I0104["ISSUE-01-04<br/>空间资源:教室与场地"]
I0105["ISSUE-01-05<br/>宿舍房间与楼宇"]
I0201["ISSUE-02-01<br/>培训计划全生命周期"]
end
subgraph Wave2["Wave 2:计划配课、参训与排课"]
I0202["ISSUE-02-02<br/>本期课程引入"]
I0301["ISSUE-03-01<br/>本期参训名单维护"]
I0302["ISSUE-03-02<br/>名单Excel批量导入"]
I0401["ISSUE-04-01<br/>排课与四维冲突排他锁"]
I0402["ISSUE-04-02<br/>完整课表聚合VO"]
end
subgraph Wave3["Wave 3:住宿、门禁与报到"]
I0501["ISSUE-05-01<br/>批量住宿预分配防超卖"]
I0502["ISSUE-05-02<br/>调房走读管理"]
I0602["ISSUE-06-02<br/>门禁afterCommit解耦同步"]
I0503["ISSUE-05-03<br/>学员报到与时限控制"]
end
subgraph Wave4["Wave 4:课次考勤"]
I0701["ISSUE-07-01<br/>课次打卡与INV-01"]
I0702["ISSUE-07-02<br/>考勤名单与人工修正"]
end
subgraph Wave5["Wave 5:成绩与学习记录"]
I0801["ISSUE-08-01<br/>成绩项目配置与INV-04"]
I0802["ISSUE-08-02<br/>成绩录入台账INV-02/05"]
I0901["ISSUE-09-01<br/>学习记录接入与INV-03"]
end
subgraph Wave6["Wave 6:工作台与成效统计"]
I1001["ISSUE-10-01<br/>培训计划综合工作台"]
I1002["ISSUE-10-02<br/>计划成效统计概览"]
end
subgraph Wave7["Wave 7:全链路端到端验收"]
I1201["ISSUE-12-01<br/>P0主链路端到端集成验收"]
end
%% 跨模块依赖连线
I0103 --> I0202
I0201 --> I0202
I0102 --> I0301
I0201 --> I0301
I0301 --> I0302
I0202 --> I0401
I0101 --> I0401
I0104 --> I0401
I0401 --> I0402
I0301 --> I0501
I0105 --> I0501
I0501 --> I0502
I0501 --> I0602
I0601 --> I0602
I0301 --> I0503
I0401 --> I0701
I0301 --> I0701
I0503 --> I0701
I0701 --> I0702
I0202 --> I0801
I0801 --> I0802
I0301 --> I0802
I0301 --> I0901
I0202 --> I0901
I0601 --> I0901
I0201 --> I1001
I0301 --> I1001
I0401 --> I1001
I0503 --> I1001
I0503 --> I1002
I0701 --> I1002
I0802 --> I1002
I0901 --> I1002
I1001 --> I1201
I1002 --> I1201
I0702 --> I1201
I0502 --> I1201
I0602 --> I1201
style Wave0 fill:#f1f8e9,stroke:#8bc34a,stroke-width:1px
style Wave1 fill:#e0f7fa,stroke:#00bcd4,stroke-width:1px
style Wave2 fill:#e8eaf6,stroke:#3f51b5,stroke-width:1px
style Wave3 fill:#fce4ec,stroke:#e91e63,stroke-width:1px
style Wave4 fill:#fff3e0,stroke:#ff9800,stroke-width:1px
style Wave5 fill:#ede7f6,stroke:#673ab7,stroke-width:1px
style Wave6 fill:#f3e5f5,stroke:#9c27b0,stroke-width:1px
style Wave7 fill:#ffebee,stroke:#f44336,stroke-width:2px
```
---
## 2. 串行依赖关键路径 (Critical Path)
系统的**最短端到端主链路关键路径**(耗时最长、环环相扣的核心串行线)如下:
$$\begin{aligned}
\text{ISSUE-01-03 (课程库)} &\longrightarrow \text{ISSUE-02-01 (创建计划)} \\
&\longrightarrow \text{ISSUE-02-02 (配置本期课程)} \\
&\longrightarrow \text{ISSUE-04-01 (课次排课与冲突锁)} \\
&\longrightarrow \text{ISSUE-07-01 (课次考勤打卡)} \\
&\longrightarrow \text{ISSUE-10-02 (计划综合统计)} \\
&\longrightarrow \text{ISSUE-12-01 (端到端验收)}
\end{aligned}$$
同时并行的辅关键路径为参训与住宿线:
$$\text{ISSUE-01-02 (学员)} \longrightarrow \text{ISSUE-03-01 (名单)} \longrightarrow \text{ISSUE-05-01 (住宿)} \longrightarrow \text{ISSUE-05-03 (报到)} \longrightarrow \text{ISSUE-07-01 (考勤)}$$
---
## 3. 并行开发泳道分析
通过上述 DAG,可以清晰划分出以下 4 条高并发研发泳道:
### 泳道 A:基础设施与主数据泳道 (可完全自由推进)
- `ISSUE-11-01` (RBAC权限)
- `ISSUE-11-02` (字典配置方案)
- `ISSUE-06-01` (外部 Adapter SPI & Mock)
- `ISSUE-01-01` (教师主数据)
- `ISSUE-01-02` (学员主档与脱敏)
- `ISSUE-01-03` (课程库)
- `ISSUE-01-04` (教学空间资源)
- `ISSUE-01-05` (宿舍基础房间)
> **特征:** 相互之间完全解耦,可由多位开发者或 Gemini Flash 代理人并行同时开工,0 依赖等待。
### 泳道 B:排课教学线 (依赖课程与计划)
- `ISSUE-02-01` (计划立项)
- `ISSUE-02-02` (本期课程)
- `ISSUE-04-01` (排课与排他锁)
- `ISSUE-04-02` (完整课表聚合)
> **特征:** 教师与教室准备完毕后,沿开班排课主干顺畅推进。
### 泳道 C:学员生活与报到线 (依赖名单与宿舍)
- `ISSUE-03-01` (名单与档案)
- `ISSUE-03-02` (Excel批量导入)
- `ISSUE-05-01` (住宿智能预分配)
- `ISSUE-05-02` (调房与走读)
- `ISSUE-06-02` (门禁异步下发重试)
- `ISSUE-05-03` (学员报到确认)
> **特征:** 围绕 `enrollment_id` 展开,不依赖具体课次,主要管理学员个人生活保障。
### 泳道 D:成效考核与外部数据接入线
- `ISSUE-08-01` (成绩科目与权重)
- `ISSUE-08-02` (成绩录入与台账矩阵大表)
- `ISSUE-09-01` (外部自主学习记录接入)
> **特征:** 在学员名单和本期课程确定后即可独立推进,与排课考勤互不干扰。
+149
View File
@@ -0,0 +1,149 @@
# RailwaySystem Phase 3:开发批次计划 (Wave Plan)
> **规划目标:** 按照依赖关系与业务闭环推进节奏,将 26 个 P0 Issue 分解为 8 个开发批次(Wave 0 ~ Wave 7),实现敏捷迭代、敏捷交付、敏捷验收。
---
## 1. Wave 推进总览表
| 批次 | 阶段主题 | 核心 Issue 清单 | 预估人日 | 前置准入条件 | 核心产出物 |
|:---|:---|:---|:---|:---|:---|
| **Wave 0** | **工程基线与外部准备** | `ISSUE-11-01`, `ISSUE-11-02`, `ISSUE-06-01` | 2.5 人日 | Phase 3 方案审查通过 | 权限常量基线、字典分类方案、Adapter SPI 及 Mock 桩 |
| **Wave 1** | **基础主数据与计划立项** | `ISSUE-01-01`, `ISSUE-01-02`, `ISSUE-01-03`, `ISSUE-01-04`, `ISSUE-01-05`, `ISSUE-02-01` | 6.0 人日 | Wave 0 权限与工程准备就绪 | 教师/学员/课程/教室/场地/宿舍基础档案、培训计划立项与生命周期 |
| **Wave 2** | **计划配课、参训与排课** | `ISSUE-02-02`, `ISSUE-03-01`, `ISSUE-03-02`, `ISSUE-04-01`, `ISSUE-04-02` | 7.0 人日 | Wave 1 主数据与计划完成 | 本期课程引入、参训名单(含Excel导入)、排课并发四维冲突锁、完整课程表 |
| **Wave 3** | **住宿分配、门禁与报到** | `ISSUE-05-01`, `ISSUE-05-02`, `ISSUE-06-02`, `ISSUE-05-03` | 5.5 人日 | Wave 2 参训名单与 Wave 0 SPI 完成 | 批量住宿智能分配防超卖、调房走读、门禁事务外下发与重试、学员报到时限控制 |
| **Wave 4** | **课次打卡考勤与修正** | `ISSUE-07-01`, `ISSUE-07-02` | 3.0 人日 | Wave 2 排课与 Wave 3 报到完成 | 班牌刷脸签到/签退、INV-01 跨班防护、课次考勤花名册、人工修正留痕 |
| **Wave 5** | **成绩科目、台账与学习记录** | `ISSUE-08-01`, `ISSUE-08-02`, `ISSUE-09-01` | 5.0 人日 | Wave 2 配课与参训名单完成 | 成绩项目权重 100% 校验(INV-04)、成绩录入上限(INV-05)与跨班(INV-02)校验、全班成绩台账大表、外部学习记录幂等三态接入(INV-03) |
| **Wave 6** | **综合工作台与成效统计** | `ISSUE-10-01`, `ISSUE-10-02` | 3.0 人日 | Wave 2~Wave 5 业务数据链路通畅 | 培训计划一站式驾驶舱 (PlanWorkbenchVO)、培训成效统计概览 (PlanStatisticsVO) |
| **Wave 7** | **P0 端到端联调与闭环验收** | `ISSUE-12-01` | 2.5 人日 | Wave 0 ~ Wave 6 全部 Issue 完成 | 17 个 P0 核心用例自动化串联测试、业务全生命周期闭环准入测试报告 |
---
## 2. 各 Wave 详尽实施方案
### Wave 0:工程基线与外部准备 (Wave 0 - Baseline & Adapters)
- **目标:** 统一全系统的 RBAC 权限字符定义,梳理业务字典与系统配置归属,建立外部系统 Mock 桩,为后续各业务模块扫清底层支撑障碍。
- **包含 Issue:**
- `ISSUE-11-01`: RuoYi RBAC 权限体系与按钮授权集成 (Gemini Flash)
- `ISSUE-11-02`: 培训业务数据字典与参数配置初始化方案 (Gemini Flash)
- `ISSUE-06-01`: 外部设备适配器 SPI 体系与 Mock 桩实现 (Gemini Flash)
- **可并行 Issue:** 本 Wave 的 3 个 Issue 彼此完全独立,**可 100% 同步并行开发**。
- **进入条件:** Phase 3 文档技术审查完成。
- **退出准则:**
- 权限字符统一收敛至 `train:*` 前缀;
- 字典分类方案清晰无歧义,静态字典与业务数据彻底隔离;
- 3 大外部 SPI 接口及其 Mock 实现类完成并注入 Spring 上下文。
---
### Wave 1:基础主数据与计划立项 (Wave 1 - Master Data & Plan Creation)
- **目标:** 完成教师、学员(含脱敏与加密)、课程库、空间场地、宿舍基础房间维护,并打通培训计划的基本立项与状态生命周期。
- **包含 Issue:**
- `ISSUE-01-01`: 师资主数据管理能力 (Gemini Flash)
- `ISSUE-01-02`: 学员主档建档与安全脱敏管理 (Codex)
- `ISSUE-01-03`: 课程库基础资料管理 (Gemini Flash)
- `ISSUE-01-04`: 教学空间资源维护(教室与实训场地) (Gemini Flash)
- `ISSUE-01-05`: 宿舍房间与楼宇基础数据维护 (Gemini Flash)
- `ISSUE-02-01`: 培训计划全生命周期创建与管理 (Codex)
- **可并行 Issue:** `ISSUE-01-01` ~ `ISSUE-01-05` 5 个主数据任务可完全并行;`ISSUE-02-01` 可同步启动。
- **进入条件:** Wave 0 权限与字典基准确定。
- **退出准则:**
- 各主数据表单能正常录入与检索;
- 学员身份证号落库已使用安全散列查重且密文存储,查询列表脱敏,日志无明文;
- 培训计划能成功创建、编辑和执行结训状态流转。
---
### Wave 2:计划配课、参训与排课 (Wave 2 - Plan Configuration & Scheduling)
- **目标:** 围绕培训计划开展本期选课、学员进班(支持单增与 Excel 批量导入)、课次排课及稳定主资源行级排他锁冲突检测,生成完整课程表。
- **包含 Issue:**
- `ISSUE-02-02`: 本期培训课程引入与配置 (Gemini Flash)
- `ISSUE-03-01`: 本期参训名单维护与单条录入 (Codex)
- `ISSUE-03-02`: 参训人员 Excel 批量导入与防重校验 (Codex)
- `ISSUE-04-01`: 课次编排与多维度排课并发冲突检测 (Codex)
- `ISSUE-04-02`: 培训计划完整课程表聚合展示 (Gemini Flash)
- **可并行 Issue:**
- `ISSUE-02-02` (配课) 与 `ISSUE-03-01` (名单) 可并行推进;
- `ISSUE-03-02` 在 `ISSUE-03-01` 完成后推进;
- `ISSUE-04-01` 在 `ISSUE-02-02` 完成后推进;`ISSUE-04-02` 紧随其后。
- **进入条件:** Wave 1 基础主数据与培训计划立项完成。
- **退出准则:**
- 课程成功引入计划生成 `plan_course_id`;
- 学员成功入班生成 `enrollment_id`;
- Excel 批量导入支持容错并反馈错误行;
- 排课并发压测下杜绝教师/教室/场地/班级重叠穿透,完整课表 VO 正确呈现。
---
### Wave 3:住宿分配、门禁与报到 (Wave 3 - Accommodation, Door Auth & Report)
- **目标:** 解决学员现场报到与在校住宿生活保障,落实宿舍并发预分配防超卖、单人调房、走读退宿、门禁事务外解耦同步与失败重试,以及报到时限告警控制。
- **包含 Issue:**
- `ISSUE-05-01`: 批量住宿智能预分配与防超卖控制 (Codex)
- `ISSUE-05-02`: 住宿人工调房、走读设置与住宿安排查看 (Codex)
- `ISSUE-06-02`: 门禁授权事务后解耦下发与失败手工重试 (Codex)
- `ISSUE-05-03`: 学员报到确认与生命周期时限控制 (Codex)
- **可并行 Issue:**
- `ISSUE-05-01` (住宿分配) 与 `ISSUE-05-03` (报到确认) 均依赖名单,两者可完全并行开发;
- `ISSUE-05-02` 与 `ISSUE-06-02` 在 `ISSUE-05-01` 完成后开展。
- **进入条件:** Wave 2 参训名单已就绪、Wave 0 门禁 Mock 桩就绪。
- **退出准则:**
- 宿舍分配严格性别隔离,`SELECT FOR UPDATE` 彻底杜绝超卖;
- 门禁下发失败不回滚住宿事务,支持界面一键重试;
- 学员报到状态顺利流转,逾期报到准确提示并支持管理员强制放行。
---
### Wave 4:课次打卡考勤与修正 (Wave 4 - Attendance & Rectification)
- **目标:** 支撑教学过程中按课次组织的出勤打卡,落实 INV-01 跨班一致性硬校验,提供考勤名单实时查看与人工修正留痕。
- **包含 Issue:**
- `ISSUE-07-01`: 课次班牌打卡签到签退与跨班不变量防护 (Codex)
- `ISSUE-07-02`: 课次考勤名单查看与人工考勤状态修正 (Gemini Flash)
- **可并行 Issue:** `ISSUE-07-02` 依赖 `ISSUE-07-01`,为串行推进。
- **进入条件:** Wave 2 课次排课已完成、Wave 3 学员已完成报到。
- **退出准则:**
- 班牌签到/签退成功落库;
- **INV-01 跨班签到拦截测试 100% 阻断**;
- 人工修改考勤结论必须强制标记 `manual_flag = 1` 留痕。
---
### Wave 5:成绩科目、台账与学习记录 (Wave 5 - Assessment & Ingestion)
- **目标:** 完成本期考核科目与权重配置,支持成绩单条/批量录入,落实 INV-02、INV-04、INV-05,输出动态列成绩台账大表,并提供外部实训自主学习流水的三态幂等接入 (INV-03)。
- **包含 Issue:**
- `ISSUE-08-01`: 本期成绩考核项与权重配置 (Codex)
- `ISSUE-08-02`: 学员成绩录入、上限校验与全班成绩台账大表 (Codex)
- `ISSUE-09-01`: 外部实训系统自主学习流水幂等接入 (Codex)
- **可并行 Issue:**
- `ISSUE-08-01` (科目配置) 与 `ISSUE-09-01` (学习记录) 可并行开发;
- `ISSUE-08-02` 在 `ISSUE-08-01` 完成后推进。
- **进入条件:** Wave 2 课程配置与参训名单已就绪。
- **退出准则:**
- 成绩项目总权重严格校验 100% (INV-04);
- 打分录入严格限制在 `[0, fullScore]` 内 (INV-05) 且严禁跨班打分 (INV-02);
- 全班台账大表准确输出加权总分 `weightedTotalScore`,无及格线硬阻断;
- 外部学习记录实现 `accepted / duplicate / invalid` 三态幂等响应与跨班阻断 (INV-03)。
---
### Wave 6:综合工作台与成效统计 (Wave 6 - Workbench & Statistics)
- **目标:** 将前面各业务阶段汇聚沉淀的数据进行跨表只读聚合,输出培训计划综合工作台驾驶舱与全景成效统计概览。
- **包含 Issue:**
- `ISSUE-10-01`: 培训计划综合工作台聚合服务 (Gemini Flash)
- `ISSUE-10-02`: 培训计划综合成效统计概览 (Codex)
- **可并行 Issue:** `ISSUE-10-01` 与 `ISSUE-10-02` **可完全并行开发**。
- **进入条件:** 报到、考勤、成绩与学时业务链路皆已走通。
- **退出准则:**
- 工作台展示开班全景、今日课表与关键待办,响应时间 < 300ms;
- 统计概览计算报到率、出勤率、加权平均分与学时,安全防护除以零异常。
---
### Wave 7:P0 端到端联调与闭环验收 (Wave 7 - End-to-End Acceptance)
- **目标:** 串联 17 个 P0 核心用例(UC-01 ~ UC-29),构建端到端自动化测试流水线,作为 Phase 3 研发交付的最终质量关卡。
- **包含 Issue:**
- `ISSUE-12-01`: 智慧培训全生命周期主链路端到端集成测试与验收 (Codex)
- **进入条件:** Wave 0 ~ Wave 6 全部 25 个 Issue 开发完成并通过独立单测。
- **退出准则:**
- 自动化端到端测试用例 100% 绿灯通过;
- 5 大跨表硬不变量在链路测试中均通过破坏性用例校验;
- 生成最终《P0 业务主链路准入验收报告》。
+110
View File
@@ -0,0 +1,110 @@
# RailwaySystem Phase 3:研发分工与代码生成器策略 (Agent Assignment & Generator Strategy)
> **制定原则:** 最大化研发效能,合理配置 AI 算力与工程资源。
> **算力调度铁律:** **简单基础工作交由 Gemini Flash 高效完成,核心高难度/高并发/高风险架构工作保留给 Codex 集中攻坚,杜绝算力浪费。**
---
## 1. 代码生成器 (Generator V2) 实施策略
系统代码生成器已于 Phase 2 完成 KingbaseES 适配与基线冻结 (`generator-v2-ready-20260914`)。在 Phase 3 Issue 实施中,各 Issue 严格执行以下三级 Generator 策略:
```text
YES (4个 Issue) : 基础主数据单表,完全通过 Generator 快速生成 Entity、基础 Mapper XML 与基础 Service 骨架。
PARTIAL (11个 Issue) : 核心业务实体或敏感表,仅生成 Domain Entity 与基础 Mapper 骨架,Controller、DTO/VO、Application Service 业务编排必须严格按 API Contract 手写。
NO (11个 Issue) : 跨表聚合服务、并发锁算法、SPI防腐接口、系统权限字典方案、纯业务状态流转或端到端测试,严禁使用生成器代码。
```
### 1.1 Generator 策略明细矩阵
| Issue ID | Issue 名称 | Generator 策略 | 策略执行细则与约束 |
|:---|:---|:---:|:---|
| `ISSUE-01-01` | 师资主数据管理能力 | **YES** | 生成 `TrainTeacher` 实体、Mapper 与基础查询;在 Service 层补充手机号全局查重校验。 |
| `ISSUE-01-02` | 学员主档建档与安全脱敏管理 | **PARTIAL** | 生成 `TrainStudent` 实体骨架;**严禁生成明文落库代码**,手写安全散列查重与可逆密文存储逻辑。 |
| `ISSUE-01-03` | 课程库基础资料管理 | **YES** | 生成 `TrainCourse` 实体、Mapper 骨架;Service 层补充课程编码唯一性校验。 |
| `ISSUE-01-04` | 教学空间资源维护(教室与实训场地) | **YES** | 生成 `TrainClassroom` 与 `TrainTrainingSite` 单表骨架;补充容量大于零业务校验。 |
| `ISSUE-01-05` | 宿舍房间与楼宇基础数据维护 | **YES** | 生成 `TrainDormitoryInfo` 基础骨架;手写楼栋/楼层级联下拉树查询逻辑。 |
| `ISSUE-02-01` | 培训计划全生命周期创建与管理 | **PARTIAL** | 生成 `TrainClassPlan` 实体;**严禁使用生成器状态机**,手写状态流转校验与结训学员批量级联更新。 |
| `ISSUE-02-02` | 本期培训课程引入与配置 | **PARTIAL** | 生成 `TrainPlanCourse` 实体骨架;手写从课程库批量选课、防重与生成 `plan_course_id` 逻辑。 |
| `ISSUE-03-01` | 本期参训名单维护与单条录入 | **PARTIAL** | 生成 `TrainEnrollment` 实体;手写招生人数上限并发校验与 `enrollment_id` 核心上下文绑定。 |
| `ISSUE-03-02` | 参训人员 Excel 批量导入与防重校验 | **NO** | 纯业务批量事务与 EasyExcel 监听器,涉及多级错误行收集,全量手写。 |
| `ISSUE-04-01` | 课次编排与多维度排课并发冲突检测 | **PARTIAL** | 生成 `TrainLesson` 实体;**排课稳定主资源行锁 (FOR UPDATE) 与区间冲突算法必须纯手写**。 |
| `ISSUE-04-02` | 培训计划完整课程表聚合展示 | **NO** | 纯聚合只读服务,手写嵌套 `PlanTimetableVO` 结果集映射与周/日维度分组逻辑。 |
| `ISSUE-05-01` | 批量住宿智能预分配与防超卖控制 | **PARTIAL** | 生成 `TrainAccommodation` 实体;**严禁生成分房算法**,手写性别隔离、宿舍主表 `SELECT FOR UPDATE` 防超卖。 |
| `ISSUE-05-02` | 住宿人工调房、走读设置与住宿安排查看 | **NO** | 纯业务调房行锁、走读床位释放与状态流转,直接复用已有实体,严禁依赖生成器。 |
| `ISSUE-05-03` | 学员报到确认与生命周期时限控制 | **PARTIAL** | 生成 `TrainReportRecord` 实体;手写 `report_deadline` 策略核对、告警与强制放行逻辑。 |
| `ISSUE-06-01` | 外部设备适配器 SPI 体系与 Mock 桩实现 | **NO** | 纯架构防腐层设计,定义 3 大 SPI 接口及 Mock 实现类,手写。 |
| `ISSUE-06-02` | 门禁授权事务后解耦下发与失败手工重试 | **NO** | 涉及 Spring `afterCommit` 事务同步器注册与事务外解耦调用,手写。 |
| `ISSUE-07-01` | 课次班牌打卡签到签退与跨班不变量防护 | **PARTIAL** | 生成 `TrainAttendanceRecord` 实体;**硬不变量 INV-01 校验与幂等更新必须纯手写**。 |
| `ISSUE-07-02` | 课次考勤名单查看与人工考勤状态修正 | **PARTIAL** | 手写应到/实到花名册聚合左联 SQL、人工修正强制标记 `manual_flag = 1` 留痕。 |
| `ISSUE-08-01` | 本期成绩考核项与权重配置 | **PARTIAL** | 生成 `TrainScoreItem` 实体;手写总权重 100% 校验与硬不变量 INV-04 课程归属核验。 |
| `ISSUE-08-02` | 学员成绩录入、上限校验与全班成绩台账大表 | **NO** | 手写满分上限校验 (INV-05)、跨班阻断 (INV-02)、动态列行转列与加权总分计算。 |
| `ISSUE-09-01` | 外部实训系统自主学习流水幂等接入 | **PARTIAL** | 生成 `TrainStudyDuration` 实体;手写防重事件 ID 唯一性校验、三态响应与 INV-03 核查。 |
| `ISSUE-10-01` | 培训计划综合工作台聚合服务 | **NO** | 纯复杂 VO 聚合,跨 4 张表组装综合驾驶舱,手写。 |
| `ISSUE-10-02` | 培训计划综合成效统计概览 | **NO** | 纯跨模块业务指标聚合计算,含除零保护与四舍五入,手写。 |
| `ISSUE-11-01` | RuoYi RBAC 权限体系与按钮授权集成 | **NO** | 权限常量定义、`sys_menu` SQL 脚本方案与按钮权限梳理,纯系统基线工程。 |
| `ISSUE-11-02` | 培训业务数据字典与参数配置初始化方案 | **NO** | 16 组字典分类架构方案与静态字典初始化,纯数据架构分析。 |
| `ISSUE-12-01` | 智慧培训全生命周期主链路端到端集成测试与验收 | **NO** | 全链路自动化业务集成测试用例与验收套件,手写。 |
---
## 2. 研发智能体分配 (Gemini Flash vs Codex)
### 2.1 分配原则与算力调优
- **Gemini Flash (共 11 个 Issue):**
- 适用场景:单表结构化 CRUD、VO/DTO 定义、权限常量梳理、数据字典方案、简单 Vue 列表页、单元测试数据构建。
- 核心优势:响应极其敏捷、大上下文处理结构清晰、遵循规范精准。
- **Codex (共 15 个 Issue):**
- 适用场景:稳定主资源行排他锁 (`FOR UPDATE`)、防超卖算法、三类资源区间冲突查询、跨表强一致性硬不变量校验、事务提交后解耦、敏感数据安全脱敏、矩阵行转列与端到端验收。
- 核心优势:深度逻辑推理严密、并发锁死锁识别能力强、复杂领域模型抽象扎实。
### 2.2 详细分工清单
```mermaid
pie title Phase 3 Issue 研发分工比例 (总数 26)
"Gemini Flash (基础CRUD/聚合VO/基线)" : 11
"Codex (高并发锁/硬不变量/事务编排/验收)" : 15
```
| Issue ID | 推荐 Agent | 核心负责模块 / 任务边界 | 推荐理由与关键关注点 |
|:---|:---:|:---|:---|
| `ISSUE-11-01` | **Gemini Flash** | RBAC 权限体系与按钮授权 | 权限常量提取与标准 RuoYi 按钮匹配,规则明确标准。 |
| `ISSUE-11-02` | **Gemini Flash** | 字典分类方案梳理 | 评估 `007_dicts.sql` 语义,输出三类字典归属报告。 |
| `ISSUE-06-01` | **Gemini Flash** | 外部 Adapter SPI 与 Mock 桩 | 标准 Java Interface 与 Mock 类编写,快速高效。 |
| `ISSUE-01-01` | **Gemini Flash** | 教师主数据 CRUD | 标准单表管理,结构简单,适合快速落地。 |
| `ISSUE-01-02` | **Codex** | 学员主档脱敏与安全加密 | 涉及安全散列查重与可逆密文存储,需要严密的安全逻辑。 |
| `ISSUE-01-03` | **Gemini Flash** | 课程库基础资料管理 | 基础主档 CRUD,重点在于去除冗余版本字段。 |
| `ISSUE-01-04` | **Gemini Flash** | 教学空间资源维护 | 教室与场地标准数据维护,校验逻辑清晰。 |
| `ISSUE-01-05` | **Gemini Flash** | 宿舍房间与级联选项 | 楼栋/楼层级联树生成与基础房间录入。 |
| `ISSUE-02-01` | **Codex** | 培训计划生命周期管理 | 核心业务主干,涉及严格的时间校验与结训学员级联更新事务。 |
| `ISSUE-02-02` | **Gemini Flash** | 本期课程引入与配置 | 课程库与计划的关联,排重校验逻辑明确。 |
| `ISSUE-03-01` | **Codex** | 参训名单维护与单条录入 | 涉及 `enrollment_id` 核心领域标识生成与招生上限并发校验。 |
| `ISSUE-03-02` | **Codex** | Excel 批量导入与防重 | 大批量数据容错、身份证号校验、分批事务处理。 |
| `ISSUE-04-01` | **Codex** | 课次排课与稳定资源锁检测 | **高技术难度:** 必须使用教师/场地稳定行锁杜绝时段重叠穿透。 |
| `ISSUE-04-02` | **Gemini Flash** | 完整课表聚合展示 | 纯聚合查询,按日期嵌套展示课表,属于结构化组装。 |
| `ISSUE-05-01` | **Codex** | 批量住宿智能分配防超卖 | **高技术难度:** 锁定宿舍主表行 `SELECT FOR UPDATE` 彻底防并发超卖。 |
| `ISSUE-05-02` | **Codex** | 调房走读管理与锁控制 | 宿舍主表行锁核验容量与释放床位短事务,升序加锁防死锁。 |
| `ISSUE-05-03` | **Codex** | 学员报到与生命周期时限策略 | 涉及 `report_deadline` 弹性策略分支与管理员特批覆盖。 |
| `ISSUE-06-02` | **Codex** | 门禁 afterCommit 解耦下发 | **高架构要求:** 必须使用事务同步器解耦,外部失败严禁回滚。 |
| `ISSUE-07-01` | **Codex** | 课次打卡与 INV-01 防护 | **核心业务防线:** 强制校验学员班级与课次班级一致性。 |
| `ISSUE-07-02` | **Gemini Flash** | 考勤名单聚合与人工修正 | 课次应到实到名单左联与 `manual_flag = 1` 留痕。 |
| `ISSUE-08-01` | **Codex** | 成绩项目配置与 INV-04 | 权重严格总和 100% 校验与课程归属性校验。 |
| `ISSUE-08-02` | **Codex** | 成绩录入台账 INV-02/05 | **核心业务防线:** 满分上限校验、跨班打分阻断、加权总分计算。 |
| `ISSUE-09-01` | **Codex** | 外部学习记录接入与 INV-03 | **高可靠性要求:** 唯一事件 ID 查重三态幂等与跨班课程校验。 |
| `ISSUE-10-01` | **Gemini Flash** | 培训计划综合工作台 VO | 跨表只读数据组装,快速呈现大盘卡片与日程。 |
| `ISSUE-10-02` | **Codex** | 计划成效综合统计概览 | 报到率、出勤率、加权平均分多指标精准聚合与除零保护。 |
| `ISSUE-12-01` | **Codex** | P0 主链路端到端闭环验收 | **终极交付质量把关:** 串联 17 个 UC 完整业务流程验证。 |
---
## 3. 研发协同与代码审查 (Review) 规范
1. **并行开发阶段:**
- Gemini Flash 先行完成 Wave 0 与 Wave 1 中主数据部分 (`ISSUE-01-01`, `01-03`, `01-04`, `01-05`),为后续业务提供数据实体;
- Codex 同步启动 `ISSUE-01-02` (安全脱敏) 与 `ISSUE-02-01` (计划生命周期)。
2. **核心业务攻坚阶段 (Wave 2 ~ Wave 5):**
- Codex 集中精力攻克排课行锁 (`04-01`)、住宿防超卖 (`05-01`)、门禁解耦 (`06-02`) 以及 5 大硬不变量(INV-01 ~ INV-05);
- Gemini Flash 配合完成课表展示 (`04-02`)、配课 (`02-02`)、考勤名单 (`07-02`) 等 VO 聚合及前端视图。
3. **代码合并准入卡点:**
- 任何涉及并发锁与硬不变量的 Codex 产出代码,必须包含对应的多线程并发单元测试或破坏性断言用例;
- 任何 Gemini Flash 产出的代码,严禁私自修改数据库 DDL 与生成器全局模板。
+114
View File
@@ -0,0 +1,114 @@
# RailwaySystem Phase 3:端到端验收矩阵与追踪表 (Acceptance Matrix)
> **设计目标:** 建立从 PRD 业务用例 (UC) → API Contract → Issue → 后端组件 → 前端组件 → 权限字符 → 测试用例 → 验收准则的全链路双向追踪体系,确保 53 个 P0 API 100% 落实且每个硬业务规则有唯一责任人。
---
## 1. 5 大跨表硬业务不变量与 1 项报到生命周期策略责任归属矩阵
系统确立的 5 大跨表拓扑一致性“硬不变量”与 1 项生命周期时限策略,责任全部落实到具体的唯一主责 Issue:
| 编号 | 规则公式 / 核心定义 | 唯一主责 Issue | 主责 Application Service | 拦截错误码 | 破坏性测试用例 |
|:---:|:---|:---:|:---:|:---:|:---|
| **INV-01** | $\text{attendance.enrollment.plan\_id} == \text{lesson.planCourse.plan\_id}$<br/>*(严禁跨班打卡串签)* | `ISSUE-07-01` | `AttendanceAppService` | `ATTENDANCE_PLAN_MISMATCH (40080)` | `AttendanceInvariantTest.testCrossPlanCheckinBlocked` |
| **INV-02** | $\text{studentScore.enrollment.plan\_id} == \text{scoreItem.plan\_id}$<br/>*(严禁跨班打分录入)* | `ISSUE-08-02` | `ScoreAppService` | `SCORE_PLAN_MISMATCH (40093)` | `ScoreInvariantTest.testCrossPlanScoreEntryBlocked` |
| **INV-03** | $\text{study.enrollment.plan\_id} == \text{planCourse.plan\_id}$<br/>*(外部学习记录本期课程与班级一致)* | `ISSUE-09-01` | `LearningAppService` | `STUDY_EVENT_INVALID (40100)` | `LearningInvariantTest.testCrossPlanCourseStudyBlocked` |
| **INV-04** | $\text{scoreItem.planCourse.plan\_id} == \text{scoreItem.plan\_id}$<br/>*(考核科目挂接课程必须属于本期计划)* | `ISSUE-08-01` | `ScoreAppService` | `SCORE_ITEM_COURSE_MISMATCH (40091)` | `ScoreConfigInvariantTest.testExternalCourseBindingBlocked` |
| **INV-05** | $0 \le \text{studentScore.score} \le \text{scoreItem.full\_score}$<br/>*(录入分值非负且不得超过满分上限)* | `ISSUE-08-02` | `ScoreAppService` | `SCORE_EXCEEDS_FULL_SCORE (40092)` | `ScoreEntryValidationTest.testExceedFullScoreBlocked` |
| **POL-01** | $\text{report\_time} \le \text{plan.report\_deadline}$<br/>*(报到生命周期时限策略,支持告警与强制放行)* | `ISSUE-05-03` | `ReportAppService` | `REPORT_DEADLINE_WARNING (40051)` | `ReportLifecyclePolicyTest.testOverdueWarningAndOverride` |
---
## 2. 53 个 P0 API 全生命周期全链路追踪矩阵 (PRD → API → Issue → Test)
> **覆盖率确认:** 涵盖 API Contract 正文全部 53 个 P0 API(包含 Module A 20 个、Module B 17 个、Module C 9 个、Module D 7 个),覆盖率达成 53/53 = 100%。严格杜绝任何未经评审的私自增改。
### 2.1 Module A:人员与基础资源 (16 个 P0 核心 API + 4 个宿舍基础 API)
| 序号 | 来源 UC | HTTP Method & Path | 对应 Issue ID | 后端实现组件 | 前端组件 / 页面 | 权限字符 | 自动化测试类 | 验收判定条件 (Acceptance Criteria) |
|:---:|:---|:---|:---:|:---|:---|:---|:---|:---|
| 1 | - | `GET /train/teacher/list` | `ISSUE-01-01` | `TrainTeacherController.list` | `views/train/teacher/index.vue` | `train:teacher:list` | `TeacherApiTest.testList` | 分页返回教师列表,包含脱敏与职称 |
| 2 | - | `GET /train/teacher/{tId}` | `ISSUE-01-01` | `TrainTeacherController.getInfo` | `views/train/teacher/index.vue` | `train:teacher:query` | `TeacherApiTest.testGet` | 正确回显指定教师详细信息 |
| 3 | - | `POST /train/teacher` | `ISSUE-01-01` | `TrainTeacherController.add` | 教师新增弹窗组件 | `train:teacher:add` | `TeacherApiTest.testAdd` | 手机号重复抛出 40001,正常新增落库 |
| 4 | - | `PUT /train/teacher/{tId}` | `ISSUE-01-01` | `TrainTeacherController.edit` | 教师编辑弹窗组件 | `train:teacher:edit` | `TeacherApiTest.testEdit` | 正确更新教师职务与联系电话 |
| 5 | - | `GET /train/student/list` | `ISSUE-01-02` | `TrainStudentController.list` | `views/train/student/index.vue` | `train:student:list` | `StudentApiTest.testList` | 分页返回学员主档,身份证掩码脱敏展示 |
| 6 | - | `GET /train/student/{sId}` | `ISSUE-01-02` | `TrainStudentController.getInfo` | `views/train/student/index.vue` | `train:student:query` | `StudentApiTest.testGet` | 返回学员完整信息,身份证默认掩码 |
| 7 | - | `POST /train/student` | `ISSUE-01-02` | `TrainStudentController.add` | 学员录入弹窗组件 | `train:student:add` | `StudentApiTest.testAdd` | 安全散列查重防重,可逆密文存入数据库 |
| 8 | - | `GET /train/course/list` | `ISSUE-01-03` | `TrainCourseController.list` | `views/train/course/index.vue` | `train:course:list` | `CourseApiTest.testList` | 分页展示公共课程库,不含冗余版本字段 |
| 9 | - | `GET /train/course/{cId}` | `ISSUE-01-03` | `TrainCourseController.getInfo` | `views/train/course/index.vue` | `train:course:query` | `CourseApiTest.testGet` | 正确获取课程学时与教学目标 |
| 10 | - | `POST /train/course` | `ISSUE-01-03` | `TrainCourseController.add` | 课程录入弹窗组件 | `train:course:add` | `CourseApiTest.testAdd` | 课程编码重复拦截抛 40003,新增成功 |
| 11 | - | `GET /train/classroom/list` | `ISSUE-01-04` | `TrainClassroomController.list` | `views/train/classroom/index.vue` | `train:classroom:list` | `ClassroomApiTest.testList` | 分页返回教室及核定容纳人数 |
| 12 | - | `GET /train/classroom/{classRoomId}` | `ISSUE-01-04` | `TrainClassroomController.getInfo` | `views/train/classroom/index.vue` | `train:classroom:list` | `ClassroomApiTest.testGet` | 回显教室详情及绑定的班牌信息 |
| 13 | - | `POST /train/classroom` | `ISSUE-01-04` | `TrainClassroomController.add` | 教室录入弹窗组件 | `train:classroom:edit` | `ClassroomApiTest.testAdd` | 容量非负校验,正常新增教室 |
| 14 | - | `GET /train/training-site/list` | `ISSUE-01-04` | `TrainTrainingSiteController.list` | `views/train/site/index.vue` | `train:site:list` | `SiteApiTest.testList` | 分页返回实训场地(VR/3D演练区) |
| 15 | - | `GET /train/training-site/{siteId}` | `ISSUE-01-04` | `TrainTrainingSiteController.getInfo` | `views/train/site/index.vue` | `train:site:list` | `SiteApiTest.testGet` | 回显实训场地设备类型与容纳人数 |
| 16 | - | `POST /train/training-site` | `ISSUE-01-04` | `TrainTrainingSiteController.add` | 实训场地录入弹窗组件 | `train:site:edit` | `SiteApiTest.testAdd` | 场地名称查重校验,正常新增场地 |
| *17*| - | `GET /train/dormitory/list` | `ISSUE-01-05` | `TrainDormitoryController.list` | `views/train/dormitory/index.vue`| `train:dormitory:list`| `DormitoryApiTest.testList` | 分页返回房间、核定床位、已住与剩余 |
| *18*| - | `GET /train/dormitory/{dormId}` | `ISSUE-01-05` | `TrainDormitoryController.getInfo` | `views/train/dormitory/index.vue`| `train:dormitory:list`| `DormitoryApiTest.testGet` | 回显房间当前入住学员列表 |
| *19*| - | `POST /train/dormitory` | `ISSUE-01-05` | `TrainDormitoryController.add` | 宿舍录入弹窗组件 | `train:dormitory:edit`| `DormitoryApiTest.testAdd` | 同楼栋房号重复拦截抛 40006,新增成功 |
| *20*| - | `GET /train/dormitory/options` | `ISSUE-01-05` | `TrainDormitoryController.options` | 楼栋楼层级联选择器组件 | `train:dormitory:list`| `DormitoryApiTest.testOptions`| 结构化返回楼栋-楼层-房间级联树 |
*(注:*项为 Module A 中宿舍基础维护接口,经 CG-01 裁决正式确认纳入一期 P0 范围)*
---
### 2.2 Module B:开班计划与排课 (17 个 P0 核心 API)
| 序号 | 来源 UC | HTTP Method & Path | 对应 Issue ID | 后端实现组件 | 前端组件 / 页面 | 权限字符 | 自动化测试类 | 验收判定条件 (Acceptance Criteria) |
|:---:|:---|:---|:---:|:---|:---|:---|:---|:---|
| 17 | - | `GET /train/plans` | `ISSUE-02-01` | `TrainPlanController.list` | `views/train/plan/index.vue` | `train:plan:list` | `PlanLifecycleTest.testList` | 分页返回培训班列表与生命周期状态 |
| 18 | UC-01 | `POST /train/plans` | `ISSUE-02-01` | `PlanAppService.createPlan` | 创建培训计划表单弹窗 | `train:plan:add` | `PlanLifecycleTest.testCreate`| 时间起止校验、自动生成唯一计划编号 |
| 19 | - | `GET /train/plans/{planId}` | `ISSUE-02-01` | `TrainPlanController.getInfo` | 计划详情页基本信息卡片 | `train:plan:query` | `PlanLifecycleTest.testGet` | 回显计划负责人、招生上限与周期 |
| 20 | UC-02 | `PUT /train/plans/{planId}` | `ISSUE-02-01` | `PlanAppService.updatePlan` | 编辑培训计划表单弹窗 | `train:plan:edit` | `PlanLifecycleTest.testUpdate`| 已结训状态禁止修改抛 40012,正常更新 |
| 21 | UC-29 | `POST /train/plans/{planId}/complete` | `ISSUE-02-01` | `PlanAppService.completePlan` | 计划工作台“结训归档”按钮 | `train:plan:complete`| `PlanLifecycleTest.testComplete`| 状态置为已结束,学员状态置为已完成 |
| 22 | - | `GET /train/plans/{planId}/workbench`| `ISSUE-10-01` | `PlanAppService.getWorkbench` | `views/train/plan/workbench.vue` | `train:plan:query` | `PlanWorkbenchTest.testWorkbench`| 聚合返回班级工作台驾驶舱全部指标 |
| 23 | - | `GET /train/plans/{planId}/courses` | `ISSUE-02-02` | `TrainPlanCourseController.list` | 计划详情-本期课程配置 Tab | `train:plan:query` | `PlanCourseTest.testList` | 返回本期已选课程及生成的 planCourseId |
| 24 | UC-03 | `POST /train/plans/{planId}/courses` | `ISSUE-02-02` | `PlanAppService.configureCourses` | 课程库穿梭选择器弹窗 | `train:plan:edit` | `PlanCourseTest.testConfigure`| 重复选课抛 40020,成功引入本期课程 |
| 25 | UC-06 | `GET /train/plans/{planId}/enrollments`| `ISSUE-03-01` | `EnrollmentAppService.list` | 计划详情-参训人员名录表格 | `train:enrollment:list`| `EnrollmentCoreTest.testList` | 分页返回学员参训花名册与报到状态 |
| 26 | UC-04 | `POST /train/plans/{planId}/enrollments`| `ISSUE-03-01` | `EnrollmentAppService.addSingle` | 添加参训学员弹窗组件 | `train:enrollment:add` | `EnrollmentCoreTest.testAdd` | 招生超限抛 40031,生成 enrollmentId |
| 27 | UC-05 | `POST /train/plans/{planId}/enrollments/batch`| `ISSUE-03-02` | `EnrollmentAppService.importBatch` | Excel 名单导入上传模态框 | `train:enrollment:import`| `EnrollmentBatchTest.testImport`| 解析 500 行花名册,错误行明细回显 |
| 28 | - | `GET /train/enrollments/{enrollmentId}` | `ISSUE-03-01` | `EnrollmentAppService.getDetail` | 学员参训全景卡片组件 | `train:enrollment:query`| `EnrollmentCoreTest.testGet` | 聚合回显住宿、考勤、成绩与学时总览 |
| 29 | UC-07 | `POST /train/plans/{planId}/lessons` | `ISSUE-04-01` | `SchedulingAppService.createLesson` | 排课弹窗(教师/场地/时段) | `train:lesson:add` | `LessonSchedulingTest.testCreate`| 四维冲突检测拦截,行排他锁防穿透 |
| 30 | UC-08 | `PUT /train/lessons/{lessonId}` | `ISSUE-04-01` | `SchedulingAppService.updateLesson` | 修改课次弹窗组件 | `train:lesson:edit` | `LessonSchedulingTest.testUpdate`| 已有打卡考勤记录时严禁修改上课时间 |
| 31 | UC-10 | `POST /train/lessons/check-conflict` | `ISSUE-04-01` | `SchedulingAppService.checkConflict` | 排课表单时段失焦预检组件 | `train:lesson:query` | `LessonConflictTest.testCheck` | 实时返回冲突原因与冲突课次列表 |
| 32 | UC-11 | `GET /train/plans/{planId}/timetable` | `ISSUE-04-02` | `SchedulingAppService.getTimetable` | 计划详情-完整课程表日历视图 | `train:plan:query` | `PlanTimetableTest.testTimetable`| 按日历周/日嵌套聚合课表,零失真展示 |
| 33 | UC-15 | `POST /train/enrollments/{enrollmentId}/report`| `ISSUE-05-03` | `ReportAppService.confirmReport` | 学员报到确认操作按钮 / 弹窗 | `train:report:confirm` | `ReportLifecycleTest.testReport` | 逾期未特批提示 40051,状态置为已报到 |
---
### 2.3 Module C:住宿、门禁与考勤 (9 个 P0 核心 API)
| 序号 | 来源 UC | HTTP Method & Path | 对应 Issue ID | 后端实现组件 | 前端组件 / 页面 | 权限字符 | 自动化测试类 | 验收判定条件 (Acceptance Criteria) |
|:---:|:---|:---|:---:|:---|:---|:---|:---|:---|
| 34 | UC-12 | `POST /train/plans/{planId}/accommodations/preallocate`| `ISSUE-05-01` | `AccommodationAppService.preallocate` | 批量预分配宿舍策略弹窗 | `train:accommodation:assign` | `AccommodationLockTest.testPrealloc` | `SELECT FOR UPDATE` 排他锁防超卖,严格性别隔离 |
| 35 | UC-13 | `PUT /train/enrollments/{enrollmentId}/accommodation` | `ISSUE-05-02` | `AccommodationAppService.adjust` | 单人调房 Dialog 弹窗 | `train:accommodation:adjust` | `AccommodationAdjustTest.testAdjust` | 目标房间满员抛 40062,跨性别调房拦截 |
| 36 | - | `PUT /train/enrollments/{enrollmentId}/accommodation/day-student`| `ISSUE-05-02` | `AccommodationAppService.setDayStudent` | 设置走读操作按钮 | `train:accommodation:adjust` | `AccommodationAdjustTest.testDay` | 走读设置成功,立即释放已占用房间床位 |
| 37 | UC-14 | `GET /train/plans/{planId}/accommodations` | `ISSUE-05-02` | `AccommodationAppService.list` | 计划详情-住宿分配台账列表 | `train:accommodation:list` | `AccommodationListTest.testList` | 分页返回全班住宿床位与门禁下发状态 |
| 38 | UC-16 | `POST /train/accommodations/{accommodationId}/auth/sync`| `ISSUE-06-02` | `ExternalIntegrationAppService.syncDoor` | 住宿列表“重试门禁同步”按钮 | `train:dormauth:sync` | `DoorAuthAsyncTest.testRetrySync` | 事务外调用 Adapter,失败更新状态为 2 |
| 39 | UC-17 | `POST /train/attendance/sign-in` | `ISSUE-07-01` | `AttendanceAppService.recordSignIn` | 班牌刷脸模拟回调接口 | `train:attendance:checkin` | `AttendanceInvariantTest.testSignIn` | **强制落实 INV-01 拦截跨班串签**,幂等查重 |
| 40 | UC-18 | `POST /train/attendance/sign-out` | `ISSUE-07-01` | `AttendanceAppService.recordSignOut` | 班牌签退刷脸模拟回调接口 | `train:attendance:checkin` | `AttendanceSignInTest.testSignOut` | 课次签退落库,自动计算出勤考勤结论 |
| 41 | UC-19 | `PUT /train/attendance/{checkinId}` | `ISSUE-07-02` | `AttendanceAppService.adjustAttendance` | 考勤异常修改 Dialog 弹窗 | `train:attendance:edit` | `AttendanceAdjustTest.testAdjust` | 修改考勤结论,强制标记 `manual_flag = 1` |
| 42 | - | `GET /train/lessons/{lessonId}/attendance` | `ISSUE-07-02` | `AttendanceAppService.getLessonRoster` | 教师端-课次考勤名单抽屉组件 | `train:attendance:list` | `AttendanceRosterTest.testRoster` | 左联花名册,准确显示应到/实到与缺勤名单 |
---
### 2.4 Module D:成绩、学习与统计 (7 个 P0 核心 API)
| 序号 | 来源 UC | HTTP Method & Path | 对应 Issue ID | 后端实现组件 | 前端组件 / 页面 | 权限字符 | 自动化测试类 | 验收判定条件 (Acceptance Criteria) |
|:---:|:---|:---|:---:|:---|:---|:---|:---|:---|
| 43 | - | `GET /train/plans/{planId}/score-items` | `ISSUE-08-01` | `ScoreAppService.getScoreItems` | 计划详情-考核科目配置表格 | `train:score:query` | `ScoreConfigTest.testList` | 返回本期考核项目、满分值与百分比权重 |
| 44 | UC-20 | `POST /train/plans/{planId}/score-items` | `ISSUE-08-01` | `ScoreAppService.configureScoreItems` | 成绩项目配置与权重保存按钮 | `train:score:config` | `ScoreConfigInvariantTest.testConfig` | **落实 INV-04 课程归属**,权重总和必须 100% |
| 45 | UC-21 | `POST /train/scores/entry` | `ISSUE-08-02` | `ScoreAppService.recordScores` | 成绩台账矩阵单元格打分输入 | `train:score:edit` | `ScoreInvariantTest.testScoreEntry` | **落实 INV-02 跨班与 INV-05 满分上限拦截** |
| 46 | - | `GET /train/plans/{planId}/scores/matrix` | `ISSUE-08-02` | `ScoreAppService.getScoreMatrix` | 计划详情-全班成绩台账大表 | `train:score:query` | `ScoreMatrixTest.testMatrix` | 动态行转列呈现科目,准确计算加权综合分 |
| 47 | UC-23 | `GET /train/enrollments/{enrollmentId}/scores` | `ISSUE-08-02` | `ScoreAppService.getStudentScoreReport` | 学员个人成绩单卡片弹窗 | `train:score:query` | `ScoreReportTest.testStudentScores` | 呈现单人各科目得分、满分、权重与加权总分 |
| 48 | UC-24 | `POST /train/study-records/receive` | `ISSUE-09-01` | `LearningAppService.receiveRecord` | 外部系统实训学时推送端点 | 系统放行 / 签名验证 | `LearningInvariantTest.testReceive` | **落实 INV-03 课程计划一致**,防重事件 ID 幂等三态响应 |
| 49 | UC-26 | `GET /train/plans/{planId}/statistics/overview` | `ISSUE-10-02` | `StatisticsAppService.getOverview` | 计划详情-培训成效统计看板 | `train:statistics:query` | `PlanStatisticsTest.testOverview` | 聚合报到率、出勤率、加权平均分与总实训学时 |
---
## 3. 验收追踪闭环结论
- **PRD 用例追踪:** 17 个 P0 核心用例全部精确映射到对应的 API、Issue 与自动化测试类;
- **API 覆盖闭环:** 53 个 P0 API 无一遗漏全部被 Issue 认领(53/53,100% 覆盖率);
- **规则硬边界:** 5 项跨表硬不变量由 `ISSUE-07-01`、`ISSUE-08-01`、`ISSUE-08-02`、`ISSUE-09-01` 唯一主责承揽,1 项生命周期时限策略由 `ISSUE-05-03` 唯一承揽;
- **质量闸门保证:** 每一个 Issue 均配备了严格对应的自动化测试类和基于 Given/When/Then 的判定条件,彻底消除了模糊验收隐患。
+112
View File
@@ -0,0 +1,112 @@
# RailwaySystem Phase 3:P1 / P2 需求储备池 (Backlog Register)
> **最高原则:** 本轮研发聚焦于 53 个 P0 API 的最小闭环,**严禁将任何 P1 或 P2 需求混入当前研发排期与测试范围**。
> **文档定位:** 本文档作为系统后续演进阶段(Phase 4 / Phase 5)的正式需求储备池,确保设计资产连续,防止需求流失。
> **数据基线:** 严格对齐 API Contract V1.0.1 真实物理端点定义,P1 共 34 个,P2 共 2 个,合计 36 个非核心接口全部封存入库。
---
## 1. P1 / P2 规模与模块分布统计
API Contract V1.0.1 中定义的 89 个 API 优先级分布为:
- **P0 (核心闭环,本轮必做):** 53 个
- **P1 (辅助支撑,登记备查):** 34 个
- **P2 (待现场确认,远期建设):** 2 个
```mermaid
pie title API 全局物理端点分布 (总数 89)
"P0 核心闭环 (本轮开发)" : 53
"P1 辅助能力 (Backlog 储备)" : 34
"P2 远期待定 (现场确认)" : 2
```
| 业务模块 | 物理总数 | P0 数量 | P1 数量 | P2 数量 | P1/P2 规划定位 |
|:---|:---:|:---:|:---:|:---:|:---|
| **Module A 人员与基础资源** | 38 | 20 | 18 | 0 | 主数据全功能闭环、资源载体绑定、班牌硬件入库 |
| **Module B 开班计划与排课** | 24 | 17 | 6 | 1 | 计划反向删除/移除、教师个人课表、学员移动端门户 |
| **Module C 住宿/门禁/考勤** | 13 | 9 | 4 | 0 | 房态实时看板、门禁下发流水、考勤人工补录、考勤综合汇总 |
| **Module D 成绩/学习/统计/画像** | 14 | 7 | 6 | 1 | 成绩Excel导入、学习记录流水、学员训练详情、学员综合画像、成绩下钻分布 |
| **合计** | **89** | **53** | **34** | **2** | **P1 (34) + P2 (2) = 36 全部封存入库** |
---
## 2. 34 个 P1 辅助能力清单 (Backlog Register)
### 2.1 Module A:人员与基础资源辅助能力 (18 个 API)
| 序号 | HTTP Method & Path | API 业务描述 | 所属领域 | 计划演进阶段 |
|:---:|:---|:---|:---:|:---:|
| 1 | `PUT /train/teacher/{tId}/status` | 修改教师启停用状态 (0停用, 1启用) | 教师管理 | Phase 4 基础功能增强 |
| 2 | `PUT /train/student/{sId}` | 修改学员主档基础信息 | 学员管理 | Phase 4 基础功能增强 |
| 3 | `POST /train/student/import` | 学员库 Excel 批量全局导入 | 学员管理 | Phase 4 基础功能增强 |
| 4 | `PUT /train/course/{cId}` | 修改公共课程库基础资料 | 课程库 | Phase 4 基础功能增强 |
| 5 | `POST /train/course/{cId}/resources` | 课程绑定教学资源 (文档/视频/VR) | 课程资源 | Phase 4 教学资源深化 |
| 6 | `DELETE /train/course/{cId}/resources/{resourceId}` | 课程解绑教学资源 | 课程资源 | Phase 4 教学资源深化 |
| 7 | `GET /train/resource/list` | 分页查询教学资源列表 | 教学资源 | Phase 4 教学资源深化 |
| 8 | `GET /train/resource/{resourceId}` | 获取指定教学资源详情与预览地址 | 教学资源 | Phase 4 教学资源深化 |
| 9 | `POST /train/resource` | 新增教学资源 (支持文档、视频、VR、3D、链接) | 教学资源 | Phase 4 教学资源深化 |
| 10 | `PUT /train/resource/{resourceId}` | 修改教学资源描述与类型 | 教学资源 | Phase 4 教学资源深化 |
| 11 | `DELETE /train/resource/{resourceId}` | 删除教学资源 (引用时校验阻断) | 教学资源 | Phase 4 教学资源深化 |
| 12 | `PUT /train/classroom/{classRoomId}` | 修改教室容纳人数与位置 | 教室管理 | Phase 4 基础功能增强 |
| 13 | `PUT /train/training-site/{siteId}` | 修改实训场地设备类型与容量 | 实训场地 | Phase 4 基础功能增强 |
| 14 | `GET /train/electronic-board/list` | 分页查询电子班牌硬件设备列表 | 电子班牌 | Phase 4 硬件运维管理 |
| 15 | `GET /train/electronic-board/{boardId}` | 获取电子班牌绑定教室与网络配置 | 电子班牌 | Phase 4 硬件运维管理 |
| 16 | `POST /train/electronic-board` | 注册录入电子班牌 SN 与网络端点 | 电子班牌 | Phase 4 硬件运维管理 |
| 17 | `PUT /train/electronic-board/{boardId}` | 修改电子班牌参数配置 | 电子班牌 | Phase 4 硬件运维管理 |
| 18 | `PUT /train/dormitory/{dormId}` | 修改宿舍房间核定容量与状态 (容量不可小于当前已住人数) | 宿舍管理 | Phase 4 基础功能增强 |
---
### 2.2 Module B:开班计划与排课辅助能力 (6 个 API)
| 序号 | HTTP Method & Path | API 业务描述 | 所属领域 | 计划演进阶段 |
|:---:|:---|:---|:---:|:---:|
| 19 | `DELETE /train/plans/{planId}/courses/{planCourseId}` | 移除本期课程 (已有排课时强校验阻断) | 选课管理 | Phase 4 计划运维 |
| 20 | `PUT /train/enrollments/{enrollmentId}/status` | 手工变更参训状态 (2请假, 3放弃) | 参训管理 | Phase 4 学员生命周期 |
| 21 | `DELETE /train/enrollments/{enrollmentId}` | 移除参训人员 (已有打卡或成绩时阻断) | 参训管理 | Phase 4 学员生命周期 |
| 22 | `DELETE /train/lessons/{lessonId}` | 删除排课课次 (已有考勤打卡记录时阻断) | 排课管理 | Phase 4 教学日程调整 |
| 23 | `GET /train/teacher/{tId}/timetable` | 获取指定教师跨班个人周课表日历 | 课表视图 | Phase 4 教师协同服务 |
| 24 | `GET /train/plans/{planId}/reports` | 查询全班学员报到流水详细明细列表 | 报到管理 | Phase 4 报到精细运维 |
---
### 2.3 Module C:住宿、门禁与考勤辅助能力 (4 个 API)
| 序号 | HTTP Method & Path | API 业务描述 | 所属领域 | 计划演进阶段 |
|:---:|:---|:---|:---:|:---:|
| 25 | `GET /train/dormitory/occupancy-board` | 宿舍楼层网格实时房态占用看板 | 住宿管理 | Phase 4 宿管大屏可视化 |
| 26 | `GET /train/plans/{planId}/dorm-auths` | 查询全班门禁授权下发流水与下发状态 | 门禁同步 | Phase 4 硬件运维管理 |
| 27 | `POST /train/attendance/manual-add` | 人工直接补录课次漏打卡考勤记录 | 考勤管理 | Phase 4 考勤特批运维 |
| 28 | `GET /train/plans/{planId}/attendance/summary` | 查询计划考勤汇总概况与缺勤率统计 | 考勤统计 | Phase 4 统计报表增强 |
---
### 2.4 Module D:成绩、学习、统计与画像辅助能力 (6 个 API)
| 序号 | HTTP Method & Path | API 业务描述 | 所属领域 | 计划演进阶段 |
|:---:|:---|:---|:---:|:---:|
| 29 | `POST /train/plans/{planId}/scores/import` | Excel 批量导入全班单科成绩 | 成绩管理 | Phase 4 成绩快速录入 |
| 30 | `GET /train/plans/{planId}/study-records` | 多维分页查询全班外部自主实训流水 | 学习记录 | Phase 4 实训记录审计 |
| 31 | `GET /train/enrollments/{enrollmentId}/study-records` | 查询单学员自主实训时长明细流水 | 学习记录 | Phase 4 学员档案深化 |
| 32 | `GET /train/enrollments/{enrollmentId}/training-detail` | 查询学员个人全流程训练详情 (出勤/单科成绩/实训流水) | 综合成效 | Phase 4 学员档案深化 |
| 33 | `POST /train/enrollments/{enrollmentId}/portrait/generate` | 结课前后手动触发 / 重新刷新生成学员简单画像 | 学员画像 | Phase 4 画像计算引擎 |
| 34 | `GET /train/enrollments/{enrollmentId}/portrait` | 查询学员综合画像数据 (弹性指标集与标签集展示) | 学员画像 | Phase 4 学员多维分析 |
---
## 3. 2 个 P2 远期/待现场确认能力 (Deferred Register)
以下 2 个 API 明确属于 PRD V-01 ~ V-14 现场确认范围或面向移动端/学员端的远期接口,**严禁在一期管理端闭环中盲目推进**:
| 序号 | HTTP Method & Path | 接口名称与业务目的 | 暂缓原因与现场确认事项 | 激活准入条件 |
|:---:|:---|:---|:---|:---|
| **P2-01** | `GET /train/student/my-training` | 学员端移动端个人当前培训日程与成绩查看 | 属于面向学员独立移动端/小程序的门户接口,目前一期定位于基地管理端运转。 | 现场完成学员端 UI 规划与移动端技术选型确认。 |
| **P2-02** | `GET /train/plans/{planId}/statistics/score-distribution` | 计划成绩分段直方图与下钻区间统计 | PRD V-07/V-08 明确提出“是否设立固定分数线或区间待现场确认”,避免过度预设区间。 | 现场最终确认成绩分段规则与及格线标准。 |
---
## 4. Backlog 演进策略建议
1. **版本冻结铁律:** 在 Phase 3 研发及后续集成验收通过之前,上述 36 个 P1/P2 项严禁立项开工;
2. **Phase 4 准入:** 当 Phase 3 验收通过,且基地管理员试运行 P0 主链路顺畅后,优先开放 Phase 4 中的“基础数据修改”与“Excel 批量导入/流水查询”类辅助项;
3. **Phase 5 准入:** 学员画像深度计算与学员移动端入口统一在 Phase 5 根据甲方现场业务实测反馈决定上线节奏。
+177
View File
@@ -0,0 +1,177 @@
# RailwaySystem Phase 3:技术与业务风险登记册 (Risk Register)
> **编制目标:** 系统性识别 Phase 3 实施过程中涉及的高并发锁冲突、事务一致性、外部系统防腐解耦、权限收敛以及契约偏差风险,制定清晰的预防策略与应急预案。
---
## 1. 核心风险总览矩阵
| 风险编号 | 风险类别 | 风险描述与潜在影响 | 发生概率 | 影响程度 | 风险等级 | 应对策略 | 唯一责任 Issue |
|:---:|:---:|:---|:---:|:---:|:---:|:---|:---:|
| **RSK-01** | 并发冲突 | 多管理员同时对同一位教师/场地排课,导致教学冲突穿透 | 中 | 高 | **重大** | 稳定主资源行锁 (`Teacher` + `Classroom/Site` `SELECT ... FOR UPDATE`) + 三类资源时段区间重叠强校验 | `ISSUE-04-01` |
| **RSK-02** | 并发超卖 | 住宿分房并发请求先查空房再插入,导致房间超载超员 | 中 | 高 | **重大** | 锁定稳定宿舍主表行 (`train_dormitory_info FOR UPDATE`) + 周期重叠明细统计,杜绝空房 phantom 超售 | `ISSUE-05-01` |
| **RSK-03** | 事务长阻塞 | 门禁外部 HTTP 调用置于数据库事务内,网络抖动拖垮连接池 | 高 | 极高 | **严重** | 严禁大事务包裹外部调用,采用 `afterCommit` 事务外解耦触发 | `ISSUE-06-02` |
| **RSK-04** | 数据串线 | 跨班学员考勤/打分/学习记录串线,破坏多班级拓扑一致性 | 低 | 极高 | **严重** | Service 层硬编码落实 5 大跨表硬不变量 (INV-01~05) | `ISSUE-07-01` 等 |
| **RSK-05** | 权限扩散 | 历史遗留 `system:teacher:*` 权限字符扩散,导致鉴权混乱 | 中 | 中 | **中等** | 统一收敛为 `train:*`,前端与后端严格对齐 | `ISSUE-11-01` |
| **RSK-06** | 字典冲突 | 盲目执行 `007_dicts.sql` 导致与生产/若依内置字典主键冲突 | 低 | 高 | **重大** | 严禁在本轮物理执行 007,输出架构分类方案并采用 NOT EXISTS 幂等 | `ISSUE-11-02` |
| **RSK-07 (CG-01)** | 契约偏差 | Module A 头部声明 16 个与正文 20 个 P0 标注存在矛盾 | 高 | 低 | **RESOLVED** | 技术负责人已裁决:详细API标记优先于错误摘要统计;P0正式集合以53个逐API标记为准。 | `ISSUE-01-05` (已完整承揽) |
| **RSK-08 (CG-02)** | 契约偏差 | 课次详情单查接口缺失,PlanTimetableVO 字段不足支撑编辑回显 | 中 | 低 | **RESOLVED** | 技术负责人已裁决:通过扩展 TimetableLessonItemVO 补齐回显字段解决;不新增 Lesson 详情 API。 | `ISSUE-04-01` / `04-02` |
---
## 2. 关键技术风险深度分析与技术对策
### 2.1 排课稳定主资源行锁与冲突检测策略 (RSK-01)
- **业务场景:** 两个培训班在同一时间段内均选聘了同一位教师授课,或者两名教务管理员在不同终端同时为不同课程预约了同一间普通教室(或实训场地)。
- **技术隐患:** 普通行锁无法锁住“尚不存在的时段重叠 Lesson 行”。若直接执行 `SELECT ... FROM train_lesson WHERE ... FOR UPDATE`,在未冲突时返回空集,普通行锁失效;事务 A 与事务 B 同时读取空结果,随后分别 INSERT,导致物理冲突穿透。
- **强制工程对策:**
1. 排课事务必须标注 `@Transactional(rollbackFor = Exception.class)`;
2. **锁定稳定主资源:** 创建/修改 Lesson 时,事务内必须先对所涉及的实际主资源行加排他锁(通过主键锁定已存在的物理主表行):
```sql
-- 锁定授课教师主表行
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;
```
3. **三类资源上的时间区间重叠冲突查询:** 在持有稳定主资源锁的同一事务内,针对教师、教室、实训场地三类资源执行区间重叠检测:
```sql
existing.start_time < :newEndTime AND existing.end_time > :newStartTime
```
4. **编辑时的新旧资源锁顺序:** 修改 Lesson 若发生教师或场地变更,必须同时对旧资源与新资源加锁;为防止交叉死锁,强制按 `resourceType + ":" + resourceId` 字典序升序依次获取行锁;
5. **课次编辑硬前置拦截:** 修改课次时,若该课次已有学员考勤签到记录,系统强行阻断时段修改。
---
### 2.2 宿舍容量防超卖与稳定宿舍主表行锁策略 (RSK-02)
- **业务场景:** 宿舍 201 核定容量 4 人,当前剩余床位 1 个;或全新空房首次分配。两位管理员并发为两名学员执行分房或调房。
- **技术隐患:** 若依赖“当前已有住宿明细”加锁,在空房或少人场景下查询结果不足以封锁并发写入,导致幻读并发穿透,造成房间超员或性别混住。
- **强制工程对策:**
1. 严禁以前端查询结果作为容量判断依据;严禁仅对 `train_accommodation` 明细行加锁;
2. **锁定稳定宿舍主表行:** 批量预分配或单人调房事务开始,必须先对目标宿舍主表行加排他行锁:
```sql
SELECT dorm_id, capacity, gender_type
FROM train_dormitory_info
WHERE dorm_id = :dormId FOR UPDATE;
```
3. **计算培训周期重叠内的有效占用人数:**
```sql
SELECT COUNT(*) FROM train_accommodation
WHERE dorm_id = :dormId
AND accommodation_status IN (0, 1)
AND NOT (end_date <= :planStartDate OR start_date >= :planEndDate);
```
4. 校验 `(occupiedCount + requestCount) <= capacity`,一旦超员立即抛出 `DORM_ROOM_FULL (40062)` 并回滚;
5. 严格核验学员性别与房间 `gender_type`,杜绝男女混住隐患。
---
### 2.3 外部第三方网络调用与数据库连接池隔离 (RSK-03)
- **业务场景:** 门禁下发需要向外部物理门禁控制机发送 HTTP 请求;电子班牌需推送课程日程;外部实训系统推送学时。
- **技术隐患:** 外部硬件网络经常存在几秒甚至几十秒的超时。若在 `@Transactional` 本地事务中发起长网络 HTTP 请求,将导致本地数据库连接被长时间挂起占用,瞬间耗尽 HikariCP 连接池,引发系统雪崩。
- **强制工程对策:**
1. **铁律:数据库短事务严禁包裹外部第三方 HTTP/网络长调用!**
2. 使用 Spring 事务同步器(`TransactionSynchronizationManager`)在本地事务 COMMIT 成功后,通过 `afterCommit` 回调异步或在事务外触发 Adapter:
```java
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
doorAccessAdapter.grantAccess(cmd);
}
});
```
3. 单次外部请求设置硬超时阈值(5 秒);
4. 外部调用失败绝对不可回滚已提交的本地业务事务,而是更新 `face_sync_status = 2` 并记录 `last_error`,提供管理页面手动重试按钮;
5. 一期明确禁止引入 MQ、Kafka、Outbox 模式,保持架构极简可靠。
---
### 2.4 跨班硬一致性破坏与串线风险 (RSK-04)
- **业务场景:** 学员 A 参加 1 班培训,打卡时误刷了 2 班的课次;或教师录入成绩时将 1 班科目的分值打在了 2 班学员的档案上。
- **技术隐患:** 数据库物理外键仅约束了 ID 的存在性,无法感知“班级”拓扑。一旦串线,将导致整个统计报表与学员档案全面污染。
- **强制工程对策:**
1. 全面落实 5 大跨表硬业务不变量(INV-01 ~ INV-05);
2. 每一条不变量由唯一的 Application Service 负责强制校验(详见 [`06_acceptance_matrix.md`](file:///Users/wzb/Desktop/%E9%A1%B9%E7%9B%AE/RailwaySystem/docs/issues-v1/06_acceptance_matrix.md));
3. 任何违背不变量的操作直接抛出全局业务异常(如 `ATTENDANCE_PLAN_MISMATCH (40080)`),从根源杜绝脏数据。
---
## 3. 契约偏差 (Contract Gap) 正式裁决与闭环
### 3.1 CG-01 正式裁决落地 (Module A P0 统计矛盾)
- **最终裁决状态:** **RESOLVED**
- **技术负责人正式裁决结论:**
- **详细 API 标记优先于错误摘要统计;P0 正式集合以 53 个逐 API 标记为准。**
- 宿舍 4 个基础维护 API(列表、详情、新增、选项)属于一期 P0,因为 Accommodation 住宿主流程强依赖可维护的宿舍房间基础资源、核定容量与性别隔离属性。
- **实施落实:**
- Module A P0 正式确认修正为 **20 个**;
- 全局 P0 正式集合确定为 **53 个**(Module A: 20, Module B: 17, Module C: 9, Module D: 7);
- `ISSUE-01-05` 完整承揽宿舍基础管理 4 个 API,架构与 Issue 数量保持 26 个完全不变;
- P0 API 覆盖率达成:**53 / 53 = 100%**。
#### Module A 38 个 API 裁决执行对照表
| 序号 | Method | Path | Contract中的P等级 | 是否主流程前置必须 | 关联Issue | 正式P等级 | 裁决依据与落地说明 |
|:---:|:---|:---|:---:|:---:|:---:|:---:|:---|
| 1 | GET | `/train/teacher/list` | P0 | 是 | `ISSUE-01-01` | **P0** | 排课选教师前置必须,主链路不可缺少 |
| 2 | GET | `/train/teacher/{tId}` | P0 | 是 | `ISSUE-01-01` | **P0** | 教师详情回显,编辑与主档核查必须 |
| 3 | POST | `/train/teacher` | P0 | 是 | `ISSUE-01-01` | **P0** | 录入基础教师数据必须 |
| 4 | PUT | `/train/teacher/{tId}` | P0 | 是 | `ISSUE-01-01` | **P0** | 教师联系方式/职务维护必须 |
| 5 | PUT | `/train/teacher/{tId}/status` | P1 | 否 | - | P1 | 启停用管理,非 MVP 开班排课必经路径 |
| 6 | GET | `/train/student/list` | P0 | 是 | `ISSUE-01-02` | **P0** | 参训选人、学员检索主链路必须 |
| 7 | GET | `/train/student/{sId}` | P0 | 是 | `ISSUE-01-02` | **P0** | 学员详情回显必须 |
| 8 | POST | `/train/student` | P0 | 是 | `ISSUE-01-02` | **P0** | 学员主数据手工建档必须 |
| 9 | PUT | `/train/student/{sId}` | P1 | 否 | - | P1 | 学员主档修改,可由名单导入覆盖 |
| 10 | POST | `/train/student/import` | P1 | 否 | - | P1 | 全局学员库导入,培训班级直接用花名册批量导入 |
| 11 | GET | `/train/course/list` | P0 | 是 | `ISSUE-01-03` | **P0** | 培训计划引入课程必须 |
| 12 | GET | `/train/course/{cId}` | P0 | 是 | `ISSUE-01-03` | **P0** | 课程详情回显必须 |
| 13 | POST | `/train/course` | P0 | 是 | `ISSUE-01-03` | **P0** | 录入公共课程必须 |
| 14 | PUT | `/train/course/{cId}` | P1 | 否 | - | P1 | 课程修改,属于运营维护功能 |
| 15 | POST | `/train/course/{cId}/resources` | P1 | 否 | - | P1 | 课程关联资源,非开班排课硬依赖 |
| 16 | DELETE | `/train/course/{cId}/resources/{resourceId}` | P1 | 否 | - | P1 | 课程解绑资源,非开班排课硬依赖 |
| 17 | GET | `/train/resource/list` | P1 | 否 | - | P1 | 教学资源库列表,辅助教学功能 |
| 18 | GET | `/train/resource/{resourceId}` | P1 | 否 | - | P1 | 教学资源详情,辅助教学功能 |
| 19 | POST | `/train/resource` | P1 | 否 | - | P1 | 新增教学资源,辅助教学功能 |
| 20 | PUT | `/train/resource/{resourceId}` | P1 | 否 | - | P1 | 修改教学资源,辅助教学功能 |
| 21 | DELETE | `/train/resource/{resourceId}` | P1 | 否 | - | P1 | 删除教学资源,辅助教学功能 |
| 22 | GET | `/train/classroom/list` | P0 | 是 | `ISSUE-01-04` | **P0** | 排课选普通教室必须 |
| 23 | GET | `/train/classroom/{classRoomId}` | P0 | 是 | `ISSUE-01-04` | **P0** | 教室详情与核定人数核查必须 |
| 24 | POST | `/train/classroom` | P0 | 是 | `ISSUE-01-04` | **P0** | 录入教室基础数据必须 |
| 25 | PUT | `/train/classroom/{classRoomId}` | P1 | 否 | - | P1 | 教室维护,非首批开班硬依赖 |
| 26 | GET | `/train/training-site/list` | P0 | 是 | `ISSUE-01-04` | **P0** | 排课选实训演练场地必须 |
| 27 | GET | `/train/training-site/{siteId}` | P0 | 是 | `ISSUE-01-04` | **P0** | 实训场地详情回显必须 |
| 28 | POST | `/train/training-site` | P0 | 是 | `ISSUE-01-04` | **P0** | 录入实训场地必须 |
| 29 | PUT | `/train/training-site/{siteId}` | P1 | 否 | - | P1 | 实训场地维护,非首批硬依赖 |
| 30 | GET | `/train/electronic-board/list` | P1 | 否 | - | P1 | 班牌设备管理,非业务流程必须 |
| 31 | GET | `/train/electronic-board/{boardId}` | P1 | 否 | - | P1 | 班牌详情,非业务流程必须 |
| 32 | POST | `/train/electronic-board` | P1 | 否 | - | P1 | 注册班牌,非业务流程必须 |
| 33 | PUT | `/train/electronic-board/{boardId}` | P1 | 否 | - | P1 | 修改班牌,非业务流程必须 |
| 34 | GET | `/train/dormitory/list` | P0 | 是 | `ISSUE-01-05` | **P0** | 宿舍房态列表,分房/调房选择必须,裁决确认 P0 |
| 35 | GET | `/train/dormitory/{dormId}` | P0 | 是 | `ISSUE-01-05` | **P0** | 宿舍详情与当前住户回显,裁决确认 P0 |
| 36 | POST | `/train/dormitory` | P0 | 是 | `ISSUE-01-05` | **P0** | 录入宿舍房间基础数据必须,裁决确认 P0 |
| 37 | PUT | `/train/dormitory/{dormId}` | P1 | 否 | - | P1 | 修改宿舍房间,维持 P1 |
| 38 | GET | `/train/dormitory/options` | P0 | 是 | `ISSUE-01-05` | **P0** | 楼栋-楼层-房间级联下拉,分房交互必须,裁决确认 P0 |
---
### 3.2 CG-02 正式裁决落地 (课次详情单查接口缺失评估)
- **最终裁决状态:** **RESOLVED**
- **技术负责人正式裁决结论:**
- **通过扩展 TimetableLessonItemVO 解决;不新增 Lesson 详情 API。**
- 严禁私自新增 `GET /train/lessons/{lessonId}` 端点,保持 API Contract 接口数量稳定。
- **实施落实:**
- 已在 `docs/api-v2/06_dto_vo_catalog.md` 中补齐 `TimetableLessonItemVO` 的关键外键关联字段:`planCourseId`、`tId`、`venueType`、`classRoomId`、`classRoomName`、`siteId`、`siteName` 与 `remark`;
- 前端通过已有的 `GET /train/plans/{planId}/timetable`(完整课表 VO)读取当前 Lesson 项并完整回显编辑表单,随后直接调用既有的 `PUT /train/lessons/{lessonId}` 完成更新,主链路完全闭环。
---
## 4. 风险审查与日常跟踪机制
1. **每日构建与自动化测试:** 每日 CI 流水线必须执行 `P0BusinessFlowIntegrationTest`,自动验证 5 大硬不变量及并发冲突破坏性用例;
2. **代码审查红线卡点:**
- 审查排课代码必须核对是否包含主资源 `FOR UPDATE` 行锁;
- 审查住宿代码必须核对是否包含稳定宿舍主表行锁与原子容量核验;
- 审查外部调用代码必须核对是否位于事务外(`afterCommit` 触发)。
3. **现场确认事项隔离:** 涉及及格线判定、学员画像复杂标签、报到逾期模式等待现场确认事项,后端一律预留弹性枚举与参数配置,严禁硬编码。
+195
View File
@@ -0,0 +1,195 @@
# 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`;
- **差集核验命令:**
```bash
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. 事务开始后,先通过主键对实际涉及的稳定主资源行加排他锁:
```sql
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. 在持有稳定主资源锁的同一事务内,针对教师、教室、实训场地三类资源执行时间区间重叠冲突检测:
```sql
existing.start_time < :newEndTime AND existing.end_time > :newStartTime
```
3. **死锁防御:** 课次编辑若涉及教师或场地变更,必须同时锁定旧资源与新资源;为防止交叉死锁,强制要求按 `resourceType + ":" + resourceId` 字典序升序依次获取行锁;
4. **状态硬约束:** 若课次已有学员考勤打卡记录,强行阻断时段修改。
### 6.2 住宿并发模型加固 (ISSUE-05-01 / 05-02)
- **缺陷剖析:** 若仅锁定当前已有住宿明细,在空房或少人入住场景下无法封锁并发的批量分配,容易发生幻读导致超核定人数入住或男女混住。
- **稳定宿舍主表行锁机制:**
1. 分房与调房事务开始后,必须先锁定目标房间的稳定物理主表行:
```sql
SELECT dorm_id, capacity, gender_type
FROM train_dormitory_info
WHERE dorm_id = :dormId FOR UPDATE;
```
2. 统计与目标培训周期存在重叠的有效住宿人数(预分配 0 与已入住 1):
```sql
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}$$