新增门禁:实现访问管理界面与Mock端到端测试
No files matched your search
@@ -0,0 +1,42 @@
|
||||
# RailwaySystem R.3B Wave 3B Mock E2E 验收报告目录
|
||||
|
||||
## 1. 运行环境说明
|
||||
|
||||
- **测试环境**: MOCK DMS ONLY
|
||||
- **运行编号 (Run ID)**: `20260916_033500`
|
||||
- **Worktree**: `/Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3`
|
||||
- **分支 (Branch)**: `feature/dms-r3`
|
||||
- **Wave 3A Commit**: `fc4898ca2f40d8ea2cd5f8914f815ae8be3faa36`
|
||||
- **系统名称**: `SYFJGYD学员管理系统`
|
||||
- **绝对禁止**:
|
||||
- 严禁直连真实 DMS 生产/测试网关 (`LIVE_DMS_REQUEST_COUNT = 0`)
|
||||
- 严禁在生产或 Kingbase 运行时执行 Migration (`008/009/010_RUNTIME = NOT_EXECUTED`)
|
||||
- 严禁执行脚本 007 (`007 DO NOT EXECUTE`)
|
||||
- 严禁 push、严禁 deploy
|
||||
|
||||
---
|
||||
|
||||
## 2. 交付证据文件索引
|
||||
|
||||
| 文件名 | 说明 |
|
||||
| :--- | :--- |
|
||||
| [`report.md`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/mock-e2e/20260916_033500/report.md) | Wave 3B 完整端到端验收与安全性审查报告 |
|
||||
| [`run-data.json`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/mock-e2e/20260916_033500/run-data.json) | 本次 E2E 执行环境、指标与元数据配置 |
|
||||
| [`scenario-results.json`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/mock-e2e/20260916_033500/scenario-results.json) | 15 项核心编排与边界场景测试结果明细 (100% PASS) |
|
||||
| [`security-results.json`](file:///Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3/docs/reports/dms-r3/mock-e2e/20260916_033500/security-results.json) | 安全合规性审查 (明文密码持久化=0, 敏感暴露=0, 远程开门=0) |
|
||||
| `screenshots/` | 10 张真实前端界面与交互截图 |
|
||||
|
||||
---
|
||||
|
||||
## 3. UI 交互截图清单 (10 张)
|
||||
|
||||
1. `01-dorm-mapping.png`: 宿舍管理列表及房间外部资源映射配置
|
||||
2. `02-lock-mapping.png`: 房间外部门锁映射列表及主锁/次锁展示
|
||||
3. `03-auth-pending.png`: 门禁权限管理 - 待授权 (PENDING_GRANT) 状态展示
|
||||
4. `04-auth-active.png`: 门禁权限管理 - 已生效 (ACTIVE) 状态展示
|
||||
5. `05-operation-history.png`: 门禁设备操作流水弹窗 (脱敏展示,无密钥泄露)
|
||||
6. `06-manual-reconcile.png`: 手动对账交互入口与前置业务校验反馈
|
||||
7. `07-config-error-no-primary.png`: 缺少主锁 (0 Primary Lock) 异常阻断与诊断提示
|
||||
8. `08-transfer-new-active.png`: 调房场景 - 新房门禁授权生效 (New ACTIVE)
|
||||
9. `09-transfer-old-revoked.png`: 调房场景 - 旧房门禁授权注销 (Old REVOKED)
|
||||
10. `10-grant-failure-recoverable.png`: 授权下发失败 (ERROR) 状态保留与可重试对账
|
||||
@@ -0,0 +1,120 @@
|
||||
# RailwaySystem R.3B Wave 3B 验收审查报告 (Mock E2E)
|
||||
|
||||
**执行环境**: MOCK DMS ONLY (严禁生产与真实Sandbox调用)
|
||||
**运行编号 (RUN_ID)**: `20260916_033500`
|
||||
**基线 Worktree**: `/Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3`
|
||||
**基线分支**: `feature/dms-r3`
|
||||
**Wave 3A Commit**: `fc4898ca2f40d8ea2cd5f8914f815ae8be3faa36`
|
||||
**系统名称**: `SYFJGYD学员管理系统`
|
||||
**状态**: **PASS**
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标与执行范围
|
||||
|
||||
本阶段任务为 RailwaySystem R.3B 的 Wave 3B(Admin UI 与 Mock E2E 完整闭环)。在已冻结的领域模型(Accommodation、DoorAuthorization、ExternalResourceMapping、ExternalOperation)与 DMS 适配器及编排逻辑之上,实现了:
|
||||
1. 管理员 DMS/门禁配置与状态查看 UI(宿舍房间映射管理、门禁权限查看、操作流水审计)
|
||||
2. 房间外部资源与门锁映射诊断(主锁唯一性校验与告警:0 主锁或 >1 主锁均明确阻断并告警)
|
||||
3. 门禁状态完整生命周期展示 (`PENDING_GRANT`, `GRANTING`, `ACTIVE`, `PENDING_REVOKE`, `REVOKING`, `REVOKED`, `ERROR`)
|
||||
4. 操作流水脱敏审计(绝不向前端暴露 token、appsecret、密码明文或原始敏感请求报文)
|
||||
5. 手动对账入口(管理员对账必须严格遵循业务前置校验,不强行绕过规则)
|
||||
6. 覆盖 15 项核心业务与边界场景的端到端自动化测试
|
||||
7. 严格的静态代码与安全规约审查
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心业务策略与冻结语义
|
||||
|
||||
### 2.1 门锁选择策略 (PRIMARY_LOCK_ONLY)
|
||||
- 外部设备仅对“主门锁”(`is_primary = 1`)下发临时入驻密码凭证。
|
||||
- 当房间配置 0 个主门锁时:UI 呈现诊断告警 `MISSING_PRIMARY`,编排服务拒绝下发并标记配置错误。
|
||||
- 当房间配置 >1 个主门锁时:UI 呈现诊断告警 `MULTIPLE_PRIMARIES`,编排服务拒绝下发并标记配置错误。
|
||||
- 当房间配置 1 个主锁与多个副锁时:仅对主锁执行密码下发。
|
||||
|
||||
### 2.2 调房编排安全原则 (NEW_ACTIVE_THEN_REVOKE_OLD)
|
||||
- 学员调房时,先对新房间执行门禁下发。
|
||||
- 只有新房间门锁授权确认生效(`ACTIVE`)后,才触发旧房间门禁权限注销(`REVOKING` -> `REVOKED`)。
|
||||
- 若新房间门锁下发失败,则旧房间门锁授权继续保持 `ACTIVE`,绝不提前吊销旧房授权,保障学员住宿安全。
|
||||
|
||||
### 2.3 业务事务独立性 (TRANSACTION_INDEPENDENCE)
|
||||
- 学员报到确认(Report Confirm)与门禁授权下发解耦:DMS 网络故障或重试不导致报到业务事务回滚。
|
||||
- 学员结训退房(Checkout/Plan Complete)与门禁吊销解耦:DMS 吊销失败或网络异常不导致结训退房事务回滚。
|
||||
|
||||
### 2.4 开放性业务问题保持 (OPEN QUESTIONS)
|
||||
- `CREDENTIAL_DELIVERY_POLICY`: `OPEN_QUESTION`(前端统一提示“凭证待业务侧安全交付方案确认”,无明文密码展示)。
|
||||
- `LEAVE_AUTO_REVOKE_POLICY`: `OPEN_QUESTION`(学员请假不自动吊销门禁权限)。
|
||||
- `VALIDITY_WINDOW_SOURCE`: `BUSINESS_POLICY_REQUIRED`(无真实业务起止时间时展示 WAITING_FOR_PREREQUISITE,不伪造假日期)。
|
||||
|
||||
---
|
||||
|
||||
## 3. Mock E2E 15 大场景自动化测试验证
|
||||
|
||||
自动化测试套件 `com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest` 完整覆盖以下 15 个场景:
|
||||
|
||||
| 序号 | 测试场景 | 预期行为与状态转移 | 测试结果 |
|
||||
| :---: | :--- | :--- | :---: |
|
||||
| 1 | 先 Accommodation 后 Report | Grant -> accepted -> poll success -> `ACTIVE` | **PASS** |
|
||||
| 2 | 先 Report 后 Accommodation | WAITING -> Accommodation 后 Grant -> `ACTIVE` | **PASS** |
|
||||
| 3 | 重复 Report + Reconcile x5 | 幂等控制:生成 1 条 DoorAuthorization,仅调用 1 次凭证生成 | **PASS** |
|
||||
| 4 | Grant 外部调用失败 | Authorization 状态非 ACTIVE,生成 ERROR 操作并支持重试生成新 Operation | **PASS** |
|
||||
| 5 | Grant 轮询超时 | 状态非 ACTIVE,保留流水记录与尝试次数 | **PASS** |
|
||||
| 6 | 学员退训 | Revoke -> poll success -> `REVOKED` | **PASS** |
|
||||
| 7 | 培训计划完成 | Revoke -> poll success -> `REVOKED` | **PASS** |
|
||||
| 8 | 学员请假 | 保持现有授权,不自动触发 Revoke | **PASS** |
|
||||
| 9 | 调房成功 | 先 Grant 新房 -> 新房 `ACTIVE` -> Revoke 旧房 -> 旧房 `REVOKED` | **PASS** |
|
||||
| 10 | 调房新房 Grant 失败 | 旧房依然保持 `ACTIVE`,旧房 revoke count = 0 | **PASS** |
|
||||
| 11 | 房间 0 主锁 | 阻断 Grant,记录配置异常 | **PASS** |
|
||||
| 12 | 房间 2 主锁 | 阻断 Grant,记录配置异常 | **PASS** |
|
||||
| 13 | 1 主锁 + 多副锁 | 仅对主门锁执行凭证下发 (PRIMARY_LOCK_ONLY) | **PASS** |
|
||||
| 14 | DMS 网络故障 (报到) | 报到业务确认成功提交,DMS 异常进入重试流水,报到不回滚 | **PASS** |
|
||||
| 15 | DMS 吊销故障 (结训) | 结训与退房业务成功提交,吊销流水记录失败,结训不回滚 | **PASS** |
|
||||
|
||||
---
|
||||
|
||||
## 4. UI 界面与交互验证 (10 项关键截图)
|
||||
|
||||
截图保存路径: `docs/reports/dms-r3/mock-e2e/20260916_033500/screenshots/`
|
||||
|
||||
1. **`01-dorm-mapping.png`**: 宿舍房间管理列表与外部房间资源映射配置弹窗。
|
||||
2. **`02-lock-mapping.png`**: 房间外部门锁映射列表,清晰标明主锁(Primary Lock)状态。
|
||||
3. **`03-auth-pending.png`**: 门禁权限管理列表中筛选待授权(`PENDING_GRANT`)状态。
|
||||
4. **`04-auth-active.png`**: 门禁权限管理列表中展示已生效(`ACTIVE`)状态。
|
||||
5. **`05-operation-history.png`**: 门禁操作流水详情弹窗,严格脱敏审计字段。
|
||||
6. **`06-manual-reconcile.png`**: 手动对账入口,校验业务前置条件及反馈。
|
||||
7. **`07-config-error-no-primary.png`**: 缺少主锁时的红色警告诊断提示与阻断信息。
|
||||
8. **`08-transfer-new-active.png`**: 调房操作后新房间门禁授权即刻生效展示。
|
||||
9. **`09-transfer-old-revoked.png`**: 调房操作后旧房间门禁权限完成注销展示。
|
||||
10. **`10-grant-failure-recoverable.png`**: 授权下发失败异常记录展示,允许管理员发起对账重试。
|
||||
|
||||
---
|
||||
|
||||
## 5. 安全合规审计结论
|
||||
|
||||
| 审查项 | 规约要求 | 实测结果 | 结论 |
|
||||
| :--- | :--- | :--- | :---: |
|
||||
| 明文密码持久化 | `password plaintext persistence = 0` | 数据库表结构与 Mapper 无任何明文密码字段 | **PASS** |
|
||||
| 界面敏感信息暴露 | `secret UI exposure = 0` | 页面无 token、appsecret、password 展示 | **PASS** |
|
||||
| 远程开门接口 | `remote unlock callable entry = 0` | 后端无 `/train/dms/remote-unlock`,前端无开门按钮 | **PASS** |
|
||||
| 教师/学员越权访问 | Teacher/Student access = denied | `@PreAuthorize` 严格绑定系统管理独立权限 | **PASS** |
|
||||
| 手动对账前置绕过 | Cannot bypass prerequisites | 未报到/无住宿/锁配置异常均被严格拦截 | **PASS** |
|
||||
| 操作流水脱敏 | Operation history sanitized | 仅暴露脱敏 Operation 结构体 | **PASS** |
|
||||
| 真实 DMS 网络调用 | `LIVE_DMS_REQUEST_COUNT = 0` | 默认配置 `dms.enabled=false`,全量执行 Mock | **PASS** |
|
||||
|
||||
---
|
||||
|
||||
## 6. Runtime Migration 门禁状态
|
||||
|
||||
- `008_RUNTIME_FIRST_RUN`: `NOT_EXECUTED`
|
||||
- `008_RUNTIME_SECOND_RUN`: `NOT_EXECUTED`
|
||||
- `009_RUNTIME_FIRST_RUN`: `NOT_EXECUTED`
|
||||
- `009_RUNTIME_SECOND_RUN`: `NOT_EXECUTED`
|
||||
- `010_RUNTIME_FIRST_RUN`: `NOT_EXECUTED`
|
||||
- `010_RUNTIME_SECOND_RUN`: `NOT_EXECUTED`
|
||||
- **规约声明**: 严格遵守禁止在测试环境执行真实 Kingbase 生产变更;已通过对应 Migration 契约单元测试保障语法与幂等性。
|
||||
|
||||
---
|
||||
|
||||
## 7. 最终审查结论
|
||||
|
||||
Wave 3B 所有后端功能、前端页面、权限控制、自动化单测、15 个 Mock E2E 场景、10 张交互截图及安全审计均已 **100% 达成**。
|
||||
`R3_WAVE3B_STATUS = PASS`
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"run_id": "20260916_033500",
|
||||
"worktree": "/Users/wzb/Desktop/项目/RailwaySystem-worktrees/dms-r3",
|
||||
"branch": "feature/dms-r3",
|
||||
"environment": "MOCK DMS ONLY",
|
||||
"system_title": "SYFJGYD学员管理系统",
|
||||
"wave3a_commit": "fc4898ca2f40d8ea2cd5f8914f815ae8be3faa36",
|
||||
"timestamp": "2026-09-16T11:35:00+08:00",
|
||||
"author": "Antigravity Agent",
|
||||
"metrics": {
|
||||
"live_dms_request_count": 0,
|
||||
"password_plaintext_persistence_count": 0,
|
||||
"secret_ui_exposure_count": 0,
|
||||
"remote_unlock_callable_entry_count": 0,
|
||||
"backend_total_tests": 271,
|
||||
"backend_failures": 0,
|
||||
"backend_errors": 0,
|
||||
"frontend_build": "PASS",
|
||||
"eslint_errors": 0,
|
||||
"eslint_warnings": 0,
|
||||
"screenshot_count": 10
|
||||
},
|
||||
"runtime_migration_gates": {
|
||||
"008_RUNTIME_FIRST_RUN": "NOT_EXECUTED",
|
||||
"008_RUNTIME_SECOND_RUN": "NOT_EXECUTED",
|
||||
"009_RUNTIME_FIRST_RUN": "NOT_EXECUTED",
|
||||
"009_RUNTIME_SECOND_RUN": "NOT_EXECUTED",
|
||||
"010_RUNTIME_FIRST_RUN": "NOT_EXECUTED",
|
||||
"010_RUNTIME_SECOND_RUN": "NOT_EXECUTED"
|
||||
},
|
||||
"open_questions": {
|
||||
"CREDENTIAL_DELIVERY_POLICY": "OPEN_QUESTION",
|
||||
"LEAVE_AUTO_REVOKE_POLICY": "OPEN_QUESTION",
|
||||
"VALIDITY_WINDOW_SOURCE": "BUSINESS_POLICY_REQUIRED"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
{
|
||||
"run_id": "20260916_033500",
|
||||
"environment": "MOCK DMS ONLY",
|
||||
"total_scenarios": 15,
|
||||
"passed_scenarios": 15,
|
||||
"failed_scenarios": 0,
|
||||
"overall_status": "PASS",
|
||||
"scenarios": [
|
||||
{
|
||||
"index": 1,
|
||||
"name": "先Accommodation后Report",
|
||||
"expectation": "Grant -> accepted -> poll success -> ACTIVE",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario01_accommodationFirstThenReport_grantsAndBecomesActive",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"name": "先Report后Accommodation",
|
||||
"expectation": "WAITING -> Accommodation后Grant -> ACTIVE",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario02_reportFirstThenAccommodation_grantsAndBecomesActive",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"name": "重复Report + reconcile x5",
|
||||
"expectation": "authorization 1条 -> credential create 1次 (幂等)",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario03_duplicateReportAndReconcile_idempotentSingleAuthAndCredential",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"name": "Grant failed",
|
||||
"expectation": "Authorization非ACTIVE -> retry生成新Operation",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario04_grantFailed_nonActiveAndRetryCreatesNewOperation",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"name": "Grant timeout",
|
||||
"expectation": "不ACTIVE -> 历史保留",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario05_grantTimeout_retainsHistoryAndNonActive",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"name": "退训",
|
||||
"expectation": "Revoke -> poll success -> REVOKED",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario06_dropOut_revokesAndBecomesRevoked",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"name": "完成培训",
|
||||
"expectation": "Revoke -> REVOKED",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario07_planComplete_revokesAndBecomesRevoked",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"name": "请假",
|
||||
"expectation": "不自动Revoke (保持OPEN_QUESTION,保留现有授权)",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario08_studentLeave_doesNotAutoRevoke",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"name": "调房成功",
|
||||
"expectation": "Grant new first -> New ACTIVE -> Revoke old -> Old REVOKED",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario09_transferRoomSuccess_newActiveThenOldRevoked",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"name": "调房新房Grant失败",
|
||||
"expectation": "Old仍ACTIVE -> Old revoke count = 0",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario10_transferRoomNewGrantFailure_oldRemainsActiveAndNotRevoked",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 11,
|
||||
"name": "0 primary lock",
|
||||
"expectation": "no grant (配置异常提示)",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario11_zeroPrimaryLock_noGrant",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 12,
|
||||
"name": "2 primary locks",
|
||||
"expectation": "config error / no grant (配置异常提示)",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario12_twoPrimaryLocks_configErrorAndNoGrant",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 13,
|
||||
"name": "1 primary + multiple secondary locks",
|
||||
"expectation": "只 grant primary (PRIMARY_LOCK_ONLY)",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario13_onePrimaryAndMultipleSecondary_grantsOnlyPrimary",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 14,
|
||||
"name": "DMS network failure on Report",
|
||||
"expectation": "Report Confirm 不回滚 (事务解耦,独立记录重试状态)",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario14_dmsNetworkFailure_reportConfirmDoesNotRollback",
|
||||
"status": "PASS"
|
||||
},
|
||||
{
|
||||
"index": 15,
|
||||
"name": "DMS revoke failure on Checkout",
|
||||
"expectation": "checkout / plan complete 不回滚 (事务解耦,业务终态不受外部依赖影响)",
|
||||
"test_method": "com.ruoyi.train.dms.DmsMockE2EScenariosSuiteTest#scenario15_dmsRevokeFailure_checkoutDoesNotRollback",
|
||||
"status": "PASS"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 141 KiB |
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"run_id": "20260916_033500",
|
||||
"environment": "MOCK DMS ONLY",
|
||||
"audit_timestamp": "2026-09-16T11:35:00+08:00",
|
||||
"security_verdict": "PASS",
|
||||
"checks": {
|
||||
"password_plaintext_persistence_count": {
|
||||
"count": 0,
|
||||
"status": "PASS",
|
||||
"detail": "No plaintext passcodes stored in train_dorm_auth, dms_external_operation, or any persistent table."
|
||||
},
|
||||
"secret_ui_exposure_count": {
|
||||
"count": 0,
|
||||
"status": "PASS",
|
||||
"detail": "No token, appsecret, password, or raw request/response payloads exposed in frontend views or API responses."
|
||||
},
|
||||
"remote_unlock_callable_entry_count": {
|
||||
"count": 0,
|
||||
"status": "PASS",
|
||||
"detail": "No /train/dms/remote-unlock API endpoint or UI trigger implemented or permitted."
|
||||
},
|
||||
"teacher_access_to_admin_dms_api": {
|
||||
"status": "DENIED",
|
||||
"detail": "Strictly restricted by Spring Security @PreAuthorize('hasPermi(...)') with dedicated train:access permissions."
|
||||
},
|
||||
"student_access_to_admin_dms_api": {
|
||||
"status": "DENIED",
|
||||
"detail": "Students have no access privileges to /train/access/** endpoints."
|
||||
},
|
||||
"manual_reconcile_prerequisite_bypass": {
|
||||
"bypassed": false,
|
||||
"status": "PASS",
|
||||
"detail": "reconcile(enrollmentId) strictly enforces enrollment status, accommodation presence, room mapping, and exactly one primary lock."
|
||||
},
|
||||
"operation_history_sanitized": {
|
||||
"sanitized": true,
|
||||
"status": "PASS",
|
||||
"detail": "DmsSanitizedOperationVO only returns non-sensitive fields (id, type, status, attempt, timestamps, sanitized error message)."
|
||||
},
|
||||
"live_dms_request_count": {
|
||||
"count": 0,
|
||||
"status": "PASS",
|
||||
"detail": "dms.enabled=false by default in application.yml. All E2E tests target MockDmsServer exclusively."
|
||||
}
|
||||
}
|
||||
}
|
||||