新增集成:实现外部资源映射与操作记录持久化
This commit is contained in:
1 parent
5de1d2a142
commit
1332b45fae
22 files changed
+2843
No files matched your search
@@ -181,3 +181,19 @@ DMS 接口 `POST /rest/doorlock/list`(入参 `placeId`)返回的是一个门
|
||||
| `credential_sub_type` | `create.subType` | 固定为 `4` (限时密码) |
|
||||
| `external_key_id` | 返回的 `data.id` | DMS 钥匙全局 ID (退宿撤权时作为删除入参) |
|
||||
| `dms_operation_id` | 返回的 `data.operationId` | DMS 异步下发任务 ID (用于10秒后状态轮询) |
|
||||
|
||||
---
|
||||
|
||||
## 5. Wave 1 Implementation Result (Wave 1 implemented)
|
||||
- **阶段状态**:Wave 1 implemented(外部资源映射模型与外部操作流水持久化模型已交付并验证)。
|
||||
- **资源映射基数与引用模型 (`RESOURCE_MAPPING_REFERENCE_MODEL = DORM_ID_FK`)**:
|
||||
- 本地采用 `dorm_id` 外键强关联 `train_dormitory_info`,确保一期完整性与零类型歧义。
|
||||
- **房间映射基数**:`ROOM_MAPPING_CARDINALITY = Dormitory 1:0..1 Active Room (Dormitory 1:N History)`,同一宿舍在同一 Vendor 下最多只能有 1 个处于 ACTIVE 状态的房间映射(通过局部唯一索引 `uq_ext_res_map_active_room` 严格保障)。
|
||||
- **门锁映射基数**:`LOCK_MAPPING_CARDINALITY = Dormitory 1:0..N DoorLocks`,支持一房多锁(防盗门、内门、套间门),`is_primary` 区分主从门锁。
|
||||
- **外部资源唯一性**:`EXTERNAL_RESOURCE_ACTIVE_UNIQUENESS = Vendor + External Resource ID + Active Unique`,同一外部资源在同一厂商下严禁跨房间重复 ACTIVE 绑定(通过局部唯一索引 `uq_ext_res_map_active_ext_res` 保障)。
|
||||
- **操作流水基数与引用模型 (`OPERATION_REFERENCE_MODEL = DOOR_AUTH_ID_FK`)**:
|
||||
- 本地采用 `door_auth_id` 外键强关联 `train_dorm_auth`,业务类型默认为 `DOOR_AUTH`。
|
||||
- **操作流水基数**:`DOOR_AUTH_OPERATION_CARDINALITY = DoorAuthorization 1:N ExternalOperation`,每次具体下发、重试、撤销均保留独立流水行,禁止直接覆写。
|
||||
- **状态机与幂等**:`OPERATION_STATUS_MODEL` 包含从 `CREATED` 到 `SUCCESS/FAILED/TIMEOUT/RETRY_WAIT` 的合法单向流转(`REVOKED` 属于 `DoorAuthorization` 业务状态,单次注销流水为 `operation_type=REVOKE` 达成 `SUCCESS`),终态不可逆;`idempotency_key` 唯一索引全局防重。
|
||||
- **敏感数据治理**:不存 raw JSON、密码明文、卡号明文、Token、Secret,敏感字段数为 0。
|
||||
- **数据库迁移安全**:`008_external_resource_operation.sql` 已通过静态契约测试与幂等验证,生产库保持零变更。
|
||||
@@ -173,3 +173,16 @@ ruoyi-train
|
||||
- DMS 返回的 `operationStatus` 字符串(`"undone"`, `"success"`, `"failed"`, `"timeout"`)由适配器转换为内部标准领域枚举 `NormalizedOperationStatus`。
|
||||
3. **第三方异常吞吐隔离**:
|
||||
- 外部网络超时、401 故障、DMS 内部报错统一由适配器包装为 `IntegrationException` 及其子类,不得泄露第三方平台的底层堆栈至前端。
|
||||
|
||||
---
|
||||
|
||||
## 5. Wave 1 Implementation Result (Wave 1 implemented)
|
||||
- **阶段状态**:Wave 1 implemented。
|
||||
- **持久化层落地**:
|
||||
- 完成外部资源映射实体 `TrainExternalResourceMapping` 与操作流水实体 `TrainExternalOperation`。
|
||||
- 完成持久化 Mapper 与 Service (`IExternalResourceMappingService`, `IExternalOperationService`)。
|
||||
- 落地 `train_external_resource_mapping`(支持一房多锁、Active 唯一性)与 `train_external_operation`(支持 DoorAuthorization 1:N 流水追踪)。
|
||||
- **零外部耦合红线**:
|
||||
- 本 Wave 严格保持 `DMS_HTTP_CLIENT_COUNT = 0`,`DMS_TOKEN_MANAGER_COUNT = 0`。
|
||||
- 零 RestTemplate / WebClient / HttpClient 网络调用,零明文敏感凭据。
|
||||
- **数据库 Migration**:`008_external_resource_operation.sql` 验证通过,生产库未执行。
|
||||
@@ -135,3 +135,15 @@ stateDiagram-v2
|
||||
1. 不得无限循环调用。
|
||||
2. 若配置了自动补偿,可追加 1 次重试查询;若依然超时,将操作置为 `TIMEOUT`,授权主表置为 `ISSUE_FAILED`。
|
||||
3. 页面以警告色徽标展示“设备下发超时”,提供【重新下发】按钮供管理员现场排障。
|
||||
|
||||
---
|
||||
|
||||
## 5. Wave 1 Implementation Result (Wave 1 implemented)
|
||||
- **阶段状态**:Wave 1 implemented。
|
||||
- **状态模型与流转控制 (`OPERATION_STATUS_MODEL`)**:
|
||||
- 流转闭环:`CREATED` -> `REQUESTED` -> `ACCEPTED` / `PENDING` -> `SUCCESS` / `FAILED` / `TIMEOUT` / `RETRY_WAIT`(`REVOKED` 归属于 `DoorAuthorization` 业务授权主状态,注销调用以 `operation_type=REVOKE` 发起并达成 `status=SUCCESS`)。
|
||||
- **终态保护**:`SUCCESS` 终态达成后禁止任何逆向跳转;`FAILED` / `TIMEOUT` 终态达成后禁止原记录重置为 `CREATED`。
|
||||
- **重试审计保持**:重试调用通过 `createRetryOperation` 创建自增 `attempt_count` 的全新流水记录,历史调用事实不可篡改。
|
||||
- **轮询检索接口 (`PENDING_OPERATION_QUERY`)**:
|
||||
- 交付 `selectPendingPollOperations`,检索处于 `ACCEPTED`、`PENDING`、`RETRY_WAIT` 且 `next_poll_time <= NOW()` 的操作记录。
|
||||
- 为 Wave 2 调度器提供完整数据准备,本 Wave 保持 0 调度器运行、0 HTTP 调用。
|
||||
@@ -153,3 +153,14 @@ sequenceDiagram
|
||||
### 5.1 换房核心准则总结
|
||||
- **“先发新、后撤旧”原则**:绝不能先删除了旧房权限再去发新房。若新房门锁出现硬件故障或网络不通,学员将两头落空无法进门。
|
||||
- **降级容错策略**:新房授权失败时,保留旧房权限,并在前端控制台突出显示“门禁换房未同步”,由管理员一键重试或安排备用钥匙。
|
||||
|
||||
---
|
||||
|
||||
## 6. Wave 1 Implementation Result (Wave 1 implemented)
|
||||
- **阶段状态**:Wave 1 implemented。
|
||||
- **本地幂等模型落地 (`IDEMPOTENCY_MODEL`)**:
|
||||
- 物理约束:`train_external_operation` 设立 `uq_ext_op_idempotency` 唯一索引,数据库级别杜绝重复写入。
|
||||
- 服务防重:`ExternalOperationServiceImpl.createOperation` 在插入前先查幂等键,命中已有记录直接返回已有实体,防止重复派发异步调用。
|
||||
- **重试审计与不可变性**:
|
||||
- 终态记录不可覆写:每次重试调用通过 `createRetryOperation` 独立创建自增 `attempt_count` 的新记录。
|
||||
- 保留完整排障轨迹:`last_error_code` 与 `last_error_message` 详细保留每次失败现场,满足段级安全审计与对账需求。
|
||||
@@ -124,3 +124,21 @@
|
||||
3. 创建局部唯一索引:`CREATE UNIQUE INDEX IF NOT EXISTS uq_accommodation_enroll_active ON train_accommodation (enrollment_id) WHERE accommodation_status IN (0, 1);`
|
||||
4. 幂等防护:重复执行幂等安全。
|
||||
- 生产执行纪律:本脚本已在单元/契约测试中完成全量静态与逻辑校验,**禁止在生产库执行**。
|
||||
|
||||
### 4.3 Wave 1 Implementation Result (外部资源映射与操作流水持久化落地 - Wave 1 implemented)
|
||||
- **阶段状态**:Wave 1 implemented。
|
||||
- **物理模型与引用决策**:
|
||||
- **资源映射表 (`train_external_resource_mapping`)**:
|
||||
- 引用模型:`RESOURCE_MAPPING_REFERENCE_MODEL = DORM_ID_FK`,直接建立外键关联 `train_dormitory_info(dorm_id)`,确保一期强完整性。
|
||||
- 房间映射基数:`ROOM_MAPPING_CARDINALITY = Dormitory 1:0..1 Active Room (Dormitory 1:N History)`,局部唯一索引 `uq_ext_res_map_active_room`。
|
||||
- 锁映射基数:`LOCK_MAPPING_CARDINALITY = Dormitory 1:0..N DoorLocks`,原生支持一房多锁,`is_primary` 标记主门锁。
|
||||
- 外部资源唯一性:`EXTERNAL_RESOURCE_ACTIVE_UNIQUENESS = Vendor + External Resource ID + Active Unique`,局部唯一索引 `uq_ext_res_map_active_ext_res`。
|
||||
- **操作流水表 (`train_external_operation`)**:
|
||||
- 引用模型:`OPERATION_REFERENCE_MODEL = DOOR_AUTH_ID_FK`,直接建立外键关联 `train_dorm_auth(auth_id)`。
|
||||
- 授权操作基数:`DOOR_AUTH_OPERATION_CARDINALITY = DoorAuthorization 1:N ExternalOperation`,每次具体下发与重试均产生新记录。
|
||||
- 本地幂等键:`IDEMPOTENCY_MODEL`,唯一索引 `uq_ext_op_idempotency`。
|
||||
- 待轮询复合索引:`idx_ext_op_poll`,高效支持状态机轮询。
|
||||
- **008 迁移脚本交付 (`008_external_resource_operation.sql`)**:
|
||||
- 安全编号:`008`(001-003 基线, 004-005 R.2, 006 Wave 0, 007 保留禁止执行)。
|
||||
- 纯增量与幂等设计:无 DROP TABLE,无 TRUNCATE,无 DELETE,无明文密码/Token敏感字段。
|
||||
- 生产状态:`PRODUCTION_DB_MODIFIED? NO`,未在生产数据库执行。
|
||||
@@ -115,3 +115,23 @@ public void testConcurrentLoginDeduplication() throws Exception {
|
||||
- 在 DMS 中建立虚拟楼栋(如“联调测试楼”),配置测试房间(如“9901室”、“9902室”)。
|
||||
4. **技术支撑配合**:
|
||||
- 供应商提供联调期间的技术接口人,并确认正式环境网络是否具备固定公网 IP 白名单或专网通道。
|
||||
|
||||
---
|
||||
|
||||
## 5. Wave 1 Implementation Result (Wave 1 implemented)
|
||||
- **阶段状态**:Wave 1 implemented。
|
||||
- **新增自动化测试清单**:
|
||||
1. `ExternalResourceMappingServiceTest.java` (10 项测试,涵盖 A 到 I 全部场景及 A2 跨资源类型同 ID 合法共存场景)。
|
||||
2. `ExternalOperationServiceTest.java` (12 项测试,涵盖 A 到 J 全部场景、K 场景 REVOKE 成功达成 SUCCESS 终态与 L 场景非法 REVOKED 操作状态抛错校验)。
|
||||
3. `ExternalResourceOperationMigrationContractTest.java` (7 项静态契约测试:表名、外键、局部唯一索引、幂等键索引、无破坏性语句、无敏感字段、多字段组合联合唯一性校验)。
|
||||
- **全量测试指标**:
|
||||
- 基线测试数:174 项。
|
||||
- 新增测试数:29 项(10 + 12 + 7)。
|
||||
- 当前测试总数:203 项(ruoyi-train: 175 项,ruoyi-admin: 28 项),Failures = 0, Errors = 0, Skipped = 0。
|
||||
- Maven `clean test` 与 `clean package` 顺利构建成功。
|
||||
- **迁移验证与准入标记**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`
|
||||
- `008_RUNTIME_SECOND_RUN = NOT_EXECUTED`
|
||||
- `008_CONTRACT_TEST = PASS`
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
||||
- 明确声明:008 迁移脚本已通过静态语法与结构契约测试(Contract Test PASS),未在实际生产库或非隔离库执行;在投产前必须在隔离 Kingbase 实例执行双跑准入门禁。
|
||||
@@ -165,3 +165,26 @@ flowchart TD
|
||||
- `ruoyi-train`: 153 tests
|
||||
- `ruoyi-admin`: 21 tests
|
||||
- 总计:174 tests, Failures: 0, Errors: 0, Skipped: 0,全量通过。
|
||||
|
||||
### 3.3 Wave 1 Implementation Result (外部资源映射与操作流水持久化 - Wave 1 implemented)
|
||||
- **阶段目标**:External Resource Mapping & External Operation Persistence
|
||||
- **执行状态**:Wave 1 implemented
|
||||
- **核心交付清单**:
|
||||
1. 迁移脚本:`RuoYi-Vue/sql/system/kingbase/008_external_resource_operation.sql`(安全编号 008,支持一房多锁与幂等流水)
|
||||
2. 领域实体:`TrainExternalResourceMapping.java`、`TrainExternalOperation.java`(纯净中立模型,零敏感数据)
|
||||
3. 持久映射:`TrainExternalResourceMappingMapper.java/.xml`、`TrainExternalOperationMapper.java/.xml`(显式列投影,严禁 `SELECT *`)
|
||||
4. 业务服务:`IExternalResourceMappingService/Impl`、`IExternalOperationService/Impl`(Active唯一性校验、跨房间绑定防护、终态保护、重试创建)
|
||||
5. 自动化测试套件:`ExternalResourceMappingServiceTest` (10项)、`ExternalOperationServiceTest` (12项)、`ExternalResourceOperationMigrationContractTest` (7项)
|
||||
- **全量构建与回归验收**:
|
||||
- `ruoyi-train`: 175 tests
|
||||
- `ruoyi-admin`: 28 tests
|
||||
- 总计:203 tests, Failures = 0, Errors = 0, Skipped = 0,全部通过。
|
||||
- Maven `clean test` 与 `clean package` 构建成功。
|
||||
- 生产数据库变更:`PRODUCTION_DB_MODIFIED? NO`。
|
||||
- 外部 HTTP 客户端与通信:`DMS_HTTP_CLIENT_COUNT = 0`,`DMS_LIVE_API_CALLED? NO`。
|
||||
- **Migration 验证与准入门禁标记**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`
|
||||
- `008_RUNTIME_SECOND_RUN = NOT_EXECUTED`
|
||||
- `008_CONTRACT_TEST = PASS`
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
||||
- 严禁将 Contract Test PASS 描述为实际 Kingbase 双执行 PASS。
|
||||
@@ -128,3 +128,30 @@
|
||||
- **质量与构建验收**:
|
||||
- 单元与契约测试总数:174 项,全部 PASS(0 failures, 0 errors)。
|
||||
- Maven `clean test` 与 `clean package` 均顺利构建成功。
|
||||
|
||||
### 6.3 Wave 1 External Resource Mapping & Operation Persistence (Wave 1 implemented)
|
||||
- **阶段状态**:Wave 1 implemented。
|
||||
- **架构决策与模型基线**:
|
||||
- 资源映射模型:`RESOURCE_MAPPING_REFERENCE_MODEL = DORM_ID_FK`,以 `dorm_id` 外键强关联 `train_dormitory_info`。
|
||||
- 房间映射基数:`ROOM_MAPPING_CARDINALITY = Dormitory 1:0..1 Active Room (Dormitory 1:N History)`。
|
||||
- 门锁映射基数:`LOCK_MAPPING_CARDINALITY = Dormitory 1:0..N DoorLocks`(支持一房多锁)。
|
||||
- 外部资源防冲突:`EXTERNAL_RESOURCE_ACTIVE_UNIQUENESS = Vendor + External Resource ID + Active Unique`。
|
||||
- 操作流水模型:`OPERATION_REFERENCE_MODEL = DOOR_AUTH_ID_FK`,以 `door_auth_id` 外键强关联 `train_dorm_auth`。
|
||||
- 授权操作基数:`DOOR_AUTH_OPERATION_CARDINALITY = DoorAuthorization 1:N ExternalOperation`。
|
||||
- 操作类型与状态分离:`OPERATION_TYPE_MODEL = GRANT, REVOKE`;`EXTERNAL_OPERATION_STATUS_MODEL = CREATED, REQUESTED, ACCEPTED, PENDING, RETRY_WAIT, SUCCESS, FAILED, TIMEOUT`(`REVOKED` 属于 `DoorAuthorization` 业务凭据状态,不属于单次操作执行结果,注销操作的执行结果为 `operation_type=REVOKE` 达成 `SUCCESS`)。
|
||||
- 本地幂等模型:`IDEMPOTENCY_MODEL` 基于 `idempotency_key` 唯一索引防重。
|
||||
- 轮询检索支持:`PENDING_OPERATION_QUERY` 准备就绪,本 Wave 保持 0 调度器运行。
|
||||
- **安全红线保持**:
|
||||
- 敏感字段:`SENSITIVE_OPERATION_FIELD_COUNT = 0`。
|
||||
- 外部耦合:`DMS_HTTP_CLIENT_COUNT = 0`,`DMS_TOKEN_MANAGER_COUNT = 0`。
|
||||
- 生产数据库:只读保护,`PRODUCTION_DB_MODIFIED? NO`。
|
||||
- **Migration 证据与准入准则**:
|
||||
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`(生产与非隔离库绝不盲跑 DDL)。
|
||||
- `008_CONTRACT_TEST = PASS`,`008_IDEMPOTENCY_STATIC_VERIFICATION = PASS`。
|
||||
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`(在正式生产投产前必须在隔离 Kingbase 完成双跑验证)。
|
||||
- **测试与验证指标**:
|
||||
- 测试套件全部通过:`TOTAL_TEST_COUNT = 203` (ruoyi-train: 175, ruoyi-admin: 28),Failures = 0, Errors = 0, Skipped = 0。
|
||||
- Maven 构建:`clean test` 与 `clean package` 均 `SUCCESS`。
|
||||
- 代码格式校验:`git diff --check = PASS`。
|
||||
- 阶段评审状态:`R3_WAVE1_REVIEW = PASS`。
|
||||
- 提交状态:`R3_WAVE1_COMMIT = READY`(执行 Checkpoint Commit,绝不 PUSH,绝不 DEPLOY)。
|
||||
Reference in new issue
Block a user