新增门禁:实现适配器、令牌与异步操作集成
This commit is contained in:
1 parent
1332b45fae
commit
bb16b0b875
54 files changed
+4215
-1
No files matched your search
@@ -67,3 +67,19 @@
|
||||
- **远程开锁 (`remote-unlock`)**:属于主动设备控制,具有物理安全风险。一期**严禁**作为学员常规功能,仅设计受控管理员权限与两票制审计,标记为 `P2_FUTURE / 受控应急`。
|
||||
- **取电开关全套接口 (`powerswitch/*`)**:沈阳房建公寓段学员管理系统核心是学员学籍、住宿、报到业务,强行纳入取电开关将带来硬件施工与网络调试成本,确定归入 `P2_FUTURE`。
|
||||
- **二维码钥匙 (`qrcode/create`)**:官方文档中明确包含端点定义 (`POST /rest/doorlock/qrcode/create` 与 `POST /rest/qrcode/delete`),分类为 `DOCUMENTED`;但其响应示例存在数据污染(`typeStr: "Online Card"`)且未见二维码载荷内容,其实际方案可行性属于 `NEEDS_BUSINESS_CONFIRMATION`,一期推荐保持使用在线密码作为 Pilot 方案。
|
||||
|
||||
---
|
||||
|
||||
## 4. Wave 2 Implementation Status (Wave 2 implemented against Mock DMS only)
|
||||
- **实现范围**:
|
||||
1. `POST /public/rest/third-party-app/token/get` (`DmsTokenManager`)
|
||||
2. `POST /rest/place/building/list`, `floor/list`, `room/list`, `room/get` (`DmsLocationClient` / `ExternalLocationGateway`)
|
||||
3. `POST /rest/doorlock/list` (`DmsDoorLockClient` / `ExternalDoorLockGateway`,支持 0、1、多把门锁)
|
||||
4. `POST /rest/doorlock/online-password-key/create` (`DmsPasswordClient` / `ExternalCredentialGateway`,支持 4~8 位,密码零持久化)
|
||||
5. `POST /rest/doorlock/online-password/delete` (`DmsPasswordClient` / `ExternalCredentialGateway`)
|
||||
6. `POST /rest/doorlock/query-operation-status` (`DmsOperationStatusClient` / `DmsOperationStatusMapper` / `DmsOperationPoller`)
|
||||
- **测试与运行纪律**:
|
||||
- 全部自动化测试均在本地内嵌 `MockDmsServer` 下运行。
|
||||
- `LIVE_DMS_REQUEST_COUNT = 0`(严禁向真实 DMS 产生任何调用)。
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`。
|
||||
@@ -138,3 +138,16 @@ sequenceDiagram
|
||||
### 5.1 恢复红线守则
|
||||
- **单次重试原则**:因 401 触发的自动重试**上限严格为 1 次**。严禁设计任何 `while(true)` 或大于 1 次的递归重试,防止由于网络异常或密码错误引发死循环或轰炸外部服务器。
|
||||
- **业务解耦原则**:若重新登录失败,DmsAdapter 应抛出封装后的 `DmsAuthenticationException`,将门禁任务状态置为 `RETRY_WAIT` 或 `FAILED`,**绝不可向上传播导致本地住宿分配主事务发生回滚**。
|
||||
|
||||
---
|
||||
|
||||
## 6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
||||
- **Token 核心实现**:
|
||||
- `TOKEN_TRANSPORT_MODEL` = `Cookie: token={token}`(严禁使用未经证明的 `Authorization: Bearer`)。
|
||||
- `TOKEN_CACHE_MODEL` = `SINGLE_PROCESS_IN_MEMORY`(全应用单一集中缓存,严禁各个客户端分散维护)。
|
||||
- `TOKEN_SINGLE_FLIGHT_MODEL` = `REENTRANT_LOCK_DCL`(ReentrantLock + 双重检查锁定,20 线程并发获取 Token 实测远程登录仅 1 次)。
|
||||
- `TOKEN_TTL_MODEL` = `7200S_WITH_REFRESH_SKEW`(默认提前 120 秒在滑动窗口内平滑单飞刷新)。
|
||||
- `SUCCESSFUL_API_EXTENDS_LOCAL_TTL` = `YES`(成功调用 DMS API 触发 `tokenManager.markSuccessfulUse()` 顺延本地失效时间戳)。
|
||||
- `AUTH_FAILURE_REFRESH_MODEL` = 401 触发集中 `invalidateToken()`,下一次调用单飞获取新令牌,杜绝 login storm。
|
||||
- `AMBIGUOUS_MUTATION_AUTO_RETRY` = `NO`(写操作读取超时绝对不自动重试,规避重复凭据下发风险)。
|
||||
- **验证结论**:自动化并发测试(20 线程单飞登录、提前刷新单飞、401 自愈)全部通过,仅针对本地 `MockDmsServer` 验证,`LIVE_DMS_REQUEST_COUNT = 0`。
|
||||
@@ -186,3 +186,24 @@ ruoyi-train
|
||||
- 本 Wave 严格保持 `DMS_HTTP_CLIENT_COUNT = 0`,`DMS_TOKEN_MANAGER_COUNT = 0`。
|
||||
- 零 RestTemplate / WebClient / HttpClient 网络调用,零明文敏感凭据。
|
||||
- **数据库 Migration**:`008_external_resource_operation.sql` 验证通过,生产库未执行。
|
||||
|
||||
---
|
||||
|
||||
## 6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
||||
- **阶段状态**:Wave 2 implemented against Mock DMS only。
|
||||
- **适配层核心交付清单**:
|
||||
1. `config/DmsProperties`:受控配置中心,`dms.enabled = false`(安全默认),支持参数化超时、提前刷新窗口、Token Cookie 头名称。
|
||||
2. `auth/DmsTokenManager`:全应用唯一集中 Token 缓存,基于 ReentrantLock + DCL 的 Single-Flight 并发互斥锁,支持滑动延展 (`markSuccessfulUse`) 与 401 集中失效自愈。
|
||||
3. `client/DmsHttpClient`:基础底层 HTTP 客户端,统一 Cookie 传输,脱敏日志(密码、Token、Secret 全程保护),写操作读取超时严禁盲目自动重试 (`AMBIGUOUS_MUTATION_AUTO_RETRY = NO`)。
|
||||
4. `client/DmsLocationClient` 与 `gateway/ExternalLocationGateway`:位置资源查询与 Place 空间定位。
|
||||
5. `client/DmsDoorLockClient` 与 `gateway/ExternalDoorLockGateway`:门锁适配器,严格支持 0 把锁(返回空列表,非 NPE)、1 把锁与多把锁(完整返回全部锁)。
|
||||
6. `client/DmsPasswordClient` 与 `gateway/ExternalCredentialGateway`:在线限时密码创建与删除适配器,支持 4~8 位数字,密码明文内存短暂留存,零落库零输出。
|
||||
7. `client/DmsOperationStatusClient` 与 `gateway/DmsOperationStatusMapper`:异步状态查询与集中映射器(success->SUCCESS, undone->PENDING, failed->FAILED, timeout->TIMEOUT, 未知状态->UNKNOWN 严禁判定为 SUCCESS)。
|
||||
8. `poller/DmsOperationPoller`:异步对账轮询调度器,仅在 `dms.enabled=true` 启用,单进程并发防重,终态不可篡改保护,错误分类退避持久化。
|
||||
9. `mock/MockDmsServer`:轻量内嵌测试服务器,精准模拟 DMS 服务端登录互斥、读超时、多锁/零锁与状态流转。
|
||||
- **环境纪律与迁移标记**:
|
||||
- `DMS_DEFAULT_ENABLED = FALSE`
|
||||
- `LIVE_DMS_REQUEST_COUNT = 0`
|
||||
- `FRONTEND_MODIFIED = 0`
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
||||
@@ -147,3 +147,15 @@ stateDiagram-v2
|
||||
- **轮询检索接口 (`PENDING_OPERATION_QUERY`)**:
|
||||
- 交付 `selectPendingPollOperations`,检索处于 `ACCEPTED`、`PENDING`、`RETRY_WAIT` 且 `next_poll_time <= NOW()` 的操作记录。
|
||||
- 为 Wave 2 调度器提供完整数据准备,本 Wave 保持 0 调度器运行、0 HTTP 调用。
|
||||
|
||||
---
|
||||
|
||||
## 6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
||||
- **阶段状态**:Wave 2 implemented against Mock DMS only。
|
||||
- **状态机与对账调度实现**:
|
||||
- `DmsOperationStatusMapper`:集中映射供应商返回的设备操作状态(`success` -> `SUCCESS`, `undone` -> `PENDING`, `failed` -> `FAILED`, `timeout` -> `TIMEOUT`),未知供应商状态一律归为 `UNKNOWN`,严禁判定为 `SUCCESS`。
|
||||
- `ACCEPTED != SUCCESS` 原则强制落地:下发/删除密码接口 HTTP 200 响应仅代表平台受理并取得 `operationId`(本地状态记录为 `ACCEPTED`),设备执行事实必须由后续 Poller 轮询确认达成 `SUCCESS`。
|
||||
- `DmsOperationPoller`:自动从 `listPendingPollOperations` 检索任务,支持 10 秒初始延迟,单进程并发防重,终态保护不可篡改,网络错误转入 `RETRY_WAIT` 退避。
|
||||
- **迁移标记**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`。
|
||||
@@ -164,3 +164,15 @@ sequenceDiagram
|
||||
- **重试审计与不可变性**:
|
||||
- 终态记录不可覆写:每次重试调用通过 `createRetryOperation` 独立创建自增 `attempt_count` 的新记录。
|
||||
- 保留完整排障轨迹:`last_error_code` 与 `last_error_message` 详细保留每次失败现场,满足段级安全审计与对账需求。
|
||||
|
||||
---
|
||||
|
||||
## 7. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
||||
- **阶段状态**:Wave 2 implemented against Mock DMS only。
|
||||
- **重试与幂等安全落地**:
|
||||
- `AMBIGUOUS_MUTATION_AUTO_RETRY = NO`:写操作(如密码创建)发生网络读取超时(Read Timeout)时,底层 `DmsHttpClient` 坚决抑制自动重试,`passwordCreatePostCounter = 1`,避免在门锁端产生重复凭据。
|
||||
- 轮询指数退避:`DmsOperationPoller` 在遭遇网络抖动时将状态置为 `RETRY_WAIT`,基于 `Math.pow(2, attemptCount) * 5` 计算下次轮询时间并递增 `attempt_count`,防止高频风暴轮询。
|
||||
- 401 集中重试:仅在明确认证失败且为安全查询时才发起 1 次 Token 刷新与重试;写操作 401 则集中失效并向外抛错,由上层流水对账接管。
|
||||
- **迁移标记**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`。
|
||||
@@ -115,3 +115,15 @@
|
||||
### 5.2 响应数据持久化策略 (`Response Sanitization Policy`)
|
||||
- **禁止项**:绝不无脑把外部 DMS 返回的几千字节原始 JSON 直接整体塞入数据库的文本列中。
|
||||
- **要求**:仅抽取核心对账字段进行结构化持久化;若出于排障目的保留原始请求与响应报文快照,**必须先经过脱敏过滤器(剔除明文密码与密钥)**后再写入 `sanitized_response_payload`。
|
||||
|
||||
---
|
||||
|
||||
## 6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
||||
- **阶段状态**:Wave 2 implemented against Mock DMS only。
|
||||
- **安全红线核验结论**:
|
||||
- `PLAINTEXT_PASSWORD_PERSISTENCE_COUNT = 0`:反射测试断言 `TrainExternalOperation` 与 `TrainDormAuth` 绝无密码明文属性,实体中仅保留 `external_key_id`。
|
||||
- `SECRET_LOGGING_COUNT = 0`:`DmsHttpClient` 与 `DmsOperationPoller` 全局应用 `sanitize` 过滤器,请求头与请求体中的 `password`、`token`、`appsecret` 均被强制替换为 `[PROTECTED]`。
|
||||
- `LIVE_DMS_REQUEST_COUNT = 0`:开发与自动化测试期间严格仅使用内嵌 `MockDmsServer`,真实 DMS 地址仅保留于默认配置占位符,未发起任何公网请求。
|
||||
- **迁移标记**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`。
|
||||
@@ -115,3 +115,15 @@
|
||||
[写入 train_external_resource_mapping, 完成两套系统物理基线的稳定锁定]
|
||||
```
|
||||
- **核心保障**:同步操作仅建立与更新映射表,**绝不自动删除或篡改本地 `train_dormitory_info` 的基础房源台账**。本地房源依然是学员管理系统的独立主数据。
|
||||
|
||||
---
|
||||
|
||||
## 6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
||||
- **阶段状态**:Wave 2 implemented against Mock DMS only。
|
||||
- **Controller 与 UI 边界红线**:
|
||||
- `CONTROLLER_COUNT` = 0(本 Wave 严禁新增任何 `/train/dms/**` 控制器,所有适配层仅供 Service/Test 内部调用)。
|
||||
- `FRONTEND_MODIFIED` = 0(前端与 `build_ui` 修改文件数严格为 0)。
|
||||
- `REMOTE_UNLOCK_CONTROLLER` = 0(保持 P2/FUTURE 决策,不提供任何远程开锁入口)。
|
||||
- **迁移标记**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`。
|
||||
@@ -135,3 +135,52 @@ public void testConcurrentLoginDeduplication() throws Exception {
|
||||
- `008_CONTRACT_TEST = PASS`
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
||||
- 明确声明:008 迁移脚本已通过静态语法与结构契约测试(Contract Test PASS),未在实际生产库或非隔离库执行;在投产前必须在隔离 Kingbase 实例执行双跑准入门禁。
|
||||
|
||||
---
|
||||
|
||||
## 6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
||||
- **阶段状态**:Wave 2 implemented against Mock DMS only。
|
||||
- **新增自动化测试清单 (26 项)**:
|
||||
1. `DmsTokenManagerTest.java` (4 项):
|
||||
- `testTokenConcurrency_SingleFlightLogin` (20 线程并发获取 Token,单飞登录仅 1 次,所有线程获取相同 Token)。
|
||||
- `testTokenRefresh_SingleFlightRefresh` (推进时间至提前刷新窗口,20 线程并发单飞刷新,旧 Token 废弃)。
|
||||
- `testSuccessfulApiExtendsLocalTtl` (成功调用 API 触发滑动延展本地有效期限)。
|
||||
- `testAuthFailureRecovery_NoLoginStorm` (401 集中失效自愈,无并发 login storm)。
|
||||
2. `DmsHttpClientTest.java` (3 项):
|
||||
- `testMutationAmbiguity_NoAutoRetryOnTimeout` (写操作读取超时坚决不自动重试,`passwordCreatePostCounter = 1`)。
|
||||
- `testTokenTransport_CookieHeader` (验证请求注入 `Cookie: token=...`,严禁 `Bearer`)。
|
||||
- `testSensitiveDataRedaction` (密码明文、Token、Secret 全局脱敏断言)。
|
||||
3. `DmsLocationAdapterTest.java` (1 项):
|
||||
- `testLocationLookup_FullHierarchy` (建筑、楼层、房间完整层级查询与 placeId 解析)。
|
||||
4. `DmsDoorLockAdapterTest.java` (2 项):
|
||||
- `testZeroLock_ReturnsEmptyList` (0 把锁场景正常返回空列表,非 NPE,非假锁)。
|
||||
- `testMultiLock_ReturnsAllLocks` (多把锁场景完整返回全部 3 把门锁)。
|
||||
5. `DmsPasswordAdapterTest.java` (4 项):
|
||||
- `testCreateOnlinePassword_Success` (正常下发 6 位限时密码,获得 keyId 与 operationId)。
|
||||
- `testCreateOnlinePassword_ValidRanges` (支持 4~8 位范围内的合法密码)。
|
||||
- `testCreateOnlinePassword_InvalidFormatsRejected` (非法格式参数拦截)。
|
||||
- `testDeleteOnlinePassword_Success` (删除在线密码成功返回 operationId)。
|
||||
6. `DmsOperationStatusAdapterTest.java` (4 项):
|
||||
- `testQueryOperationStatus_FromMock` (查询门锁操作状态)。
|
||||
- `testStatusMapper_AllKnownTransitions` (success->SUCCESS, undone->PENDING, failed->FAILED, timeout->TIMEOUT)。
|
||||
- `testStatusMapper_UnknownStatusNeverSuccess` (未知状态映射为 UNKNOWN,绝非 SUCCESS)。
|
||||
- `testStatusMapper_TerminalStatusIdentification` (终态识别判定)。
|
||||
7. `DmsOperationPollerTest.java` (6 项):
|
||||
- `testSafeDefaults_DisabledPollerDoesNothing` (安全默认:enabled=false 绝不执行轮询)。
|
||||
- `testPollFlow_ReachesSuccess` (轮询流转到 SUCCESS 终态)。
|
||||
- `testPollFlow_ReachesFailed` (轮询流转到 FAILED 终态)。
|
||||
- `testPollFlow_ReachesTimeout` (轮询流转到 TIMEOUT 终态)。
|
||||
- `testPollFlow_PendingUndoneRetained` (设备 undone 保持 PENDING 并延展时间)。
|
||||
- `testTerminalStateProtection_NeverRewritten` (终态记录不可篡改)。
|
||||
8. `DmsAsyncLifecycleAndSecurityTest.java` (2 项):
|
||||
- `testAcceptedNotEqualsSuccess_LifecycleVerification` (核心验证:HTTP 200 仅为 ACCEPTED,轮询成功后才为 SUCCESS)。
|
||||
- `testCredentialDataLeak_ZeroPlaintextStorage` (反射断言持久化实体绝无密码明文属性)。
|
||||
- **全量测试指标**:
|
||||
- 基线测试数:203 项。
|
||||
- 新增测试数:26 项。
|
||||
- 当前测试总数:229 项(ruoyi-train: 201 项,ruoyi-admin: 28 项),Failures = 0, Errors = 0, Skipped = 0。
|
||||
- Maven `clean test` 与 `clean package` 顺利构建成功。
|
||||
- **环境纪律与迁移标记**:
|
||||
- `LIVE_DMS_REQUEST_COUNT = 0`
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
||||
@@ -188,3 +188,30 @@ flowchart TD
|
||||
- `008_CONTRACT_TEST = PASS`
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
||||
- 严禁将 Contract Test PASS 描述为实际 Kingbase 双执行 PASS。
|
||||
|
||||
### 3.4 Wave 2 Implementation Result (DMS 适配层 / Token / HTTP / Poller / Mock 集成 - Wave 2 implemented)
|
||||
- **阶段目标**:DMS Adapter / Token / HTTP / Poller / Mock Integration against Mock DMS only
|
||||
- **执行状态**:Wave 2 implemented
|
||||
- **核心交付清单**:
|
||||
1. 基础配置:`DmsProperties.java`(受控配置,`enabled=false` 安全默认,参数化超时与刷新窗口)。
|
||||
2. 令牌管理:`DmsTokenManager.java`(进程级单例缓存,ReentrantLock + DCL 单飞互斥防击穿,滑动顺延,401 集中失效)。
|
||||
3. 通信客户端:`DmsHttpClient.java`(Cookie 头鉴权,脱敏日志,写操作读取超时严禁自动重发 `AMBIGUOUS_MUTATION_AUTO_RETRY = NO`)。
|
||||
4. 位置适配器:`DmsLocationClient.java`、`ExternalLocationGateway.java`、`DmsLocationGatewayImpl.java`(层级空间查询与 placeId 解析)。
|
||||
5. 门锁适配器:`DmsDoorLockClient.java`、`ExternalDoorLockGateway.java`、`DmsDoorLockGatewayImpl.java`(支持 0、1、多把智能门锁)。
|
||||
6. 密码凭据适配器:`DmsPasswordClient.java`、`ExternalCredentialGateway.java`、`DmsCredentialGatewayImpl.java`(下发 4~8 位限时密码、删除密码,密码明文内存短暂留存)。
|
||||
7. 状态查询与映射:`DmsOperationStatusClient.java`、`DmsOperationStatusMapper.java`(集中统一映射,未知状态判定为 UNKNOWN 严禁判定为 SUCCESS)。
|
||||
8. 异步轮询器:`DmsOperationPoller.java`(条件化启动,单进程并发防重,终态不可篡改保护,退避重试)。
|
||||
9. 测试基础设施:`MockDmsServer.java`(内嵌纯 JDK HttpServer,完全模拟真实 DMS 平台登录互斥、短 TTL、多锁/零锁与状态流转)。
|
||||
10. 自动化测试套件:`DmsTokenManagerTest` (4项)、`DmsHttpClientTest` (3项)、`DmsLocationAdapterTest` (1项)、`DmsDoorLockAdapterTest` (2项)、`DmsPasswordAdapterTest` (4项)、`DmsOperationStatusAdapterTest` (4项)、`DmsOperationPollerTest` (6项)、`DmsAsyncLifecycleAndSecurityTest` (2项)。
|
||||
- **全量构建与回归验收**:
|
||||
- `ruoyi-train`: 201 tests
|
||||
- `ruoyi-admin`: 28 tests
|
||||
- 总计:229 tests, Failures = 0, Errors = 0, Skipped = 0,全部通过。
|
||||
- Maven `clean test` 与 `clean package` 构建成功。
|
||||
- 生产数据库变更:`PRODUCTION_DB_MODIFIED? NO`。
|
||||
- 外部通信真实调用:`LIVE_DMS_REQUEST_COUNT = 0`。
|
||||
- 控制器与前端改动:`CONTROLLER_COUNT = 0`,`FRONTEND_MODIFIED = 0`。
|
||||
- **Migration 标记**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`
|
||||
- `008_RUNTIME_SECOND_RUN = NOT_EXECUTED`
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
||||
@@ -46,3 +46,12 @@
|
||||
| **Q-NON-04** | **开门密码学员触达渠道**:密码如何安全告知学员? | 推荐学员在移动端个人中心经二次身份验证后查看 30 秒倒计时明文,节省短信资费。 |
|
||||
| **Q-NON-05** | **远程紧急开锁 (Remote Unlock)**:一期是否需要上线远程开锁? | 属于高危控制操作,一期严格排除;仅设计两票制受控应急方案备查。 |
|
||||
| **Q-NON-06** | **门锁电量与信号监控**:是否需要专门的设备运行状态大盘? | 一期在宿舍列表表格中轻量展示电量与信号徽标,辅助宿管员排查低电量门锁。 |
|
||||
|
||||
---
|
||||
|
||||
## 4. Wave 2 架构中对未决问题的设计守则 (`Wave 2 Open Question Guards`)
|
||||
在 Wave 2 适配层开发中,上述问题被严格保留为待确认事项,绝不在代码与文档中伪称已解决:
|
||||
1. **门锁离线与 RTC 漂移语义**:依然待供应商提供技术规格,系统在 Adapter 与 Poller 中保持以主动撤权为主、有效期为辅的双重安全设计。
|
||||
2. **真实环境 Sandbox 账号**:本 Wave 严格使用 `MockDmsServer` 动态模拟,不依赖真实 DMS 沙箱。
|
||||
3. **真实错误码全集**:通过 `DmsOperationPoller.ERROR_CATEGORY_*` 抽象通用错误分类(AUTH_ERROR, NETWORK_ERROR, VENDOR_BUSINESS_ERROR, DEVICE_FAILED, DEVICE_TIMEOUT),兼容未知供应商错误。
|
||||
4. **Token Cookie 头名称**:在 `DmsProperties.tokenCookieName` 中参数化配置(默认 "token"),杜绝写死猜测。
|
||||
@@ -154,4 +154,43 @@
|
||||
- Maven 构建:`clean test` 与 `clean package` 均 `SUCCESS`。
|
||||
- 代码格式校验:`git diff --check = PASS`。
|
||||
- 阶段评审状态:`R3_WAVE1_REVIEW = PASS`。
|
||||
- 提交状态:`R3_WAVE1_COMMIT = READY`(执行 Checkpoint Commit,绝不 PUSH,绝不 DEPLOY)。
|
||||
- 提交状态:`R3_WAVE1_COMMIT = COMMITTED` (SHA: 22bcd1bacb66826e8e911454e9c01b54c8b64b32)。
|
||||
|
||||
### 6.4 Wave 2 DMS Adapter, Token, Poller & Mock Integration (Wave 2 implemented against Mock DMS only)
|
||||
- **阶段状态**:`R3_WAVE2_STATUS = PASS`。
|
||||
- **配置与安全默认**:
|
||||
- `DMS_DEFAULT_ENABLED = FALSE`:默认不开启 DMS 通信与轮询。
|
||||
- `DMS_PROPERTIES`:完整实现受控配置,零硬编码密钥,参数化超时与刷新窗口。
|
||||
- **令牌与通信架构**:
|
||||
- `TOKEN_TRANSPORT_MODEL` = `Cookie: token={token}`(严禁使用未核实的 `Authorization: Bearer`)。
|
||||
- `TOKEN_CACHE_MODEL` = `SINGLE_PROCESS_IN_MEMORY`(全应用单一集中缓存)。
|
||||
- `TOKEN_SINGLE_FLIGHT_MODEL` = `REENTRANT_LOCK_DCL`(高并发过期单飞防击穿,实测 20 线程并发登录仅 1 次)。
|
||||
- `TOKEN_TTL_MODEL` = `7200S_WITH_REFRESH_SKEW`(滑动窗口提前 120 秒平滑单飞刷新)。
|
||||
- `SUCCESSFUL_API_EXTENDS_LOCAL_TTL` = `YES`(成功调用 DMS API 顺延本地失效时间戳)。
|
||||
- `AUTH_FAILURE_REFRESH_MODEL` = `INVALIDATE_THEN_SINGLE_FLIGHT`(401 集中失效并在下一次请求单飞获取新 Token,无 login storm)。
|
||||
- `AMBIGUOUS_MUTATION_AUTO_RETRY` = `NO`(写操作读取超时坚决抑制自动重发,防止重复生成门锁凭据)。
|
||||
- `DMS_HTTP_CLIENT` = `DmsHttpClient` 统一底层通信与全局脱敏日志(零明文密码/Token/Secret 泄露)。
|
||||
- **设备与凭据适配能力**:
|
||||
- `LOCATION_ADAPTER` = `DmsLocationClient` / `ExternalLocationGateway`(Building, Floor, Room 空间定位与 placeId 解析)。
|
||||
- `DOORLOCK_ADAPTER` = `DmsDoorLockClient` / `ExternalDoorLockGateway`(支持 0 把锁空列表与多把锁完整返回)。
|
||||
- `ONLINE_PASSWORD_CREATE` = `DmsPasswordClient` / `ExternalCredentialGateway`(支持 4~8 位数字限时密码下发,密码零落库)。
|
||||
- `ONLINE_PASSWORD_DELETE` = `DmsPasswordClient` / `ExternalCredentialGateway`(注销并返回 operationId)。
|
||||
- `OPERATION_STATUS_QUERY` = `DmsOperationStatusClient`。
|
||||
- `VENDOR_STATUS_MAPPING` = `DmsOperationStatusMapper`(集中统一映射,未知状态判定为 UNKNOWN,绝非 SUCCESS)。
|
||||
- **异步轮询与测试模拟**:
|
||||
- `POLLER_IMPLEMENTED` = `DmsOperationPoller`(条件化启动,单进程并发防重,终态不可篡改保护,指数退避重试)。
|
||||
- `POLLER_INITIAL_DELAY` = 10s。
|
||||
- `MULTI_INSTANCE_POLLER_LOCK` = `FUTURE_GATE`。
|
||||
- `MOCK_DMS_IMPLEMENTED` = `MockDmsServer`(纯轻量 JDK 原生模拟,登录互斥、短 TTL、多锁/零锁与状态流转)。
|
||||
- **测试与质量指标**:
|
||||
- `OLD_TEST_COUNT = 203`
|
||||
- `NEW_TEST_COUNT = 26`
|
||||
- `TOTAL_TEST_COUNT = 229` (ruoyi-train: 201, ruoyi-admin: 28),Failures = 0, Errors = 0, Skipped = 0。
|
||||
- `MAVEN_TEST = SUCCESS`,`MAVEN_PACKAGE = SUCCESS`。
|
||||
- `git diff --check = PASS`。
|
||||
- **环境纪律与迁移标记**:
|
||||
- `LIVE_DMS_REQUEST_COUNT = 0`(全生命周期未对公网真实 DMS 发起任何请求)。
|
||||
- `FRONTEND_MODIFIED = 0`,`CONTROLLER_COUNT = 0`。
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`。
|
||||
- `COMMIT? NO`,`PUSH? NO`,`DEPLOY? NO`(严格 HOLD 等待审查)。
|
||||
Reference in new issue
Block a user