docs(审计): 完成Phase 0工程与数据库基线核验
记录当前Git开发基线、Kingbase真实表结构、培训数据与权限状态。 补充数据库与代码差异、只读兼容性验证及PRD V1.0核心对象映射,未包含业务代码或数据库修改。
This commit is contained in:
1 parent
e12eda0596
commit
fb00f67d3b
6 files changed
+1174
No files matched your search
@@ -0,0 +1,185 @@
|
||||
# Phase 0:设计文档、实时Kingbase与代码三方差异
|
||||
|
||||
> 业务判断以 `doc/RailwaySystem 智慧培训系统一期 PRD V1.0.md` 为最高依据。原始表设计只用于说明V1数据库来源,不能否定PRD V1.0已经确认的新业务对象。
|
||||
|
||||
## 1. 三方总览
|
||||
|
||||
14个 Mapper XML 的 `resultMap` 字段数与实时表列数逐表一致:157个实际列均在对应 Mapper映射中出现。当前 Entity/Mapper与旧14表可以静态对接;主要问题来自旧表模型与PRD V1.0业务对象不一致,以及若依系统表schema冲突。
|
||||
|
||||
| 表 | 原设计文档 | 实际Kingbase | Entity / Mapper | 是否一致 | 主要差异 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `train_teacher` | 12列,`t_id varchar(20)` | 12列,`t_id varchar(32)`,PK,更新时间触发器,1行 | 12列全映射,`TrainTeacher` | 部分一致 | ID长度不同;PRD不再强制院系/高校职称,缺启停等培训字段 |
|
||||
| `train_student` | 12列,`s_id varchar(20)` | 12列,`s_id varchar(32)`,PK,更新时间触发器,0行 | 12列全映射,`TrainStudent` | 部分一致 | ID长度不同;缺加密身份证、人脸关联、培训型主档字段 |
|
||||
| `train_course` | 14列 | 14列,PK,更新时间触发器,0行 | 14列全映射,`TrainCourse` | 字段一致 | 附件/模型为文本列;PRD要求可选择教学资源对象 |
|
||||
| `train_class_plan` | 14列,单一`c_id/t_id` | 14列,`c_id/t_id`均NOT NULL且有FK,0行 | 14列全映射,`TrainClassPlan` | 旧模型一致 | 与PRD一班多课、课次教师关系直接冲突;缺报到截止规则 |
|
||||
| `train_dormitory_info` | 11列 | 11列,房间组合UNIQUE,更新时间触发器,0行 | 11列全映射 | 字段一致 | 只有楼栋+房间汇总,无楼层、床位、男女属性 |
|
||||
| `train_dorm_auth` | 12列,INT自增 | 12列,`bigint identity`,3个FK,学员/计划UNIQUE,0行 | 12列全映射,Long + generated keys | 语义部分一致 | 住宿安排与门禁授权耦合;`bed_no`是自由文本 |
|
||||
| `train_classroom_info` | 9列 | 9列,PK,更新时间触发器,0行 | 9列全映射 | 一致 | 基础对象符合PRD;排课关系应由课次表达 |
|
||||
| `train_training_site` | 10列 | 10列,PK,更新时间触发器,0行 | 10列全映射 | 一致 | 基础对象可留;`site_device`为文本而非资源关系 |
|
||||
| `train_class_report` | 11列,INT自增 | 11列,`bigint identity`,5个FK,计划/学员UNIQUE,0行 | 11列全映射 | 旧模型一致 | 应基于参训关系;报到行混入宿舍/教室/场地分配 |
|
||||
| `train_electronic_board` | 14列 | 14列,PK,SN唯一,教室/计划FK,0行 | 14列全映射 | 旧模型一致 | 缺设备名称/接口配置;直接绑计划不能表达当前课次 |
|
||||
| `train_student_checkin` | 10列,INT自增 | 10列,`bigint identity`,4个FK,旧课次组合UNIQUE,0行 | 10列全映射 | 旧模型一致 | 无`lesson_id`和参训关系;起止时间重复保存;没有签到/签退事件模型 |
|
||||
| `train_score_info` | 10列,固定三类成绩 | 10列,`bigint identity`,3个FK,计划/课程/学员UNIQUE,0行 | 10列全映射 | 旧模型一致 | 被PRD“成绩项目+权重+学员得分”正式替代 |
|
||||
| `train_study_duration` | 9列,INT自增 | 9列,`bigint identity`,3个FK,0行 | 9列全映射 | 一致 | PRD需参训关系、学习内容/来源和可幂等接入信息 |
|
||||
| `train_student_portrait` | 9列,INT自增 | 9列,`bigint identity`,学员/计划UNIQUE,0行 | 9列全映射 | 基础一致 | 与PRD简单画像接近;需参训关系和雷达展示所需基础指标 |
|
||||
|
||||
## 2. 旧设计与实际Kingbase的结构差异
|
||||
|
||||
### 2.1 类型映射
|
||||
|
||||
- 设计 `DATETIME` 在Kingbase实际为 `timestamp`。
|
||||
- 设计 `TINYINT` 在实际为 `smallint`。
|
||||
- 设计6个 `INT AUTO_INCREMENT` 主键在实际为 `bigint GENERATED BY DEFAULT AS IDENTITY`。
|
||||
- `train_teacher.t_id`、`train_student.s_id` 由设计的 `varchar(20)`扩大为实际 `varchar(32)`。
|
||||
- `numeric(5,2)`、`numeric(8,2)` 精度与设计一致。
|
||||
|
||||
这些类型差异与当前 Java `Date`、`Long`、`BigDecimal`、`String` 基本兼容。
|
||||
|
||||
### 2.2 实际约束超过设计文本
|
||||
|
||||
实时库明确存在24个外键,以及以下业务唯一约束:
|
||||
|
||||
- 报到:`plan_id + student_id`
|
||||
- 宿舍授权:`student_id + plan_id`
|
||||
- 宿舍房间:`dorm_building + dorm_room`
|
||||
- 班牌:`board_sn`
|
||||
- 成绩:`plan_id + c_id + student_id`
|
||||
- 签到:`plan_id + c_id + student_id + lesson_start_time`
|
||||
- 画像:`student_id + plan_id`
|
||||
|
||||
这些约束未体现在 Entity注解或业务校验中,错误主要由数据库返回。除主键/唯一索引外,外键列没有额外非唯一索引。
|
||||
|
||||
### 2.3 更新时间
|
||||
|
||||
教师、学员、课程、计划、宿舍、宿舍授权、教室、场地、班牌9张表有UPDATE触发器维护 `update_time`。部分 ServiceImpl同时设置更新时间,形成数据库与应用双重维护。
|
||||
|
||||
## 3. 一班多课与课次迁移影响
|
||||
|
||||
### 当前结构
|
||||
|
||||
```text
|
||||
train_class_plan
|
||||
├── c_id NOT NULL -> train_course
|
||||
└── t_id NOT NULL -> train_teacher
|
||||
```
|
||||
|
||||
这会把“培训班”“本期课程”“具体授课安排”压在一行中。
|
||||
|
||||
### PRD V1.0要求的初步迁移方向
|
||||
|
||||
```text
|
||||
开班计划
|
||||
↔ 开班课程
|
||||
→ 课次(教师、时间、教室或实训场地)
|
||||
```
|
||||
|
||||
- `train_class_plan`保留培训班核心信息。
|
||||
- `c_id`对应的信息迁入独立“开班课程”关系,一个计划可多条。
|
||||
- `t_id`不应继续代表整个培训班唯一教师;PRD将教师安排到具体课次。
|
||||
- 计划应补充开班级报到截止规则。
|
||||
- 当前 `train_class_plan` 为0行,实时库不存在需要搬迁的历史计划;这降低数据风险,但不消除 Controller、页面、Mapper和外键改造范围。
|
||||
|
||||
本报告不确定最终表名、主键或DDL。
|
||||
|
||||
## 4. 参训关系缺口与迁移影响
|
||||
|
||||
当前没有独立 `student + plan` 参训关系。以下6张表重复保存两者:
|
||||
|
||||
| 当前表 | 重复字段 | 新增参训关系后的初步引用对象 | 当前行数 |
|
||||
| --- | --- | --- | ---: |
|
||||
| `train_dorm_auth` | `student_id + plan_id` | 住宿安排/门禁授权所属参训人 | 0 |
|
||||
| `train_class_report` | `student_id + plan_id` | 报到所属参训人 | 0 |
|
||||
| `train_student_checkin` | `student_id + plan_id` | 考勤所属参训人 | 0 |
|
||||
| `train_score_info` | `student_id + plan_id` | 成绩所属参训人 | 0 |
|
||||
| `train_study_duration` | `student_id + plan_id` | 学习记录所属参训人 | 0 |
|
||||
| `train_student_portrait` | `student_id + plan_id` | 画像所属参训人 | 0 |
|
||||
|
||||
新增参训关系后,上述对象可以引用参训关系,避免每个模块独立解释学员在本期的资格和状态。同一学员/计划应由参训关系保证唯一。
|
||||
|
||||
当前6张表均为空,没有现存业务行需要转换。若数据库V2前产生数据,迁移时必须先按唯一的 `student_id + plan_id` 生成参训记录,再把报到、考勤、成绩、学习、画像、住宿/授权关联到相应参训记录。
|
||||
|
||||
## 5. `lesson_id` 对现有数据和代码的影响
|
||||
|
||||
### 当前签到
|
||||
|
||||
`train_student_checkin` 用:
|
||||
|
||||
```text
|
||||
plan_id + c_id + student_id + lesson_start_time
|
||||
```
|
||||
|
||||
模拟课次身份,并保存 `lesson_end_time`;唯一约束也以这组字段为基础。
|
||||
|
||||
### 加入正式课次后的影响
|
||||
|
||||
- 签到/考勤需要引用课次和参训关系,旧 `plan_id/c_id/lesson_start_time/lesson_end_time` 不再承担课次主键作用。
|
||||
- `train_class_plan.t_id` 中的教师关系应进入课次。
|
||||
- 教室和实训场地应由课次安排,不应继续由 `train_class_report.alloc_classroom_id/alloc_site_id` 作为学员报到分配。
|
||||
- 班牌保留与教室关系;当前展示内容应由教室在当前时段的课次决定,`bind_plan_id`不能覆盖多班多课排期。
|
||||
- Controller、查询条件、前端签到表单、唯一约束、统计维度和Mock班牌接口都会受影响。
|
||||
- 当前计划、签到、教室、场地和班牌表均为0行,不存在历史课次数据;未来迁移不能只凭相同起止时间推断课次,需在产生数据前冻结V2。
|
||||
|
||||
## 6. 宿舍:资源、床位、住宿安排、门禁授权
|
||||
|
||||
当前表达为:
|
||||
|
||||
```text
|
||||
train_dormitory_info(房间汇总+bed_total/bed_used+门锁SN)
|
||||
→ train_dorm_auth(学员+计划+房间+bed_no+人脸同步状态)
|
||||
← train_class_report.alloc_dorm_id(报到记录再次保存房间)
|
||||
```
|
||||
|
||||
无法完整表达PRD V1.0的:
|
||||
|
||||
```text
|
||||
宿舍资源 → 床位 → 住宿安排 → 门禁授权
|
||||
```
|
||||
|
||||
初步影响:
|
||||
|
||||
- `train_dormitory_info`可作为房间资源的来源,但缺楼层、床位实体、男女属性和可靠剩余量。
|
||||
- `bed_no`只是授权表文本,不能单独管理床位占用。
|
||||
- `train_dorm_auth`同时保存住宿事实和设备同步事实,需要拆开看待。
|
||||
- `train_class_report.alloc_dorm_id`与报到前预分配冲突;报到应读取已有住宿安排,而不是创建住宿事实。
|
||||
- 这3张表当前均0行,没有现有住宿数据需要搬迁;V2仍需定义从旧授权行拆出住宿安排和门禁授权的规则,以防切换前产生数据。
|
||||
|
||||
## 7. 成绩模型变化
|
||||
|
||||
### 当前字段
|
||||
|
||||
`train_score_info` 固定:
|
||||
|
||||
```text
|
||||
plan_id, c_id, student_id,
|
||||
course_score, train_score, exam_score,
|
||||
source_type, source_system, import_time
|
||||
```
|
||||
|
||||
### PRD V1.0目标
|
||||
|
||||
```text
|
||||
培训班 → 成绩项目 → 权重
|
||||
参训学员 → 成绩项目 → 得分
|
||||
```
|
||||
|
||||
### 初步迁移判断
|
||||
|
||||
- `course_score`、`train_score`、`exam_score` 三个固定分数字段将不再是最终模型,未来可能废弃或仅作为迁移来源。
|
||||
- `plan_id`、`c_id`、`student_id` 可用于识别旧成绩所属培训班/课程/学员;其中学员+计划应先映射参训关系,课程或其他考核类型应映射成绩项目。
|
||||
- `source_type`、`source_system`、`import_time` 的来源追溯语义仍有保留价值,可随具体得分记录迁移。
|
||||
- 旧唯一约束 `plan_id+c_id+student_id` 无法支持同课程多个成绩项目或非课程考核。
|
||||
- 当前 `train_score_info` 精确行数为0,因此不存在真实成绩迁移;从数据角度现在是调整模型的低风险窗口。
|
||||
- 代码层仍有 Entity、Mapper、Controller、API、成绩CRUD、课程成绩页和学员成绩页依赖固定三列,因此不能只改数据库。所谓“安全重构”仅指没有生产成绩数据需要保留,不代表代码改造可以无评审完成。
|
||||
|
||||
## 8. PRD V1.0明确不应再作为一期阻塞的旧要求
|
||||
|
||||
- 课程版本、课程审批、草稿/发布/归档、复杂标签、热门、初级/进阶:PRD V1.0明确不做;当前代码缺少这些能力不是一期阻塞。
|
||||
- 复杂画像规则引擎:一期只需基础指标、简单标签、雷达图。当前画像表可作为简单结果载体,主要缺参训关系、指标生成和雷达展示。
|
||||
- 自动结业规则引擎:一期按培训结束、状态完成、历史数据保留处理。当前不应新增“签到率+成绩+时长”自动结业复杂逻辑。
|
||||
|
||||
## 9. 实时数据库数据对迁移窗口的影响
|
||||
|
||||
- 必须保留/迁移:`train_teacher`唯一1行教师数据。
|
||||
- 当前无历史业务数据:其余13张培训表全部0行,包括成绩、计划、参训相关明细、住宿、签到、学习和画像。
|
||||
- 需要保留并重新评审的系统配置:23条培训菜单行。
|
||||
- 需要先处理的数据异常:`public.sys_role`为空,而用户角色、角色菜单关系已有孤儿数据;不能把这些关系直接当作有效权限基线迁入V2。
|
||||
Reference in new issue
Block a user