feat(iot): B2 RuleChain/Node/Link 数据模型 + CRUD(单 Trigger/DAG 无环/乐观锁)

- 新增 sql/iot/V2.0.1__iot_rule_chain.sql(iot_rule_chain/node/link 三表 + idx_binding 索引)
- 新增 rule 模块 dal/(3 个 DO + 4 个封闭枚举 + 3 个 Mapper)
- 新增 rule 模块 service/(CRUD + 单 Trigger 校验 + DAG DFS 无环 + 乐观锁 + 级联软删)
- 新增 rule 模块 controller/admin/(7 REST 端点 + @PreAuthorize + VO)
- 新增 resources/mapper/rule/(3 个 MyBatis XML)
- api 模块 ErrorCodeConstants 新增规则链段(1-050-030-xxx)
- **补 B1 遗漏依赖**:rule/pom.xml 追加 viewsh-spring-boot-starter-{web,security,biz-tenant}
- 测试:8 个单元用例全绿(BaseMockitoUnitTest)
- Known Pitfalls 落地:
  ⚠️ 评审 B4:relation_type VARCHAR + 应用层 RuleLinkRelationType.isValid 校验
  ⚠️ 评审 B9:updateWithVersion 乐观锁原子 SQL + idx_update_time 索引支撑 B9 拉模式兜底扫描
  ⚠️ 评审 B10:单 Trigger 校验在 Service 层(validateSingleTrigger)
  ⚠️ 评审 A4:name UK(name, tenant_id, deleted)
  ⚠️ 评审 §十一-B:idx_binding (tenant_id, subsystem_id, product_id, device_id) 最左匹配

Co-Authored-By: Claude Sonnet (B2 subagent) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context, orchestrator) <noreply@anthropic.com>
This commit is contained in:
lzh
2026-04-23 21:09:54 +08:00
parent 6649e1abb6
commit 962e69290b
24 changed files with 1746 additions and 0 deletions

View File

@@ -85,4 +85,12 @@ public interface ErrorCodeConstants {
ErrorCode SUBSYSTEM_CODE_DUPLICATE = new ErrorCode(1_050_020_002, "同项目下子系统编码已存在");
ErrorCode SUBSYSTEM_HAS_DEVICES = new ErrorCode(1_050_020_003, "子系统下存在设备,不允许删除");
// ========== IoT 规则链DAG1-050-030-000 ==========
ErrorCode RULE_CHAIN_NOT_EXISTS = new ErrorCode(1_050_030_000, "规则链不存在");
ErrorCode RULE_CHAIN_NAME_DUPLICATE = new ErrorCode(1_050_030_001, "同租户下规则链名称已存在");
ErrorCode RULE_CHAIN_MUST_HAVE_EXACTLY_ONE_TRIGGER = new ErrorCode(1_050_030_002, "规则链有且仅能有一个触发器节点");
ErrorCode RULE_CHAIN_CYCLE_DETECTED = new ErrorCode(1_050_030_003, "规则链存在环路,不允许保存");
ErrorCode RULE_CHAIN_OPTIMISTIC_LOCK_CONFLICT = new ErrorCode(1_050_030_004, "规则链已被其他操作修改,请刷新后重试");
ErrorCode RULE_CHAIN_INVALID_RELATION_TYPE = new ErrorCode(1_050_030_005, "规则连线的关系类型非法");
}