docs(审计): 完成Phase 0工程与数据库基线核验

记录当前Git开发基线、Kingbase真实表结构、培训数据与权限状态。

补充数据库与代码差异、只读兼容性验证及PRD V1.0核心对象映射,未包含业务代码或数据库修改。
This commit is contained in:
wangzhibiao committed 2026-09-14 00:36:53 +08:00
1 parent e12eda0596
commit fb00f67d3b
6 files changed
+1174

No files matched your search

@@ -0,0 +1,405 @@
# Phase 0:Kingbase 实时数据库快照
> 快照时间:数据库返回 `2026-09-14 00:07:58`
> 连接方式:复用 `application-druid.yml` 的 Kingbase JDBC配置,通过既有 SSH/Tailscale隧道连接 `127.0.0.1:4321`。
> 安全措施:JDBC连接开启只读事务,所有探测仅执行 `SELECT`、`SHOW` 和系统目录查询;最后执行 rollback并关闭连接。未输出口令、用户明细或培训人员明细。
## 1. 数据库基本信息
| 项目 | 实际值 |
| --- | --- |
| 数据库产品版本 | `KingbaseES V009R003C018` |
| JDBC驱动 | Kingbase8 JDBC Driver `V008R006B0001`;项目Maven坐标版本为 8.6.0 |
| database | `training` |
| schema | `public` |
| 当前用户 | `kingbase` |
| `database_mode` | `mysql` |
| 底层兼容版本设置 | `server_version=12.1` |
| 简单 `SELECT 1` | 成功 |
## 2. 14张培训表是否存在及行数
| 表名 | 是否存在 | schema | 精确行数 |
| --- | --- | --- | ---: |
| `train_teacher` | 是 | public | 1 |
| `train_student` | 是 | public | 0 |
| `train_course` | 是 | public | 0 |
| `train_class_plan` | 是 | public | 0 |
| `train_dormitory_info` | 是 | public | 0 |
| `train_dorm_auth` | 是 | public | 0 |
| `train_classroom_info` | 是 | public | 0 |
| `train_training_site` | 是 | public | 0 |
| `train_class_report` | 是 | public | 0 |
| `train_electronic_board` | 是 | public | 0 |
| `train_student_checkin` | 是 | public | 0 |
| `train_score_info` | 是 | public | 0 |
| `train_study_duration` | 是 | public | 0 |
| `train_student_portrait` | 是 | public | 0 |
`public` 中所有以 `train_` 开头的表恰好就是这 14 张,没有发现额外培训表。
## 3. 真实表结构
说明:`N` 表示 NOT NULL,`Y` 表示允许 NULL;未标默认值即无默认。`IDENTITY` 均为 `GENERATED BY DEFAULT AS IDENTITY`。实际时间类型为 Kingbase `timestamp`,实际小整数类型为 `smallint`。
### 3.1 `train_teacher`
```text
t_id varchar(32) N PK
t_name varchar(30) N
t_gender char(2) Y
t_birth date Y
t_department varchar(50) N
t_title varchar(30) Y
t_phone varchar(20) Y
t_email varchar(50) Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`t_id`);无其他 UNIQUE。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_teacher_modify` 在 UPDATE前调用 `func_train_update_modifytime()`。
### 3.2 `train_student`
```text
s_id varchar(32) N PK
s_name varchar(30) N
s_gender char(2) Y
s_birth date Y
s_department varchar(50) N
s_major varchar(50) N
s_class varchar(30) Y
s_phone varchar(20) Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`s_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_student_modify` 更新 `update_time`。
### 3.3 `train_course`
```text
c_id varchar(32) N PK
c_name varchar(100) N
c_type varchar(30) Y
c_duration integer Y
teaching_objective text Y
course_content text Y
attach_doc text Y
attach_video text Y
attach_model_link text Y
model_resource_ids text Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`c_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_course_modify` 更新 `update_time`。
### 3.4 `train_class_plan`
```text
plan_id varchar(32) N PK
plan_name varchar(100) N
c_id varchar(32) N FK -> train_course.c_id
start_time timestamp N
end_time timestamp N
train_address varchar(100) Y
t_id varchar(32) N FK -> train_teacher.t_id
recruit_num integer Y
apply_condition text Y
plan_status smallint Y DEFAULT 0
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`plan_id`)。
- 外键:`fk_classplan_course`、`fk_classplan_teacher`,默认 NO ACTION。
- 索引:只有主键唯一索引;未发现 `c_id`、`t_id` 的独立索引。
- 触发器:`trig_train_classplan_modify` 更新 `update_time`。
### 3.5 `train_dormitory_info`
```text
dorm_id varchar(32) N PK
dorm_building varchar(50) Y
dorm_room varchar(30) N
bed_total integer Y
bed_used integer Y DEFAULT 0
lock_device_sn varchar(64) Y
dorm_status smallint Y DEFAULT 1
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`dorm_id`);UNIQUE(`dorm_building`,`dorm_room`)。
- 外键:无。
- 索引:主键与房间组合唯一索引,无额外非唯一索引。
- 触发器:`trig_train_dorminfo_modify` 更新 `update_time`。
### 3.6 `train_dorm_auth`
```text
auth_id bigint N PK, IDENTITY
student_id varchar(32) N FK -> train_student.s_id
plan_id varchar(32) N FK -> train_class_plan.plan_id
dorm_id varchar(32) N FK -> train_dormitory_info.dorm_id
bed_no varchar(20) Y
face_sync_status smallint Y DEFAULT 0
auth_start timestamp Y
auth_end timestamp Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`auth_id`);UNIQUE(`student_id`,`plan_id`)。
- 外键:`fk_dormauth_stu`、`fk_dormauth_plan`、`fk_dormauth_dorm`。
- 索引:主键与参训人组合唯一索引,无其他非唯一索引。
- 生成:内部 identity序列 `train_dorm_auth_auth_id_seq`。
- 触发器:`trig_train_dormauth_modify` 更新 `update_time`。
### 3.7 `train_classroom_info`
```text
class_room_id varchar(32) N PK
room_name varchar(60) N
room_location varchar(100) Y
capacity integer Y
room_status smallint Y DEFAULT 1
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`class_room_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_classroom_modify` 更新 `update_time`。
### 3.8 `train_training_site`
```text
site_id varchar(32) N PK
site_name varchar(80) N
site_location varchar(100) Y
capacity integer Y
site_device text Y
site_status smallint Y DEFAULT 1
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`site_id`)。
- 外键:无。
- 索引:只有主键唯一索引。
- 触发器:`trig_train_trainsite_modify` 更新 `update_time`。
### 3.9 `train_class_report`
```text
report_id bigint N PK, IDENTITY
plan_id varchar(32) N FK -> train_class_plan.plan_id
student_id varchar(32) N FK -> train_student.s_id
report_way smallint Y
report_device_sn varchar(64) Y
report_time timestamp Y
report_status smallint Y DEFAULT 0
alloc_dorm_id varchar(32) Y FK -> train_dormitory_info.dorm_id
alloc_classroom_id varchar(32) Y FK -> train_classroom_info.class_room_id
alloc_site_id varchar(32) Y FK -> train_training_site.site_id
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`report_id`);UNIQUE(`plan_id`,`student_id`)。
- 外键:计划、学员、宿舍、教室、实训场地共5个外键。
- 索引:主键与计划/学员唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_class_report_report_id_seq`。
- 触发器:无。
### 3.10 `train_electronic_board`
```text
board_id varchar(32) N PK
board_sn varchar(64) N UNIQUE
bind_classroom_id varchar(32) Y FK -> train_classroom_info.class_room_id
bind_plan_id varchar(32) Y FK -> train_class_plan.plan_id
board_ip varchar(50) Y
board_content varchar(500) Y
board_playmode smallint Y DEFAULT 1
support_checkin_type varchar(30) Y
board_status smallint Y DEFAULT 1
last_heartbeat timestamp Y
create_user varchar(32) N
create_time timestamp Y DEFAULT CURRENT_TIMESTAMP
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
remark varchar(200) Y
```
- 主键/唯一:PK(`board_id`);UNIQUE(`board_sn`)。
- 外键:教室、开班计划。
- 索引:主键与设备序列号唯一索引,无其他非唯一索引。
- 触发器:`trig_train_board_modify` 更新 `update_time`。
### 3.11 `train_student_checkin`
```text
checkin_id bigint N PK, IDENTITY
plan_id varchar(32) N FK -> train_class_plan.plan_id
c_id varchar(32) N FK -> train_course.c_id
student_id varchar(32) N FK -> train_student.s_id
board_id varchar(32) Y FK -> train_electronic_board.board_id
checkin_way smallint Y
checkin_time timestamp Y
checkin_status smallint Y
lesson_start_time timestamp Y
lesson_end_time timestamp Y
```
- 主键/唯一:PK(`checkin_id`);UNIQUE(`plan_id`,`c_id`,`student_id`,`lesson_start_time`)。
- 外键:计划、课程、学员、班牌。
- 索引:主键与旧“课次+学员”组合唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_student_checkin_checkin_id_seq`。
- 触发器:无。
### 3.12 `train_score_info`
```text
score_id bigint N PK, IDENTITY
plan_id varchar(32) Y FK -> train_class_plan.plan_id
c_id varchar(32) Y FK -> train_course.c_id
student_id varchar(32) Y FK -> train_student.s_id
course_score numeric(5,2) Y
train_score numeric(5,2) Y
exam_score numeric(5,2) Y
source_type smallint Y
source_system varchar(50) Y
import_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`score_id`);UNIQUE(`plan_id`,`c_id`,`student_id`)。
- 外键:计划、课程、学员。
- 索引:主键与计划/课程/学员唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_score_info_score_id_seq`。
- 触发器:无。
### 3.13 `train_study_duration`
```text
dur_id bigint N PK, IDENTITY
student_id varchar(32) Y FK -> train_student.s_id
plan_id varchar(32) Y FK -> train_class_plan.plan_id
c_id varchar(32) Y FK -> train_course.c_id
device_type varchar(50) Y
start_time timestamp Y
end_time timestamp Y
study_seconds integer Y
sync_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`dur_id`);无其他 UNIQUE。
- 外键:学员、计划、课程。
- 索引:只有主键唯一索引。
- 生成:identity序列 `train_study_duration_dur_id_seq`。
- 触发器:无。
### 3.14 `train_student_portrait`
```text
portrait_id bigint N PK, IDENTITY
student_id varchar(32) N FK -> train_student.s_id
plan_id varchar(32) N FK -> train_class_plan.plan_id
total_study_hour numeric(8,2) Y
avg_score numeric(5,2) Y
checkin_rate numeric(5,2) Y
label_tag text Y
portrait_content text Y
update_time timestamp Y DEFAULT CURRENT_TIMESTAMP
```
- 主键/唯一:PK(`portrait_id`);UNIQUE(`student_id`,`plan_id`)。
- 外键:学员、计划。
- 索引:主键与学员/计划唯一索引,无其他非唯一索引。
- 生成:identity序列 `train_student_portrait_portrait_id_seq`。
- 触发器:无。
## 4. 主键、外键、索引与触发器汇总
- 14张表均有主键。
- 6张数字主键表均为 `bigint GENERATED BY DEFAULT AS IDENTITY`,JDBC元数据返回 `IS_AUTOINCREMENT=YES`;驱动返回 `supportsGetGeneratedKeys=true`。由于禁止写入,本次没有实际 INSERT验证回填。
- 8张字符串主键表没有默认生成器,仍由应用/用户提供业务编号。
- 实际有 24个培训外键关系,孤儿统计均为 0;当前除教师外各表为空,不能用现有数据证明复杂关联行为。
- 除主键和7组业务唯一约束外,`pg_indexes` 未发现额外非唯一索引;多个外键列没有独立索引。
- 9张有 `update_time` 的主数据表通过 `func_train_update_modifytime()` 触发器在 UPDATE前更新时间。
## 5. 数据安全统计
- 唯一现有培训业务数据:`train_teacher` 1行;未输出姓名、电话、邮箱或主键值。
- 8张字符串主键表均无 NULL或重复主键;其中7张为空,教师表1行。
- 24组已建外键关系的孤儿数均为0。
- `train_score_info` 为0行,当前没有真实成绩需要迁移。
- `train_class_plan`、`train_student`、报到、住宿、签到、时长、画像均为0行。
- 教师记录的 `create_time`、`update_time` 确实含非零时分秒;其他业务时间字段因对应表为空,无法用数据确认。
## 6. 关键 `sys_*` 表真实状态
以下均指明确限定的 `public.sys_*`,避免与 Kingbase系统视图混淆。
| 表 | 是否存在 | 行数 | 主要列是否覆盖若依模型 |
| --- | --- | ---: | --- |
| `public.sys_user` | 是 | 1 | 是:`user_id`至`pwd_update_date`齐全 |
| `public.sys_role` | 是 | 0 | 是:`role_id`、`role_key`、`data_scope`等齐全,但无数据 |
| `public.sys_menu` | 是 | 106 | 是:路由、component、perms、menu_type等齐全 |
| `public.sys_user_role` | 是 | 20 | 列齐全,但关系数据异常 |
| `public.sys_role_menu` | 是 | 170 | 列齐全,但关系数据异常 |
| `public.sys_dept` | 是 | 15 | 列齐全 |
| `public.sys_role_dept` | 是 | 0 | 列齐全 |
| `public.sys_config` | 是 | 0 | 列齐全,但无应用配置数据 |
| `public.sys_dict_type` | 是 | 44 | 列齐全 |
| `public.sys_dict_data` | 是 | 500 | 列齐全 |
| `public.sys_job` | 是 | 0 | 列齐全 |
| `public.sys_job_log` | 是 | 0 | 列齐全 |
关系完整性统计:
- `public.sys_user_role` 20行,其中18行引用不存在的应用用户,20行全部引用不存在的应用角色。
- `public.sys_role_menu` 170行,全部引用不存在的应用角色;另有9行引用不存在的菜单。
- `public.sys_role` 为0行,因此实时库没有可识别的培训角色或普通应用角色。
## 7. Kingbase系统视图同名冲突
当前隐式搜索顺序为:
```text
sys -> pg_catalog -> sys_catalog -> public
```
Kingbase在 `sys_catalog` 中也提供 `sys_user`、`sys_role`、`sys_config` 视图。现有若依 Mapper 使用未限定表名,实测:
- `select ... user_id ... from sys_user` 命中系统视图并报 `user_id` 不存在。
- `select ... role_id ... from sys_role` 命中系统视图并报 `role_id` 不存在。
- `select ... config_id ... from sys_config` 命中系统视图并报 `config_id` 不存在。
因此“public表结构与Entity/Mapper列名一致”仍不足以证明若依系统功能可用;schema解析冲突是独立阻塞项。