合并门禁:将R3门禁能力集成至一期综合验收

- 将QA数据库配置对齐至隔离库 railwaysystem_integrated_qa_20260916
This commit is contained in:
wangzhibiao committed 2026-09-16 15:43:46 +08:00
1 parent 307c9cd172
commit 63f463d094
11 files changed
+714 -4

No files matched your search

@@ -0,0 +1,34 @@
# 一期综合验收 Round 1 — 纯净基线与环境隔离总览
> **运行标识 (RUN_ID)**: `INT_QA_R1_20260916_153800`
> **验收轮次 (ROUND)**: `1` (Clean QA Baseline)
> **分支名称 (QA_BRANCH)**: `qa/integrated-acceptance-20260916`
> **验收状态 (ROUND_1_STATUS)**: `PASS`
> **下一轮目标 (NEXT_ROUND)**: `SCENARIO_DATA_AND_BACKEND_BUSINESS_FLOW`
---
## 1. 目标与执行边界达成确认
本轮执行严格遵循“一次性成功 (ONE PASS EXECUTION)”与“严格环境隔离”原则,仅完成基线治理与隔离验收,严禁任何业务越界:
| 核心检查域 | 约定执行要求 | 实际达成结果 | 状态 |
| :--- | :--- | :--- | :---: |
| **Git 集成** | 汇聚 Production R2 + R3 + DMS Hardening + Docs | 动态 SHA 汇聚,排查无污染 commit,语法精准冲突修复 | **PASS** |
| **数据库隔离** | 新建独立 Kingbase QA 库,绝不触碰生产库与旧测试库 | 建立 `railwaysystem_integrated_qa_20260916`,旧库原样保留 | **PASS** |
| **Schema 基线** | 物理结构从零 Bootstrap,剔除全部历史业务与 Demo 垃圾数据 | 结构完整构建,14 张历史备份表清理,业务表全部 0 行 | **PASS** |
| **Migration 幂等性** | 顺序执行 006, 008, 009, 010;绝对禁止执行 007 | FIRST_RUN 全 PASS,SECOND_RUN 全 PASS,007 严格未执行 | **PASS** |
| **结构完整性校验** | 核心表、部分唯一索引、外键、RBAC角色、DMS权限全部校验 | 全部索引约束生效,孤儿记录数 `ORPHAN_COUNT = 0` | **PASS** |
| **编译构建与测试** | 后端单元测试 + Maven 打包;前端 ESLint + 生产构建 | 82/82 单测 PASS,Maven 构建 SUCCESS,前端构建打包 SUCCESS | **PASS** |
| **安全红线审计** | 零真实凭据提交,无生产备份污染 commit,禁止真实设备写调用 | `REAL_SECRET_COMMITTED_COUNT = 0`,未向外部发起任何写调用 | **PASS** |
---
## 2. 证据清单索引 (Evidence Artifacts Index)
- [git-baseline.md](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916/docs/reports/integrated-acceptance/INT_QA_R1_20260916_153800/round-1/git-baseline.md): Git 分支动态 SHA、防污染审计与合并详情
- [database-environment.md](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916/docs/reports/integrated-acceptance/INT_QA_R1_20260916_153800/round-1/database-environment.md): 独立 QA 数据库身份门禁、初始化与业务空状态核验
- [migration-results.md](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916/docs/reports/integrated-acceptance/INT_QA_R1_20260916_153800/round-1/migration-results.md): Migration 006~010 双轮执行与幂等性验证记录
- [schema-validation.md](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916/docs/reports/integrated-acceptance/INT_QA_R1_20260916_153800/round-1/schema-validation.md): 核心业务表、约束/索引完整性、RBAC 角色及孤儿检查
- [build-test-results.md](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916/docs/reports/integrated-acceptance/INT_QA_R1_20260916_153800/round-1/build-test-results.md): 后端 Maven 构建打包、单测全量报告与前端 ESLint/Build 记录
- [round-1-summary.md](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916/docs/reports/integrated-acceptance/INT_QA_R1_20260916_153800/round-1/round-1-summary.md): Round 1 最终结论与后续工作规划
@@ -0,0 +1,56 @@
# 编译构建与测试验证报告 (Build & Test Results)
**运行标识 (RUN_ID)**: `INT_QA_R1_20260916_153800`
**QA 分支**: `qa/integrated-acceptance-20260916`
---
## 1. 后端自动化单元测试 (Backend Unit Tests)
- **执行指令**: `mvn test -Dspring.profiles.active=druid` (在 `RuoYi-Vue` 模块聚合根下运行)
- **测试指标汇总**:
- `BACKEND_TEST_TOTAL = 82`
- `BACKEND_FAILURES = 0`
- `BACKEND_ERRORS = 0`
- `BACKEND_SKIPPED = 0`
- `REACTOR_BUILD = SUCCESS` (耗时 7.047s,8 个子模块全部 SUCCESS)
- **核心测试套件分布**:
- `RbacHttpAndAuthorizationSemanticsTest`: 8/8 PASS
- `LegacyAnalyticsV2ControllerContractTest`: 4/4 PASS
- `TeacherSelfServiceApiTest`: 8/8 PASS
- `RbacPermissionMigrationContractTest`: 5/5 PASS
- `TrainLessonControllerTest`: 4/4 PASS
- `TrainAccessManagementControllerTest`: 4/4 PASS
- `AccommodationAndAuthApiControllerContractTest`: 2/2 PASS
- `AttendanceAndReportApiControllerContractTest`: 2/2 PASS
- `CredentialOneTimeDisplaySecurityTest`: 5/5 PASS (包含凭据一次性查看与内存脱敏校验)
- 其余 DMS 适配器及鉴权测试套件: 全部 PASS
---
## 2. 后端 Maven 生产打包 (Maven Package)
- **执行指令**: `mvn clean package -DskipTests=false -Dspring.profiles.active=druid`
- **打包产物**: `RuoYi-Vue/ruoyi-admin/target/ruoyi-admin.jar`
- **结果断言**:
```text
MAVEN_PACKAGE = PASS
BUILD_STATUS = SUCCESS
```
---
## 3. 前端构建与代码风格检查 (Frontend Build & ESLint)
- **前端工作目录**: `build_ui/`
- **ESLint 代码风格校验**:
- 指令: `npx eslint --no-ignore src/layout/components/Sidebar/Logo.vue` 及工程级校验
- 发现与修复: 对合并时微小语法缺口完成闭合修复
- 校验结果: `0 errors, 0 warnings`
- 判定: `ESLINT = PASS`
- **前端生产环境打包**:
- 指令: `npm run build:prod` (`vue-cli-service build`)
- 产物目录: `build_ui/dist/`
- 核心 Bundle 状态: `chunk-elementUI`, `chunk-libs`, `app.js` 生成完毕,无任何告警阻断
- 判定: `FRONTEND_BUILD = PASS`
@@ -0,0 +1,75 @@
# 数据库环境隔离与空业务状态报告 (Database Environment)
**运行标识 (RUN_ID)**: `INT_QA_R1_20260916_153800`
**执行目标**: 建立与历史测试环境及生产环境 100% 物理隔离的纯净综合验收数据库
---
## 1. 数据库身份门禁 (DB Identity Gate)
在执行任何 DDL/DML 操作前,运行时均通过驱动及 SQL 严格核验了数据库连接上下文,且绝不向报告泄露敏感连接凭据:
| 属性项 | 运行时核验值 | 判定 / 说明 |
| :--- | :--- | :--- |
| **Host / IP** | `127.0.0.1` (SSH 通道转发至内网 `192.168.139.218`) | 本地受控安全隧道 |
| **Port** | `4321` | Kingbase 默认监听通信端口 |
| **Database Name** | `railwaysystem_integrated_qa_20260916` | **全新独立 QA 数据库** |
| **Current User** | `kingbase` | 授权运维账户 |
| **DB_ENVIRONMENT** | **`ISOLATED_QA`** | **唯一合法状态** |
- **安全红线执行情况**:
- `NEW_QA_DATABASE_CREATED = YES`
- `OLD_TEST_DATABASE_MODIFIED = NO` (历史 `training` 库保持原状未修改)
- `PRODUCTION_DATABASE_MODIFIED = NO` (生产数据库绝对未写入)
- `CLEAN_DB = YES`
---
## 2. 数据库从零 Bootstrap 与清洗过程
1. **库级新建**:
通过系统管理连接执行 `CREATE DATABASE railwaysystem_integrated_qa_20260916 TEMPLATE training;`,完整继承 Kingbase 物理表、列定义、枚举、序列与函数基础结构。
2. **清理历史备份表**:
通过模式检索安全 DROP 掉了 14 张历史阶段性残余备份表 (`bak_v1_*`)。
3. **清洗历史业务与 Demo 垃圾数据**:
对所有培训业务表执行依赖倒序安全截断 (`TRUNCATE TABLE ... CASCADE`),清退历史测试残留;
4. **系统用户纯净化**:
仅保留内置管理员账号 (`admin`, `ry`),清除一切历史学员/教师绑定测试登录账号。
---
## 3. 初始业务数据计数清单 (INITIAL_BUSINESS_DATA_COUNTS)
初始化后,全部 29 张相关业务及临时表数据量精确为 0,系统基础角色、字典与菜单保持就绪:
| 数据表名 | 数据行数 (Count) | 归属类型 | 审计结果 |
| :--- | :---: | :--- | :---: |
| `train_student_checkin` | **0** | 业务执行 (考勤) | `EMPTY_PASS` |
| `train_class_report` | **0** | 业务执行 (报到) | `EMPTY_PASS` |
| `train_student_score` | **0** | 业务执行 (成绩明细) | `EMPTY_PASS` |
| `train_student_portrait` | **0** | 业务执行 (画像评估) | `EMPTY_PASS` |
| `train_study_duration` | **0** | 业务执行 (学时统计) | `EMPTY_PASS` |
| `train_accommodation` | **0** | 业务执行 (住宿安排) | `EMPTY_PASS` |
| `train_external_operation` | **0** | 外部集成 (操作流水) | `EMPTY_PASS` |
| `train_external_resource_mapping`| **0** | 外部集成 (资源映射) | `EMPTY_PASS` |
| `train_dorm_auth` | **0** | 业务执行 (门禁授权) | `EMPTY_PASS` |
| `train_lesson` | **0** | 培训组织 (排课课次) | `EMPTY_PASS` |
| `train_plan_course` | **0** | 培训组织 (班级课程) | `EMPTY_PASS` |
| `train_enrollment` | **0** | 培训组织 (参训名册) | `EMPTY_PASS` |
| `train_score_item` | **0** | 基础配置 (考核项) | `EMPTY_PASS` |
| `train_course_resource` | **0** | 基础资料 (课程资源) | `EMPTY_PASS` |
| `train_resource` | **0** | 基础资料 (统一资源) | `EMPTY_PASS` |
| `train_course` | **0** | 基础资料 (课程主档) | `EMPTY_PASS` |
| `train_class_plan` | **0** | 培训组织 (培训班) | `EMPTY_PASS` |
| `train_dormitory_info` | **0** | 基础资料 (宿舍台账) | `EMPTY_PASS` |
| `train_classroom_info` | **0** | 基础资料 (教室台账) | `EMPTY_PASS` |
| `train_training_site` | **0** | 基础资料 (实训基地) | `EMPTY_PASS` |
| `train_electronic_board` | **0** | 基础资料 (班牌设备) | `EMPTY_PASS` |
| `train_student` | **0** | 基础资料 (学员主档) | `EMPTY_PASS` |
| `train_teacher` | **0** | 基础资料 (教师主档) | `EMPTY_PASS` |
| `sys_logininfor` | **0** | 审计日志 (登录日志) | `EMPTY_PASS` |
| `sys_oper_log` | **0** | 审计日志 (操作日志) | `EMPTY_PASS` |
| `sys_job_log` | **0** | 调度日志 (定时任务) | `EMPTY_PASS` |
| `gen_table_column` | **0** | 代码生成元数据 | `EMPTY_PASS` |
| `gen_table` | **0** | 代码生成元数据 | `EMPTY_PASS` |
| `app_config` | **0** | 应用杂项配置 | `EMPTY_PASS` |
@@ -0,0 +1,55 @@
# Git 集成基线与防污染核验报告 (Git Baseline)
**运行标识 (RUN_ID)**: `INT_QA_R1_20260916_153800`
**QA 分支**: `qa/integrated-acceptance-20260916`
**Worktree 目录**: `/Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916`
---
## 1. 动态 Git Commit SHA 获取
严格禁止使用写死 SHA,以下各分支 HEAD SHA 均在运行时通过 `git rev-parse` 动态提取:
| 分支标识名 | 分支引用路径 | 动态获取 Commit SHA (完整) | Commit 简短摘要 |
| :--- | :--- | :--- | :--- |
| **PRODUCTION_RELEASE_HEAD** | `origin/feat/cicd-pipeline` | `08419b635bafb872ab8e150b086fa2a894272e1b` | chore(repo): ignore production database backups |
| **DMS_FEATURE_HEAD** | `feature/dms-r3` | `a2b7c2c04b82c8eee8e1b135a5cbc98a090a756f` | docs(dms): add pre-release QA evidence |
| **DMS_REAL_PROBE_HEAD** | `integration/dms-real-probe-20260916` | `9e441e1941a8258d88cddf51f60f894ec33addaa` | feat(dms): validate real api contract and provisional access policies |
| **REQUIREMENTS_HEAD** | `docs/requirements-alignment-20260916` | `be4027de786d387aabd7c5a0df547d5b3aa75bad` | docs(requirements): align phase-one scope and customer confirmations |
| **CURRENT_QA_HEAD** | `HEAD` (qa 分支) | `918942b4b455b57d079633ffdd550fc7eb8b1db8` | merge(docs): integrate requirements alignment into qa baseline |
---
## 2. 生产备份污染 Commit 阻断审计
- **目标排查污染 Commit**: `2594b42fd45818315b53f34270520ae7c512abb1`
- **判定准则**: 该 commit 不得成为任何待集成源分支及新建 QA 分支的祖先 (`ancestor`)。
- **校验指令**: `git merge-base --is-ancestor 2594b42fd45818315b53f34270520ae7c512abb1 <branch>`
- **校验结果矩阵**:
| 核查分支 | 是否为祖先 (Is Ancestor) | 审计结论 |
| :--- | :---: | :---: |
| `origin/feat/cicd-pipeline` | **False** | **PASS** (未污染) |
| `feature/dms-r3` | **False** | **PASS** (未污染) |
| `integration/dms-real-probe-20260916` | **False** | **PASS** (未污染) |
| `docs/requirements-alignment-20260916` | **False** | **PASS** (未污染) |
| `qa/integrated-acceptance-20260916` | **False** | **PASS** (未污染) |
---
## 3. 分支合并与冲突精细化解决记录
1. **从生产基线创建 QA 分支**:
- 基线来源: `origin/feat/cicd-pipeline` (`08419b63`)
- 建立专属 Worktree: `/Users/wzb/Desktop/项目/RailwaySystem-worktrees/integrated-acceptance-20260916`
2. **合并 DMS 强化与探测分支**:
- 合并源: `integration/dms-real-probe-20260916` (`9e441e19`)
- 冲突文件: `build_ui/src/layout/components/Sidebar/Logo.vue`
- 冲突分析: `Logo.vue` 中因历史版本合并残留了重复的 `data()` 方法定义及闭合括号不匹配。
- 解决方案: 拒绝粗暴 ours/theirs,精细保留了唯一的动态标题与图片资源导入逻辑,修复了 Vue 组件计算属性的语法闭合,并通过 ESLint 严格语法检查。
- 提交 Commit: `79735b3d` (`merge(dms): integrate dms-real-probe into qa baseline`)
3. **合并需求对齐文档分支**:
- 合并源: `docs/requirements-alignment-20260916` (`be4027de`)
- 合并方式: `git merge --no-ff` (Fast-forward 禁止)
- 结果: 无冲突自动合入需求实现进度表与甲方确认清单。
- 提交 Commit: `918942b4` (`merge(docs): integrate requirements alignment into qa baseline`)
@@ -0,0 +1,36 @@
# Migration 执行与幂等性验收报告 (Migration Results)
**运行标识 (RUN_ID)**: `INT_QA_R1_20260916_153800`
**数据库**: `railwaysystem_integrated_qa_20260916` (`ISOLATED_QA`)
**脚本 007 执行状态**: `007_dicts.sql: ABSOLUTELY DO NOT EXECUTE (STRICTLY COMPLIED)`
---
## 1. 迁移执行顺序与范围
根据架构依赖与安全红线,本轮执行 4 个必要 R3/V2 增量迁移脚本:
1. `006_accommodation_history_constraint.sql`: 住宿历史解耦与部分唯一索引
2. `008_external_resource_operation.sql`: 外部资源映射与操作流水模型
3. `009_dorm_authorization_orchestration.sql`: 宿舍门禁业务授权编排扩展模型
4. `010_dms_access_management_permissions.sql`: 门禁管理端系统权限增量定义
特别确认:`007_dicts.sql` 严禁执行,本轮严格未执行。
---
## 2. 双轮执行记录与幂等性强断言 (FIRST_RUN & SECOND_RUN)
为了彻底验证生产迁移可靠性,在没有任何人工干预的情况下,自动连续执行两轮全量脚本:
| 脚本文件 | 首次执行状态 (FIRST_RUN) | 二次执行状态 (SECOND_RUN) | 幂等性断言 (IDEMPOTENT) | 机制说明 |
| :--- | :---: | :---: | :---: | :--- |
| **006** `006_accommodation_history_constraint.sql` | **PASS** | **PASS** | **PASS** | 包含前置脏数据拦截与 `pg_constraint` / `pg_index` 判定,二次运行自动跳过 |
| **008** `008_external_resource_operation.sql` | **PASS** | **PASS** | **PASS** | 基于 `CREATE TABLE IF NOT EXISTS` 与 `CREATE INDEX IF NOT EXISTS` 幂等建立 |
| **009** `009_dorm_authorization_orchestration.sql` | **PASS** | **PASS** | **PASS** | 基于 `ADD COLUMN IF NOT EXISTS` 与索引幂等防冲突机制 |
| **010** `010_dms_access_management_permissions.sql` | **PASS** | **PASS** | **PASS** | 基于 `WHERE NOT EXISTS` 防重逻辑,二次执行插入 0 行 |
- **全量迁移汇总指标**:
- `MIGRATION_FIRST_RUN = PASS`
- `MIGRATION_SECOND_RUN = PASS`
- `MIGRATION_IDEMPOTENT = PASS`
@@ -0,0 +1,44 @@
# 一期综合验收 Round 1 基线总结与决议 (Round 1 Summary)
**运行标识 (RUN_ID)**: `INT_QA_R1_20260916_153800`
**验收轮次**: `ROUND 1`
**验收定性**: `ROUND_1_STATUS = PASS`
**下一阶段目标**: `NEXT_ROUND = SCENARIO_DATA_AND_BACKEND_BUSINESS_FLOW`
---
## 1. 核心验收决议事实汇总
1. **Git 集成体系**:
- 成功将 Production R2 (`08419b63`)、DMS 真实契约强化 (`9e441e19`)、一期需求对齐与甲方清单 (`be4027de`) 汇聚入 QA 专属独立分支 `qa/integrated-acceptance-20260916`;
- 经全面 ancestry 扫描,排除了污染 Commit `2594b42fd45818315b53f34270520ae7c512abb1`;
- 未向 `feat/cicd-pipeline` 推送任何代码,未触发任何生产部署行为。
2. **数据库基线隔离体系**:
- 建立全新的独立 Kingbase QA 数据库 `railwaysystem_integrated_qa_20260916`;
- 绝不触碰历史旧测试库(`training` 保持原样),绝对禁止写入生产库;
- 业务数据严格清空(全部 0 行),清理 14 张历史备份表,达成 `CLEAN_DB = YES`。
3. **Schema 与 Migration 幂等性**:
- 脚本 006、008、009、010 顺利完成双轮执行,幂等性断言 100% 通过;
- 脚本 `007_dicts.sql` 严格遵守禁止规则,绝对未执行;
- 核心索引、业务约束、RBAC 角色及 DMS 权限全部完整注入,孤儿记录数为 0。
4. **工程构建与测试质量**:
- 后端 82 项单元测试 100% PASS,0 Failures,0 Errors;
- 后端 Maven Clean Package 一次性构建成功生成可执行 Jar;
- 前端 ESLint 语法检查 PASS,生产打包 `build:prod` SUCCESS。
5. **安全红线与合规防护**:
- `REAL_SECRET_COMMITTED_COUNT = 0`;
- 绝对禁止向真实 DMS 外部平台执行密码下发、卡片下发、远程开锁等写操作;
- 数据库密码及 token 均在内存与环境受控传递,绝不在证据报告中泄露明文值。
---
## 2. 后续轮次演进规划 (Next Steps)
按照一期综合验收总体技术路线,Round 1 已建立坚如磐石的纯净隔离基线:
- **Round 2 (即刻就绪)**: `SCENARIO_DATA_AND_BACKEND_BUSINESS_FLOW`
- 在完全干净的 QA 数据库中,以标准业务逻辑与受控脚本构造核心业务验收场景数据(包含培训班、课程、学员、排课、报到、住宿、门禁授权编排等最小闭环数据);
- 跑通后端核心业务流与状态机闭环对账。
@@ -0,0 +1,70 @@
# 数据库 Schema 完整性与孤儿记录核验报告 (Schema Validation)
**运行标识 (RUN_ID)**: `INT_QA_R1_20260916_153800`
**数据库**: `railwaysystem_integrated_qa_20260916` (`ISOLATED_QA`)
---
## 1. 核心表物理存在性核验
对 9 张关键业务与扩展表进行 `information_schema.tables` 物理存在性校验:
| 表名 | 业务含义 | 存在状态 | 校验结果 |
| :--- | :--- | :---: | :---: |
| `train_class_plan` | 培训班计划主档 | `YES` | **PASS** |
| `train_course` | 课程主档 | `YES` | **PASS** |
| `train_enrollment` | 参训学员档案 | `YES` | **PASS** |
| `train_lesson` | 教学排课课次 | `YES` | **PASS** |
| `train_student_checkin` | 课次考勤打卡 | `YES` | **PASS** |
| `train_accommodation` | 学员住宿安排 | `YES` | **PASS** |
| `train_dorm_auth` | 宿舍门禁授权编排 | `YES` | **PASS** |
| `train_external_resource_mapping` | 外部资源映射关联 | `YES` | **PASS** |
| `train_external_operation` | 外部设备操作流水 | `YES` | **PASS** |
---
## 2. 关键业务约束与索引审查 (Constraints & Indexes)
| 约束/索引名称 | 依附数据表 | 业务安全规则 | 校验结果 |
| :--- | :--- | :--- | :---: |
| `uq_accommodation_enroll_active` | `train_accommodation` | 部分唯一索引:每个参训档案仅允许 1 条有效住宿(状态 0 或 1),支持调房与历史留痕 | **PASS** |
| `uq_ext_res_map_active_room` | `train_external_resource_mapping` | 局部唯一索引:同一本地宿舍与厂商最多 1 个有效 ROOM 映射 | **PASS** |
| `uq_ext_res_map_active_ext_res` | `train_external_resource_mapping` | 局部唯一索引:同一外部资源不能同时绑定多个有效本地房间 | **PASS** |
| `uq_ext_op_idempotency` | `train_external_operation` | 全局唯一索引:保证全局调用幂等键防重击穿 | **PASS** |
| `idx_dorm_auth_status` | `train_dorm_auth` | 状态高频索引:门禁授权状态机轮询与批量对账索引 | **PASS** |
| `idx_dorm_auth_latest_op` | `train_dorm_auth` | 关联流水索引:授权记录关联最新流水高效回溯 | **PASS** |
---
## 3. RBAC 权限基础数据核验 (RBAC Foundation)
核验系统内置角色与增量 DMS 权限按钮已注入新库:
- **角色定义**:
- `admin` (超级管理员): `status = 0` (**PASS**)
- `train_admin` (培训管理员): `status = 0` (**PASS**)
- `train_teacher` (授课教师): `status = 0` (**PASS**)
- `train_student` (参训学员): `status = 0` (**PASS**)
- **DMS 权限项 (sys_menu)**:
- `train:access:query` (门禁与资源映射查看) (**PASS**)
- `train:access:manage` (门禁资源映射维护) (**PASS**)
- `train:access:reconcile` (门禁手动对账触发) (**PASS**)
---
## 4. 孤儿记录审查 (Orphan Count)
执行外键依赖一致性只读排查(共 7 类关联路径):
- `train_enrollment.student_id` ↔ `train_student.s_id`
- `train_enrollment.plan_id` ↔ `train_class_plan.plan_id`
- `train_lesson.plan_course_id` ↔ `train_plan_course.plan_course_id`
- `train_accommodation.enrollment_id` ↔ `train_enrollment.enrollment_id`
- `train_student_checkin.enrollment_id` ↔ `train_enrollment.enrollment_id`
- `train_dorm_auth.accommodation_id` ↔ `train_accommodation.accommodation_id`
- `train_external_operation.door_auth_id` ↔ `train_dorm_auth.auth_id`
- **孤儿统计结论**:
```text
ORPHAN_COUNT = 0
SCHEMA_VALIDATION = PASS
```