17 KiB
17 KiB
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}$ (严禁跨班打卡串签) |
ISSUE-07-01 |
AttendanceAppService |
ATTENDANCE_PLAN_MISMATCH (40080) |
AttendanceInvariantTest.testCrossPlanCheckinBlocked |
| INV-02 | $\text{studentScore.enrollment.plan_id} == \text{scoreItem.plan_id}$ (严禁跨班打分录入) |
ISSUE-08-02 |
ScoreAppService |
SCORE_PLAN_MISMATCH (40093) |
ScoreInvariantTest.testCrossPlanScoreEntryBlocked |
| INV-03 | $\text{study.enrollment.plan_id} == \text{planCourse.plan_id}$ (外部学习记录本期课程与班级一致) |
ISSUE-09-01 |
LearningAppService |
STUDY_EVENT_INVALID (40100) |
LearningInvariantTest.testCrossPlanCourseStudyBlocked |
| INV-04 | $\text{scoreItem.planCourse.plan_id} == \text{scoreItem.plan_id}$ (考核科目挂接课程必须属于本期计划) |
ISSUE-08-01 |
ScoreAppService |
SCORE_ITEM_COURSE_MISMATCH (40091) |
ScoreConfigInvariantTest.testExternalCourseBindingBlocked |
| INV-05 | $0 \le \text{studentScore.score} \le \text{scoreItem.full_score}$ (录入分值非负且不得超过满分上限) |
ISSUE-08-02 |
ScoreAppService |
SCORE_EXCEEDS_FULL_SCORE (40092) |
ScoreEntryValidationTest.testExceedFullScoreBlocked |
| POL-01 | $\text{report_time} \le \text{plan.report_deadline}$ (报到生命周期时限策略,支持告警与强制放行) |
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 的判定条件,彻底消除了模糊验收隐患。