Files
railwaysystem/docs/codebase-audit/17_phase0_summary.md
T
wangzhibiao fb00f67d3b docs(审计): 完成Phase 0工程与数据库基线核验
记录当前Git开发基线、Kingbase真实表结构、培训数据与权限状态。

补充数据库与代码差异、只读兼容性验证及PRD V1.0核心对象映射,未包含业务代码或数据库修改。
2026-09-14 00:36:53 +08:00

212 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RailwaySystem Phase 0 工程与数据库真实基线总结
> 业务判断最高依据:`doc/RailwaySystem 智慧培训系统一期 PRD V1.0.md`。旧数据库设计、V0.9、详细开发说明、HTML 原型和既有生成模型仅作为现状证据;与 V1.0 冲突时,以 V1.0 为准。
## 1. 当前可以作为正式开发基线的是哪个代码状态?
当前可识别的提交基线是:
- branch:`main`;
- HEAD:`e12eda059679b89eb5d09215ffe1ce7132f161f2`;
- 最新提交:`docs(prd): 发布RailwaySystem智慧培训系统一期PRD V1.0正式业务基线`;
- 该提交已经包含成绩、宿舍、教室接口别名、本地启动脚本、Node 22 适配、Kingbase 本地连接适配和 PRD V1.0。
当前工作树不能整体直接称为一个新的正式提交基线:其中有一组未提交的旧材料移动,即 `doc/` 下3个旧文件表现为已跟踪删除,`doc/wxy_doc/` 下对应材料表现为未跟踪文件;`doc/wxy_doc/readme.md` 明确标注这些资料暂不使用。除此之外,核验开始时没有未提交的 Java、Vue、API、SQL 或运行配置代码。
因此,继续开发应以 `e12eda0` 的代码内容和 PRD V1.0 为起点;开始数据库 V2 工作前,还应先决定是否正式接纳这组旧文档归档变化。本次新增的 `12`—`17` 报告是审计产物,没有提交。
## 2. 14张培训表实际存在多少张?
14张全部存在于 `public` schema,数据库中也没有第15张 `train_%` 表。
实际数据量:
- `train_teacher`:1行;
- 其余13张培训表:均为0行。
所有表均有主键;6张数字主键表使用 `bigint GENERATED BY DEFAULT AS IDENTITY`,8张字符串主键表没有数据库默认生成器。数据库还存在24个培训表外键、7组业务唯一约束和9个更新时间触发器。
## 3. 实际表结构和当前代码差异有哪些?
从“数据库字段是否能被当前生成代码映射”看,14个 Mapper XML 的 `resultMap` 字段数与实际表字段数一致,实际157个字段均能在当前 Mapper 中找到映射,Entity 的 `String`、`Date`、`Long`、`BigDecimal` 类型也基本兼容。
主要差异和风险是:
1. 旧设计文档中的 `t_id`、`s_id` 是 `varchar(20)`,实际为 `varchar(32)`;`DATETIME` 落为 timestamp,`TINYINT` 落为 smallint,6个 `INT AUTO_INCREMENT` 落为 bigint identity。
2. 实际数据库比旧设计文档多出外键、唯一约束和更新时间触发器,迁移时不能只按 Markdown 字段表重建。
3. 多个 Java 日期字段使用 `@JsonFormat(pattern = "yyyy-MM-dd")`,数据库能够保存时分秒,但接口序列化可能只暴露日期。
4. 当前代码与现有表结构相互匹配,不代表满足 PRD V1.0。`train_class_plan.c_id/t_id`、无参训关系、无课次、住宿与授权耦合、签到无 `lesson_id`、成绩固定三列,均与正式业务对象冲突。
5. 当前训练表 DDL 没有形成仓库内可追溯的初始化/迁移来源,现有数据库约束和触发器只能从实例读取。
详见 `13_live_database_snapshot.md` 和 `14_database_code_diff.md`。
## 4. 当前数据库是否真正使用Kingbase?
是。通过现有数据源配置和项目已有 JDBC 驱动成功建立只读连接,实测信息为:
- KingbaseES V009R003C018;
- database:`training`;
- schema:`public`;
- 当前用户:`kingbase`;
- `database_mode=mysql`;
- Maven 驱动依赖版本:8.6.0。
当前数据源通过既有的本地 `127.0.0.1:4321` SSH/Tailscale 隧道连接。简单 SELECT 正常。整个核验事务为只读并已回滚关闭,没有修改数据库。
## 5. 当前Kingbase兼容模式能支持多少现有MySQL语法?
本次指定且可安全执行的语法探测全部通过:
- `date_format`;
- `ifnull`;
- `find_in_set`;
- `current_database()`;
- `sysdate()`;
- `LIMIT ... OFFSET ...`;
- MySQL 风格 `LIMIT offset,row_count`;
- `SELECT 1 FROM dual`;
- 反引号标识符。
当前 `PageHelper helperDialect=mysql` 的分页尾句具备语法基础,identity 和 JDBC generated keys 的元数据条件也满足。由于本阶段禁止写入,真实 INSERT 生成键回填和完整 PageHelper 请求链仍无法只读确认。
同时已经确认两个比单项语法更严重的应用级问题:
1. 代码生成器用 `table_schema=current_database()`,当前 database 为 `training`、schema 为 `public`,所以生成器按现有 SQL 查到0张表、0个字段。
2. Kingbase 的 `sys_catalog` 存在 `sys_user`、`sys_role`、`sys_config` 系统视图;当前搜索顺序优先于 `public`。若依 Mapper 使用未限定 schema 的表名时会命中系统视图并因字段不匹配失败。
因此结论是“列出的 MySQL 语法在当前实例中全部可用”,不能表述为“项目已经完成 Kingbase 适配”。
## 6. 培训菜单是否真实存在?
真实存在。`public.sys_menu` 中有23条培训相关菜单记录:6个目录、17个组件页面,ID 范围为2154—2176。17个 component 均能在前端找到对应 Vue 页面。
但这些记录存在关键缺口:
- 全部 `perms` 为空;
- 没有培训按钮权限记录;
- 没有 plan-course、参训关系、课次/课表、床位/住宿安排、独立门禁授权、成绩项目/权重和培训班工作台页面;
- 前端按钮主要使用 `train:*`,Controller 主要使用 `system:*`,数据库菜单没有对应权限字符串。
所以“菜单数据存在”和“培训权限链路可用”是两个不同结论。
## 7. 普通角色权限是否可能正常工作?
按当前实时数据,不能认为普通角色权限可以正常工作:
1. `public.sys_role` 为0行,没有培训角色。
2. `public.sys_user_role` 有20行,其中18行找不到对应应用用户,20行全部找不到对应应用角色。
3. `public.sys_role_menu` 有170行,全部找不到对应应用角色,另有9行找不到菜单。
4. 培训菜单 `perms` 全为空,前端和后端权限字符串也不一致。
5. 未限定的核心 `sys_user`、`sys_role`、`sys_config` 查询会命中 Kingbase 系统视图,登录、角色和配置查询本身存在阻塞。
若依已有 RBAC、菜单、按钮、数据权限和日志框架仍值得复用,但当前数据库权限数据及 schema 解析必须先核实和修复,不能据此新造一套账号权限系统。本阶段没有修改任何 `sys_*` 表。
## 8. 哪些问题必须在数据库V2以前处理?
1. 固定正式代码基线,并决定当前旧文档归档移动是否进入后续提交,避免 V2 设计建立在不清晰工作树上。
2. 明确若依 `sys_*` 应用表的 schema 访问方式,解决与 Kingbase 系统视图的名称冲突;在解决前,登录和权限核验不具备可靠基础。
3. 查明 `sys_role` 为空及用户—角色—菜单关系大量孤儿的来源,制定非破坏性恢复或迁移方案;不能直接改 `sys_*` 表试错。
4. 建立可审查、可版本化的数据库结构来源,完整保留实际外键、唯一约束、identity 和触发器信息。
5. 按 PRD V1.0 先确认开班计划—课程、参训关系和课次三个核心关系,再决定当前 CRUD 的字段去留。
6. 确认床位、住宿安排和门禁授权的业务边界,避免延续当前住宿事实与设备授权耦合。
7. 确认成绩项目/权重与参训学员得分的迁移边界,停止把固定三列当成最终成绩模型。
8. 统一数据库菜单、前端 `v-hasPermi` 和 Controller `@PreAuthorize` 的权限命名,并补齐按钮权限设计。
9. 明确字符串业务主键、identity 主键和 MyBatis 生成键的统一策略,并用后续可回滚集成环境验证真实写链路。
10. 明确时间字段是否需要时分秒,避免数据库 timestamp 与 Java `yyyy-MM-dd` 输出之间继续产生语义差异。
11. 在学员 V2 模型中确定身份证等敏感字段的可逆加密、脱敏展示和访问权限方案。
12. 修正代码生成器对 database/schema 的错误假设后,再把它作为 V2 代码生成依据。
## 9. 哪些现有数据必须迁移/保留?
当前培训业务只有 `train_teacher` 的1行真实数据需要明确保留和迁移;其他13张培训表为空,没有成绩、签到、住宿、报到或画像历史业务数据。
仍需保留或纳入迁移评估的非业务明细包括:
- 23条培训菜单的层级、名称、component 和排序,可作为 V1.0 菜单迁移底稿;
- `sys_user_role`、`sys_role_menu` 的现有记录需要先确认来源,虽然当前为孤儿关系,也不应直接删除;
- 14张表的实际约束、identity、sequence 和触发器定义;
- 唯一一条教师记录的标识、业务字段及审计时间。
由于其他培训表均为空,以下业务模型的数据迁移成本当前较低:
- `train_class_plan.c_id/t_id` 转向开班计划—课程及课次关系;
- 重复的 `student_id + plan_id` 转向正式参训关系;
- 签到转向 `lesson_id`;
- 宿舍/授权拆分;
- 固定三列成绩转向成绩项目和学员得分。
“数据为空”只降低历史数据迁移风险,不降低代码、接口、菜单和约束迁移工作量。
## 10. 哪些现有CRUD值得继续复用?
### 可优先复用业务外壳
- 教师、学员、课程、教室、实训场地:列表、分页、表单校验、导入导出、权限注解和基础 Mapper 结构可继续作为实现底稿。
- 电子班牌:设备资源 CRUD 外壳可保留,但与班级、教室、课次的关系需按 V1.0 重新确认。
- 开班计划、报到、学习时长、简单画像:页面和接口骨架可复用,领域字段及关联对象需要调整。
### 只能部分复用
- 宿舍房间:资源维护部分可复用,必须补足床位对象;
- 宿舍授权:现有 CRUD 可作为历史字段和设备接入参考,不能继续同时承担住宿安排与门禁授权;
- 签到:采集来源、时间和状态字段有参考价值,关联主线需要从 plan/course/time 转向参训关系与课次;
- 成绩:导入来源、录入人、录入时间等审计能力可参考,固定三列成绩及当前唯一约束不能作为最终模型。
### 不应按现状继续扩展
- 遗留的 `person`、`character`、`analysis`、`weather` 等页面没有形成 PRD V1.0 核心业务链,不应被当作领域模型依据。
- 现有代码没有课程版本/审批、复杂画像规则和自动结业引擎,这些缺失不构成一期阻塞。
## 11. 哪些表可以原地改造,哪些领域明显需要新增表?
本节仅作领域级初步分类,不确定最终表名、字段、主键、外键或迁移 DDL。
### 可保留主体并调整关联或字段
- `train_teacher`、`train_student`、`train_course`;
- `train_class_plan` 的计划主体;
- `train_classroom_info`、`train_training_site`;
- `train_electronic_board`;
- `train_class_report`、`train_student_checkin`、`train_study_duration`、`train_student_portrait`。
### 明显需要拆分或由新模型承接
- `train_dormitory_info` 目前只有房间层级,床位需要成为独立正式对象;
- `train_dorm_auth` 同时承载住宿事实和授权事实,需要由住宿安排与门禁授权分别表达;
- `train_score_info` 固定三列成绩不符合 V1.0,应由成绩项目/权重与参训学员得分模型承接。
### PRD V1.0已经明确、当前缺失的正式关系或对象
- 开班计划—课程关系;
- 参训关系;
- 课次;
- 教学资源及课程资源关系;
- 床位;
- 住宿安排;
- 独立门禁授权;
- 成绩项目及权重;
- 参训学员按成绩项目的得分。
最终哪些对象使用新表、关系表或原表改造,应在数据库 V2 评审中确定。
## 12. 当前14张培训表与 PRD V1.0 核心对象的映射
| 当前表 | PRD V1.0对应对象 | 判断 |
| --- | --- | --- |
| `train_teacher` | 教师 | 修改 |
| `train_student` | 学员 | 修改 |
| `train_course` | 课程 | 修改 |
| `train_class_plan` | 开班计划 | 修改 |
| `train_dormitory_info` | 宿舍资源、房间、床位 | 拆分 |
| `train_dorm_auth` | 住宿安排、门禁授权 | 拆分 |
| `train_classroom_info` | 教室 | 原样保留 |
| `train_training_site` | 实训场地 | 原样保留 |
| `train_class_report` | 报到 | 修改 |
| `train_electronic_board` | 电子班牌 | 修改 |
| `train_student_checkin` | 课次考勤 | 修改 |
| `train_score_info` | 成绩项目、权重、参训学员得分 | 被新模型替代 |
| `train_study_duration` | 学习记录/学习时长 | 修改 |
| `train_student_portrait` | 基础指标、简单标签、雷达图 | 修改 |
这里的“原样保留”表示其资源主体可以继续作为 V2 基础,不代表无需增加审计字段、关联表或约束;“修改、拆分、被新模型替代”也只是 Phase 0 初判,不构成最终数据库 V2 设计。