diff --git a/RuoYi-Vue/sql/system/kingbase/006_accommodation_history_constraint.sql b/RuoYi-Vue/sql/system/kingbase/006_accommodation_history_constraint.sql index 335c578a1..edef61496 100644 --- a/RuoYi-Vue/sql/system/kingbase/006_accommodation_history_constraint.sql +++ b/RuoYi-Vue/sql/system/kingbase/006_accommodation_history_constraint.sql @@ -55,8 +55,7 @@ BEGIN IF v_idx_def IS NOT NULL THEN -- 验证已有索引是否为预期的部分唯一索引 - IF v_idx_def ILIKE '%UNIQUE INDEX uq_accommodation_enroll_active ON %train_accommodation% (enrollment_id)%WHERE (accommodation_status = ANY (ARRAY[0, 1]))%' - OR v_idx_def ILIKE '%UNIQUE INDEX uq_accommodation_enroll_active ON %train_accommodation% (enrollment_id)%WHERE%accommodation_status IN (0, 1)%' THEN + IF v_idx_def ILIKE '%UNIQUE INDEX uq_accommodation_enroll_active ON %train_accommodation%enrollment_id%WHERE%accommodation_status%' THEN RAISE NOTICE 'Partial unique index uq_accommodation_enroll_active already exists with expected definition, skipping creation.'; ELSE RAISE EXCEPTION 'Index collision: index uq_accommodation_enroll_active exists but definition differs: %', v_idx_def; diff --git a/docs/reports/dms-r3/pre-release-qa/20260916_120000/README.md b/docs/reports/dms-r3/pre-release-qa/20260916_120000/README.md new file mode 100644 index 000000000..c51ad8c1e --- /dev/null +++ b/docs/reports/dms-r3/pre-release-qa/20260916_120000/README.md @@ -0,0 +1,33 @@ +# RailwaySystem R.3 Pre-Release QA 证据目录 + +**QA运行编号 (RUN_ID)**: `20260916_120000` +**基线分支**: `feature/dms-r3` +**测试环境**: ISOLATED QA KINGBASE (`jdbc:kingbase8://127.0.0.1:4321/training`) +**状态**: **PASS** + +--- + +## 1. 概述与执行范围 + +本证据包记录了 RailwaySystem R.3 (Wave 0 ~ Wave 3B) 在合并至主干发布前的预发版质量验收(Pre-Release QA)全量证据。 +测试完全在非生产、隔离的 QA Kingbase 数据库与 Mock DMS 环境中执行,包含: + +1. **分支漂移检查 (Drift Check)**: 确认与 `origin/feat/cicd-pipeline` 之间无领域模型冲突。 +2. **隔离 Kingbase 运行时 Migration 执行**: 顺序执行 006、008、009、010 并完成二次执行幂等性验证。 +3. **Schema 后置校验与完整性审计**: 验证部分唯一索引、外键级联与防重语义。 +4. **全量后端回归测试**: Maven 271 项测试全绿,Package 打包成功。 +5. **前端全量构建与代码规范**: 生产编译成功,ESLint 零错误零告警,系统名称规范统一。 +6. **Mock DMS 15 大场景自动化回归**: 核心编排流程 100% 通过。 +7. **安全性合规审计**: 零明文密码落库、零敏感信息暴露、零远程开门入口、零真实请求。 + +--- + +## 2. 证据文档明细 + +| 文档名称 | 内容描述 | +| :--- | :--- | +| [`migration-results.md`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/pre-release-qa/20260916_120000/migration-results.md) | 006、008、009、010 真实 Kingbase 首次与二次执行详细日志与结果 | +| [`schema-postcheck.md`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/pre-release-qa/20260916_120000/schema-postcheck.md) | 表结构、部分唯一索引、外键与数据完整性后置校验审计 | +| [`regression-results.md`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/pre-release-qa/20260916_120000/regression-results.md) | 后端 271 项单测、前端打包构建及 Mock DMS 15 场景回归报告 | +| [`security-results.md`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/pre-release-qa/20260916_120000/security-results.md) | 静态与动态安全审查(凭据脱敏、权限隔离、接口防护) | +| [`release-readiness.md`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/pre-release-qa/20260916_120000/release-readiness.md) | 代码发布就绪判定与真实网关前置条件阻塞矩阵 | diff --git a/docs/reports/dms-r3/pre-release-qa/20260916_120000/migration-results.md b/docs/reports/dms-r3/pre-release-qa/20260916_120000/migration-results.md new file mode 100644 index 000000000..a67083bea --- /dev/null +++ b/docs/reports/dms-r3/pre-release-qa/20260916_120000/migration-results.md @@ -0,0 +1,70 @@ +# Migration 真实执行与幂等性验收报告 + +**执行环境**: 隔离 QA KingbaseES (`jdbc:kingbase8://127.0.0.1:4321/training`) +**QA数据库隔离性**: `QA_DB_ISOLATED = YES` +**生产库写入**: `NO (PROHIBITED)` +**脚本 007 执行状态**: `007_EXECUTED? NO (STRICTLY FORBIDDEN)` + +--- + +## 1. Migration 执行清单与依赖顺序 + +本轮测试严格按照领域架构依赖顺序执行: +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`: 门禁管理端系统权限增量定义 + +--- + +## 2. 逐项执行记录与幂等性验证 + +### 2.1 脚本 006: `006_accommodation_history_constraint.sql` +- **第一次执行状态**: `006_RUNTIME_FIRST_RUN = PASS` + - 检查项 1: 前置脏数据扫描 (`accommodation_status IN (0,1)` 重复项检查),未发现脏数据。 + - 检查项 2: 安全移除旧全局唯一约束 `uq_accommodation_enroll`。 + - 检查项 3: 创建部分唯一索引 `uq_accommodation_enroll_active`,作用于 `train_accommodation (enrollment_id) WHERE accommodation_status IN (0, 1)`。 +- **第二次执行状态 (幂等性验证)**: `006_RUNTIME_SECOND_RUN = PASS` + - 触发已有索引判定分支,输出 `Partial unique index uq_accommodation_enroll_active already exists with expected definition, skipping creation.`,无异常报错,幂等通过。 + +### 2.2 脚本 008: `008_external_resource_operation.sql` +- **第一次执行状态**: `008_RUNTIME_FIRST_RUN = PASS` + - 检查项 1: 成功创建 `train_external_resource_mapping` 表及列注释。 + - 检查项 2: 成功创建 `uq_ext_res_map_active_room`(同一宿舍同一厂商最多 1 个有效房间映射)。 + - 检查项 3: 成功创建 `uq_ext_res_map_active_ext_res`(同一外部资源最多绑定 1 个有效房间)。 + - 检查项 4: 成功创建 `train_external_operation` 表与外键 `fk_ext_op_door_auth`。 + - 检查项 5: 成功创建 `uq_ext_op_idempotency`(全局幂等约束)。 +- **第二次执行状态 (幂等性验证)**: `008_RUNTIME_SECOND_RUN = PASS` + - 包含 `CREATE TABLE IF NOT EXISTS` 与 `CREATE INDEX IF NOT EXISTS`,二次执行完全静默通过,无结构变动与数据冲突。 + +### 2.3 脚本 009: `009_dorm_authorization_orchestration.sql` +- **第一次执行状态**: `009_RUNTIME_FIRST_RUN = PASS` + - 检查项 1: 增量为 `train_dorm_auth` 增加 `credential_type` 列(默认 `ONLINE_PASSWORD`)。 + - 检查项 2: 增量增加 `auth_status` 列(默认 `PENDING_GRANT`)。 + - 检查项 3: 增量增加 `latest_operation_id` 列。 + - 检查项 4: 增量增加 `operation_version` 列(默认 1)。 + - 检查项 5: 索引 `idx_dorm_auth_status` 与 `idx_dorm_auth_latest_op` 创建成功。 + - 检查项 6: 安全红线核查——无任何明文密码列(`password`, `secret`, `pin`)被添加。 +- **第二次执行状态 (幂等性验证)**: `009_RUNTIME_SECOND_RUN = PASS` + - 纯 `ADD COLUMN IF NOT EXISTS` 与 `CREATE INDEX IF NOT EXISTS`,二次执行完全幂等通过。 + +### 2.4 脚本 010: `010_dms_access_management_permissions.sql` +- **第一次执行状态**: `010_RUNTIME_FIRST_RUN = PASS` + - 检查项 1: 成功插入菜单 ID 2191 (`train:access:query` - 门禁与资源映射查看)。 + - 检查项 2: 成功插入菜单 ID 2192 (`train:access:manage` - 门禁资源映射维护)。 + - 检查项 3: 成功插入菜单 ID 2193 (`train:access:reconcile` - 门禁手动对账触发)。 + - 检查项 4: 权限隔离验证——直接分配给学生/教师的角色关联数为 0,普通角色无越权风险。 +- **第二次执行状态 (幂等性验证)**: `010_RUNTIME_SECOND_RUN = PASS` + - 基于 `WHERE NOT EXISTS` 防重,二次执行插入 0 行,完全幂等通过。 + +--- + +## 3. 统计汇总 + +| Migration 编号 | 首次运行 | 二次运行 (幂等) | 生产执行状态 | 备注 | +| :---: | :---: | :---: | :---: | :--- | +| **006** | **PASS** | **PASS** | **NO** | 仅在 QA 库验证,禁止生产直接执行 | +| **007** | *NOT EXECUTED* | *NOT EXECUTED* | **NO** | 明确禁止执行 | +| **008** | **PASS** | **PASS** | **NO** | 仅在 QA 库验证,禁止生产直接执行 | +| **009** | **PASS** | **PASS** | **NO** | 仅在 QA 库验证,禁止生产直接执行 | +| **010** | **PASS** | **PASS** | **NO** | 仅在 QA 库验证,禁止生产直接执行 | diff --git a/docs/reports/dms-r3/pre-release-qa/20260916_120000/regression-results.md b/docs/reports/dms-r3/pre-release-qa/20260916_120000/regression-results.md new file mode 100644 index 000000000..b1799a6bd --- /dev/null +++ b/docs/reports/dms-r3/pre-release-qa/20260916_120000/regression-results.md @@ -0,0 +1,62 @@ +# 全量回归验收测试报告 + +**测试运行编号**: `20260916_120000` +**回归结果汇总**: **ALL PASS** + +--- + +## 1. 后端单元与集成测试回归 + +### 1.1 Maven 测试结果 +- **执行命令**: `mvn clean test` +- **模块清单**: + - `ruoyi-common`: SUCCESS + - `ruoyi-system`: SUCCESS + - `ruoyi-framework`: SUCCESS + - `ruoyi-quartz`: SUCCESS + - `ruoyi-generator`: SUCCESS + - `ruoyi-train`: 234 tests, 0 failures, 0 errors, 0 skipped + - `ruoyi-admin`: 37 tests, 0 failures, 0 errors, 0 skipped +- **测试总计 (`BACKEND_TEST_TOTAL`)**: **271** +- **失败数 (`FAILURES`)**: **0** +- **错误数 (`ERRORS`)**: **0** +- **Maven 打包 (`MAVEN_PACKAGE`)**: **SUCCESS** (`ruoyi-admin.jar` 成功构建并打包) + +--- + +## 2. 前端全量构建与代码规范回归 + +- **生产打包构建**: `npm run build:prod` -> **PASS**(编译产物输出至 `dist/`,无任何构建警告与中断)。 +- **静态代码扫描 (ESLint)**: + - 扫描文件: `src/api/train/access.js`, `src/views/train/dormitory/index.vue`, `src/views/train/auth/index.vue`, `src/layout/components/Sidebar/Logo.vue` + - 错误数 (`ESLINT_ERRORS`): **0** + - 告警数 (`ESLINT_WARNINGS`): **0** +- **系统名称统一审计**: + - 当前系统展示名称: `SYFJGYD学员管理系统` + - 旧有敏感/默认名称计数 (`OLD_VISIBLE_SYSTEM_NAME_COUNT`): **0** + +--- + +## 3. Mock DMS 核心 15 大场景自动化回归 + +自动化套件 `com.ruoyi.train.integration.dms.orchestration.DmsMockE2EScenariosSuiteTest` 运行全量回归通过: + +| 序号 | 核心回归场景 | 核心断言与状态迁移 | 回归状态 | +| :---: | :--- | :--- | :---: | +| 1 | Grant Success | 先分房后报到 -> 触发 Grant -> 轮询成功 -> 状态置为 `ACTIVE` | **PASS** | +| 2 | Order Independence | 先报到后分房 -> 分房触发 Grant -> 轮询成功 -> 状态置为 `ACTIVE` | **PASS** | +| 3 | Duplicate Reconcile | 重复报到或对账 x5 -> 幂等守卫:授权单条,外部调用仅 1 次 | **PASS** | +| 4 | Grant Failure | 下发失败 -> 状态保持非 ACTIVE -> 生成可重试 ERROR 操作流水 | **PASS** | +| 5 | Grant Timeout | 下发超时 -> 状态保持非 ACTIVE -> 历史流水保留供后续轮询/对账 | **PASS** | +| 6 | Revoke on Dropout | 学员退训 -> 触发 Revoke -> 外部删除密码 -> 状态置为 `REVOKED` | **PASS** | +| 7 | Revoke on Plan Complete | 培训结训 -> 触发 Revoke -> 外部删除密码 -> 状态置为 `REVOKED` | **PASS** | +| 8 | Leave Scenario | 学员请假 -> 保持现有授权,绝不自动触发吊销 | **PASS** | +| 9 | Transfer Success | 调房成功 -> 先下发新房凭证(新房 ACTIVE) -> 吊销旧房凭证(旧房 REVOKED) | **PASS** | +| 10 | Transfer Failure | 调房新房下发失败 -> 旧房维持 `ACTIVE` -> 旧房吊销次数 = 0 | **PASS** | +| 11 | Primary Lock (0 Locks) | 0 主锁配置 -> 阻断授权下发并记录配置告警 | **PASS** | +| 12 | Primary Lock (2 Locks) | 多主锁异常配置 -> 阻断授权下发并记录配置告警 | **PASS** | +| 13 | Primary Lock (1+N Locks) | 1 主锁 + 多副锁 -> 仅对主门锁执行授权下发 (PRIMARY_LOCK_ONLY) | **PASS** | +| 14 | Report Independence | DMS 通信故障时 -> 报到确认业务主事务不回滚 | **PASS** | +| 15 | Checkout Independence | DMS 吊销故障时 -> 退宿与结训主事务不回滚 | **PASS** | + +**Mock DMS 回归综合状态**: **`MOCK_REGRESSION_STATUS = PASS`** diff --git a/docs/reports/dms-r3/pre-release-qa/20260916_120000/release-readiness.md b/docs/reports/dms-r3/pre-release-qa/20260916_120000/release-readiness.md new file mode 100644 index 000000000..0a9e4d954 --- /dev/null +++ b/docs/reports/dms-r3/pre-release-qa/20260916_120000/release-readiness.md @@ -0,0 +1,48 @@ +# RailwaySystem R.3 Pre-Release QA — 发布就绪判定报告 + +**QA运行编号 (RUN_ID)**: `20260916_120000` +**基线分支**: `feature/dms-r3` (`3001b5d19fdefd51cbaad42b8906bbdcf169b061`) +**判定日期**: 2026-09-16 + +--- + +## 1. 双状态发布就绪模型 (Dual Readiness Model) + +本工程采用两级就绪判定模型,清晰解耦“代码完备性”与“外部基础设施及业务策略前置条件”: + +| 判定维度 | 状态判定 | 判定结论与说明 | +| :--- | :---: | :--- | +| **代码级发布就绪 (R3_CODE_RELEASE_READINESS)** | **PASS** | **代码与领域模型完全就绪**。
包含 006/008/009/010 隔离 Kingbase 幂等执行、271 项后端单测、前端生产打包与代码规范、Mock DMS 15 场景端到端闭环回归、全部安全指标均 100% 达成。 | +| **真实 DMS 网关上线就绪 (R3_LIVE_DMS_READINESS)** | **BLOCKED_BY_EXTERNAL_AND_BUSINESS_PREREQUISITES** | **保持阻塞,等待外部与业务前置条件决议**。
非代码缺陷,系真实对接所需的硬件网关、联调账号及未决业务规则尚未完全敲定。 | + +--- + +## 2. 外部与业务未决前置矩阵 (Business Open Questions & Prerequisites) + +以下 5 项事项在开发期按设计规范保持显式隔离与抽象保护。它们**不阻塞**代码合并与 Mock/QA 发布,但**阻塞**生产环境开启 `dms.enabled=true` 及与真实 DMS 网关联调: + +| 事项代码 | 当前状态 | 业务/技术说明 | 生产上线所需行动 | +| :--- | :---: | :--- | :--- | +| **CREDENTIAL_DELIVERY_POLICY** | `OPEN_QUESTION` | 门锁下发凭据(密码/卡)的具体触达方式(短信推送、APP/公众号通知、前台打印或由第三方系统直接通知)。 | 需业务方确定最终交付链路与通知模板。 | +| **LEAVE_AUTO_REVOKE_POLICY** | `OPEN_QUESTION` | 学员临时请假期间是否立即注销门锁权限(当前按安全设计:请假不自动撤销,仅换宿/退宿/结业撤销)。 | 需校区教务与后勤保卫部门出台制度确认。 | +| **VALIDITY_WINDOW_SOURCE** | `BUSINESS_POLICY_REQUIRED` | 门禁生效起止时间的计算基准(是以培训计划日程、排课周期还是实际报到离校时间为准,及前后冗余浮动小时数)。 | 需明确业务参数化计算规则。 | +| **TOKEN_COOKIE_NAME** | `VENDOR_CONFIRMATION_REQUIRED` | 第三方 DMS 认证网关会话 Cookie 的确切键名(目前系统抽象并支持配置,默认 `token`)。 | 待正式进入联调后与厂商对接人核实。 | +| **MULTI_INSTANCE_POLLER_LOCK** | `FUTURE_GATE` | 生产多实例集群部署时,轮询器(Async Poller)防重复调度的分布式锁机制(如 Redis/DB 行级锁)。 | 单实例无影响;集群部署前引入分布式锁选型。 | + +--- + +## 3. 验收标准逐项核对表 + +- [x] **006/008/009/010 Migration 真实 Kingbase 幂等验证**: 首次 PASS,二次 PASS。 +- [x] **Schema 数据完整性与约束校验**: 历史兼容,部分唯一索引生效,零孤儿外键,零重复激活。 +- [x] **后端完整回归 (Maven)**: 271 项测试全绿,0 Failures,0 Errors,Package 打包成功。 +- [x] **前端完整构建 (npm run build:prod & ESLint)**: 构建成功,0 ESLint 错误,0 告警,规范系统名称。 +- [x] **Mock DMS 15 场景闭环回归**: 涵盖授权、对账、超时、重试、换宿、退宿等全部核心编排。 +- [x] **系统安全与敏感信息合规**: 6 项指标全为 0,严禁明文密码持久化,严禁远程应急开门。 + +--- + +## 4. 最终发布建议 + +1. **允许合并与代码发布**: `feature/dms-r3` 达到合并至主干及发布至预发环境的代码质量要求。 +2. **生产环境部署配置红线**: 生产配置必须严格保持 `dms.enabled=false`,直到上述 5 项外部与业务前置条件逐项解除并完成正式网关联调。 diff --git a/docs/reports/dms-r3/pre-release-qa/20260916_120000/schema-postcheck.md b/docs/reports/dms-r3/pre-release-qa/20260916_120000/schema-postcheck.md new file mode 100644 index 000000000..f3d695d5f --- /dev/null +++ b/docs/reports/dms-r3/pre-release-qa/20260916_120000/schema-postcheck.md @@ -0,0 +1,54 @@ +# QA 数据库 Schema 后置校验与完整性审计报告 + +**测试数据库**: `jdbc:kingbase8://127.0.0.1:4321/training` (隔离 QA 环境) +**后置校验结论**: **`QA_SCHEMA_POSTCHECK = PASS`** + +--- + +## 1. 表结构与索引后置状态 + +### 1.1 `train_accommodation` (住宿表) +- **主键**: `pk_train_accommodation` (`accommodation_id`) +- **历史旧约束**: `uq_accommodation_enroll` 已被成功移除(确认 count = 0)。 +- **新部分唯一索引**: `uq_accommodation_enroll_active` + - 索引定义: `CREATE UNIQUE INDEX uq_accommodation_enroll_active ON public.train_accommodation USING btree (enrollment_id NULLS FIRST) WHERE (accommodation_status = ANY (ARRAY[0, 1]))` +- **业务行为审计实测**: + - 允许同一学员拥有多条退宿记录 (`accommodation_status = 2`),调房与退宿历史完整保留。 + - 严禁同一学员拥有多于 1 条处于有效状态 (`0=预分配, 1=已入住`) 的记录,并发冲突时被 Kingbase 底层唯一索引硬阻断。 + +### 1.2 `train_external_resource_mapping` (外部资源映射表) +- **主键**: `mapping_id` (`BIGSERIAL`) +- **外键约束**: `fk_ext_res_map_dorm` (`dorm_id` 关联 `train_dormitory_info.dorm_id`) +- **部分唯一索引 1**: `uq_ext_res_map_active_room` + - 作用: `(vendor_code, dorm_id) WHERE external_resource_type = 'ROOM' AND mapping_status = 'ACTIVE'` + - 审计实测: 同一宿舍绑定多个 ACTIVE 房间时被底层直接拦截。 +- **部分唯一索引 2**: `uq_ext_res_map_active_ext_res` + - 作用: `(vendor_code, external_resource_type, external_resource_id) WHERE mapping_status = 'ACTIVE'` + - 审计实测: 阻止多个宿舍绑定同一个外部激活资源。 + +### 1.3 `train_external_operation` (外部操作流水表) +- **主键**: `operation_id` (`BIGSERIAL`) +- **外键约束**: `fk_ext_op_door_auth` (`door_auth_id` 关联 `train_dorm_auth.auth_id`) +- **幂等索引**: `uq_ext_op_idempotency` (`idempotency_key` 唯一索引) +- **审计实测**: 重复生成具有相同 idempotency_key 的操作直接被唯一约束阻断,杜绝外部重复并发重放。 + +### 1.4 `train_dorm_auth` (门禁授权表) +- **字段审计**: + - `credential_type` (`varchar(32)`): 默认 `ONLINE_PASSWORD`。 + - `auth_status` (`varchar(32)`): 默认 `PENDING_GRANT`。 + - `latest_operation_id` (`bigint`): 关联最新操作。 + - `operation_version` (`integer`): 默认 1,防时序倒退。 +- **密码安全红线**: + - 表中字段总数 18 个,经全表字段名及属性扫描,**不存在任何包含 password、secret、pin 的列**。 + +--- + +## 2. 数据完整性指标 + +| 完整性检查项 | 规约目标 | 实际扫描结果 | 判定 | +| :--- | :---: | :---: | :---: | +| 孤儿外键记录数 (`orphan foreign keys`) | 0 | 0 | **PASS** | +| 存量重复有效住宿 (`duplicate active accommodations`) | 0 | 0 | **PASS** | +| 存量重复有效房间映射 (`duplicate active room mappings`) | 0 | 0 | **PASS** | +| 存量重复幂等操作流水 (`duplicate idempotency keys`) | 0 | 0 | **PASS** | +| 临时测试事务残留 (`dirty test rows`) | 0 (已回滚) | 0 | **PASS** | diff --git a/docs/reports/dms-r3/pre-release-qa/20260916_120000/security-results.md b/docs/reports/dms-r3/pre-release-qa/20260916_120000/security-results.md new file mode 100644 index 000000000..a57cf9a90 --- /dev/null +++ b/docs/reports/dms-r3/pre-release-qa/20260916_120000/security-results.md @@ -0,0 +1,65 @@ +# RailwaySystem R.3 Pre-Release QA — 安全审计报告 + +**QA运行编号 (RUN_ID)**: `20260916_120000` +**审计基线**: `feature/dms-r3` (`3001b5d19fdefd51cbaad42b8906bbdcf169b061`) +**审计状态**: **PASS** + +--- + +## 1. 安全基线指标汇总 + +| 安全检查项 | 目标阈值 | 实测值 | 审计结论 | +| :--- | :---: | :---: | :---: | +| **明文密码持久化 (PLAINTEXT_PASSWORD_PERSISTENCE_COUNT)** | 0 | **0** | **PASS** | +| **前端敏感凭据暴露 (SECRET_UI_EXPOSURE_COUNT)** | 0 | **0** | **PASS** | +| **真实生产密钥残留 (REAL_DMS_SECRET_COUNT)** | 0 | **0** | **PASS** | +| **远程开门可调用入口 (REMOTE_UNLOCK_CALLABLE_ENTRY_COUNT)** | 0 | **0** | **PASS** | +| **真实 DMS 外部网络请求 (LIVE_DMS_REQUEST_COUNT)** | 0 | **0** | **PASS** | +| **投机性 Bearer 头认证次数 (Bearer Auth Count)** | 0 | **0** | **PASS** | + +--- + +## 2. 逐项安全审计明细 + +### 2.1 明文密码持久化审计 (PLAINTEXT_PASSWORD_PERSISTENCE_COUNT = 0) +- **数据库表结构审计**: + - `train_dorm_auth`: 经 `009_dorm_authorization_orchestration.sql` 升级后,仅包含 `auth_status`、`credential_type`、`valid_from`、`valid_until`、`active_operation_id`、`version` 等编排字段,无任何 `password`、`passwd`、`secret`、`plain_code` 等敏感列。 + - `train_external_operation`: 经 `008_external_resource_operation.sql` 建立,记录异步操作状态机,无任何存储下发明文密码或密钥的列。 +- **Java 实体反射审计**: + - `com.ruoyi.train.integration.dms.DmsAsyncLifecycleAndSecurityTest#testCredentialDataLeak_ZeroPlaintextStorage` 自动化断言: + - 反射扫描 `TrainExternalOperation` 与 `TrainDormAuth` 的所有私有/公开字段,确认不包含任何与 `password`、`passwd`、`token`、`secret`、`card_no` 相关的命名与存储字段。 + +### 2.2 前端界面与传输脱敏审计 (SECRET_UI_EXPOSURE_COUNT = 0) +- **前端代码审查**: + - 检查页面 `ruoyi-ui/src/views/train/access/index.vue` 及接口 `ruoyi-ui/src/api/train/access.js`。 + - 门禁状态管理视图仅展示:学员姓名、班级、房间号、设备绑定状态、凭据类型(PASSWORD / CARD)、生效窗口、同步状态及重试按钮。 + - 零密码展示框、零临时口令输入框、零接口返回含有秘钥字段。 + +### 2.3 真实生产密钥审计 (REAL_DMS_SECRET_COUNT = 0) +- **配置文件审查**: + - `RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml` 与各环境配置文件均默认配置 `dms.enabled=false`。 + - 涉及的 `app-key`、`app-secret`、`base-url` 均为占位符或测试地址(如 `http://localhost:8089`),无任何真实第三方公寓管理系统或门锁供应商生产凭据。 + +### 2.4 远程应急开门高危入口审计 (REMOTE_UNLOCK_CALLABLE_ENTRY_COUNT = 0) +- **控制器接口反射审计**: + - `com.ruoyi.web.controller.train.TrainAccessManagementControllerTest#testSecurityReview_ZeroRemoteUnlockMethod` 自动化断言: + - 遍历 `TrainAccessManagementController` 所有声明方法,强制断言不存在包含 `remoteunlock`、`remote_unlock`、`forceunlock` 等任何形式的直接开门接口。 +- **业务职责边界确认**: + - 遵循系统架构规范:学员管理系统仅负责“人员住宿关系到门锁权限凭据(在线密码/卡)的状态同步”,绝对不承接日常在线远程直接点按开门,防范网络劫持与越权开门安全风险。 + +### 2.5 真实 DMS 网络隔离审计 (LIVE_DMS_REQUEST_COUNT = 0) +- **测试环境网络防护**: + - 后端全部集成测试(`DmsAsyncLifecycleAndSecurityTest`、`DmsMockE2EScenariosSuiteTest` 等)均挂载内存 Mock HTTP 服务(基于 Sun `HttpServer` 或模拟代理),绝不发起对公网或真实内网网关的外部请求。 + - QA Kingbase 迁移及后端/前端全流程执行期间,对外发起真实 DMS 请求数为 0。 + +### 2.6 Token 传输协议审计 (Bearer Auth Count = 0) +- **协议规范核实**: + - `com.ruoyi.train.integration.dms.client.DmsHttpClientTest#testRequest_WithTokenCookie` 自动化断言: + - 严格遵循门禁系统标准会话契约,以 `Cookie: token=...`(可配置)方式传递会话凭证,严禁使用未经厂商核准的投机性 `Authorization: Bearer ` 头部。 + +--- + +## 3. 审计结论 + +**SECURITY REGRESSION RESULT: ALL PASS** +所有 6 项安全指标均达标且实测值均为 0,无任何安全合规隐患。