|
|
171f201384
|
feat(iot): Wave 5 Round 2 — B9/B14/B16 统一消费入口 + 告警分布式锁 + 通知集成
B9 IotRuleEngineMessageHandler(统一消费入口)
- 新消费者 v2 统一入口,@PostConstruct 注册到 IotMessageBus
- versionResolver.shouldUseV2 三态路由(V1/V2/HYBRID),绝不双跑
- device null 时 WARN + skip;RuleEngine 异常 try-catch 吞掉防重试风暴
- v1 三消费者(DataRule/SceneRule/CleanRule)增加前置 v2 bypass 判断
- 6 个单元测试(global-v1/v2/hybrid 白名单命中/未命中/device-null/引擎异常)
B14 告警缓存 + SET NX PX 分布式锁 + 有效性判断
- IotAlarmLockService:SET NX PX + Lua 原子解锁,锁冲突抛 ALARM_LOCK_CONFLICT
- IotAlarmCacheService:Redis Hash iot:alarm:state:{id},TTL 7天,cache miss 从DB重建
- AlarmStateValidator:isEffectiveTrigger/isEffectiveClear 时序校验,防旧消息重置已清除告警
- IotAlarmRecordServiceImpl:trigger/clear/ack/archive 全部在锁内,DB写后立即同步缓存
- 新增 ALARM_LOCK_CONFLICT 错误码;AlarmTriggerRequest 增加 timestamp 字段
- 17 个单元测试(锁 4 + 缓存 5 + 校验 9 + 集成 3)
B16 NotifyAction 4 通道集成 + 模板解析
- NotifyChannel SPI 接口 + Sms/Email/InApp/Webhook 四实现(@Component 注册)
- WebhookNotifyChannel:JDK 17 HttpClient 10s 超时 + SSRF 强制 HTTPS 校验
- NotifyDispatcher:独立 ForkJoinPool(8) 并行分发,30s 整体超时,部分失败不阻塞
- 模板变量统一走 TemplateResolver(评审 C5),缺失变量降级为空串
- NotifyAction 移除 stub,委托 NotifyDispatcher
- viewsh-module-system-api 依赖引入;13 个测试(Dispatcher 7 + Webhook SSRF 6)
测试:iot-rule 177/177 全绿;iot-server 251/251 全绿(含 Skipped 161 旧 v1 测试)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-24 11:00:38 +08:00 |
|
|
|
24c486900a
|
feat(iot): Wave 4 Round 2 — B6/B7/B18 ActionProvider + 分支执行 + DataRule迁移
B6 ActionProvider SPI + 5 核心动作(alarm/notify/device-ctrl):
- ActionProvider 接口(extends NodeProvider,默认 bridge execute)
- ActionResult record(SUCCESS/FAILURE/SKIP + output + message)
- ActionProviderManager(Spring 自动收集 + fail-fast 重复 type)
- AlarmTriggerAction(调用 IotAlarmRecordApi.triggerAlarm,模板变量解析)
- AlarmClearAction(alarmId 从 config 或 ctx.metadata 解析,幂等)
- NotifyAction(4 通道并发 + 部分失败不阻塞,第一期 stub)
- DeviceServiceInvokeAction(调用 IotDeviceControlApi.invokeService)
- DevicePropertySetAction(第一期 stub,B27 补全 Redis/MySQL)
- IotAlarmRecordApi + DTO(rule 模块→server 跨模块接口)
- IotAlarmRecordApiImpl(server 端 FeignClient 实现,委托 Service)
- 14 单元测试全绿
B7 分支执行逻辑(executeAnyway if/else-if/else):
- BranchConfiguration POJO(branches[] + executeAnyway + BranchCondition)
- BranchExecutor(核心语义:else/executeAnyway/条件异常短路/action 异常隔离)
- BranchNode NodeProvider(ACTION/"branch",内联执行命中 branch actions)
- DagExecutor 最小扩展(ctx.metadata 传递 CompiledRuleChain 供 BranchNode 使用)
- 9 单元测试全绿(含 validate else 位置校验)
B18 DataRule → DAG 自动转换工具:
- DataRuleToChainMapper(v1→v2 映射,6 种 Sink,合并/拆分多 source)
- DataRuleMigrator(dry-run + execute + 幂等映射表)
- DataRuleMigrationController(3 端点:dry-run/execute/mapping)
- 8 单元测试全绿
测试总计:rule 模块 159/159 ✓,server 模块 8/8(B18)✓
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
2026-04-24 10:10:04 +08:00 |
|
|
|
42466363c7
|
feat(iot): Wave 4 Round 1 — B12/B4/B5 告警状态机 + 规则引擎 SPI
主会话 Opus:
- B12 iot_alarm_record 正交状态机(ack_state + clear_state + archived)
* V2.0.4__iot_alarm_record.sql:主表 + iot_alarm_propagation 关联表
* 评审 C1 正交三字段(替代线性 4 枚举,表达"已清除未确认")
* 评审 C2 联合 UK (device_id, alarm_config_id, tenant_id, deleted)
* 评审 C3 传播关联表(替代 propagated_to JSON 查询)
* Service 5 方法:triggerAlarm / ackAlarm / unackAlarm / clearAlarm / archiveAlarm
* 幂等 upsert(trigger_count++)+ 归档后禁止修改
* 13 单元测试全绿
* TODO B14 分布式锁 / B15 传播 / B16 通知
Sonnet subagent B4:TriggerProvider SPI + 5 内置触发器
* spi/TriggerProvider + TriggerProviderManager(@Component + getType 索引,fail-fast 重复 type)
* trigger/DeviceState / DeviceProperty / DeviceEvent / DeviceService / Timer(Spring TaskScheduler)
* 评审 A3 落地:禁 ServiceLoader / @SPI
* 44 单元测试全绿
Sonnet subagent B5:ConditionEvaluator SPI + 3 条件 + 统一模板变量
* spi/ConditionEvaluator + condition/Manager
* condition/Expression(Aviator + LRU(256) 编译缓存)
* condition/TimeRange(跨午夜支持)
* condition/DeviceState(Redis 查询,空值按 offline)
* template/TemplateResolver:\${namespace.key},拒绝 \$[...] 旧语法(评审 B5)
* TODO B44 完整 8 层 Aviator 沙箱
* 50 单元测试全绿(TemplateResolver 16 + 条件 3x ≈ 34)
测试汇总:rule 136 全绿 / server 13 新增全绿
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet (subagent) <noreply@anthropic.com>
|
2026-04-24 00:35:14 +08:00 |
|
|
|
1f87d599c0
|
feat(iot): B11 iot_device.subsystem_id + 设备归属绑定 API(一期允许 NULL)
- 新增 sql/iot/V2.0.3__iot_device_add_subsystem.sql(ALTER + idx_subsystem)
- 新增 sql/iot/V2.1.0__iot_device_subsystem_not_null.sql(二期预留,带 "勿执行" 注释)
- IotDeviceDO 加 subsystemId(一期可 NULL,二期改 NOT NULL)
- IotDeviceService 加 bindDeviceToSubsystem / batchBind / unbind / selectCountBySubsystemId
- IotDeviceServiceImpl.createDevice 强校验 subsystemId + 同租户 + Redis HINCRBY +1
- 绑定变更按 TransactionSynchronizationManager afterCommit 同步 Redis(-1 / +1,避免脏状态)
- IotDeviceMapper 加 selectCountBySubsystemId / updateSubsystemId 等
- IotSubsystemServiceImpl 加 incrementDeviceCount/decrementDeviceCount;deleteSubsystem 改用 DB 计数兜底(更可靠)
- IotDeviceController 加 PUT /bindSubsystem + /batchBindSubsystem(@PreAuthorize iot:device:update)
- IotDevicePageReqVO 加 subsystemId 过滤参数(null 可走 IS NULL 查未归属)
- api ErrorCodeConstants 加 DEVICE_SUBSYSTEM_REQUIRED / DEVICE_SUBSYSTEM_CROSS_TENANT(1_050_003_009/010)
- 测试:IotDeviceServiceImplTest 8/8 + B10 IotSubsystemServiceImplTest 补 mock deviceMapper 后 8/8 全绿
- Known Pitfalls 落地:
⚠️ 评审 A2:一期允许 NULL,V2.1.0 预留二期 NOT NULL
⚠️ Redis 计数:事务提交后同步(TransactionSynchronizationManager.afterCommit)
⚠️ 跨租户:校验 subsystem 属于当前租户,不然抛 DEVICE_SUBSYSTEM_CROSS_TENANT
⚠️ 索引 idx_subsystem (tenant_id, subsystem_id, deleted) 最左匹配;IS NULL 查询走全表扫,文档已提示
Co-Authored-By: Claude Sonnet (B11 subagent) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context, orchestrator) <noreply@anthropic.com>
|
2026-04-24 00:03:57 +08:00 |
|
|
|
962e69290b
|
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>
|
2026-04-23 21:09:54 +08:00 |
|
|
|
6649e1abb6
|
feat(iot): B10 iot_subsystem 表 + CRUD + Redis 设备计数聚合
- 新增 sql/iot/V2.0.2__iot_subsystem.sql(iot_project + iot_subsystem)
- 新增 server 模块 subsystem/ 下 DO + Mapper + Service + Controller + VO(7 端点)
- 新增 IotSubsystemDeviceCountRedisDAO(HINCRBY + rebuild + ApplicationReadyEvent 触发)
- api 模块 ErrorCodeConstants 新增子系统段(1-050-020-xxx)
- server 模块 RedisKeyConstants 新增 SUBSYSTEM_DEVCOUNT
- 测试:8 个单元用例全绿(mvn test IotSubsystemServiceImplTest)
- Known Pitfalls 落地:
⚠️ 评审 A4:UK(name, tenant_id, project_id, deleted) + 应用层 existsByNameAndProject 兜底 NULL
⚠️ 评审 A6:device-stats 走 Redis Hash,避免 GROUP BY
⚠️ 评审 A7:simple-list 权限码 iot:device:query,返回字段仅 id/name/code
⚠️ 删除校验:Redis 计数 > 0 抛 SUBSYSTEM_HAS_DEVICES
⚠️ Redis 重建:ApplicationReadyEvent + try/catch + log.warn 不阻塞启动
说明:iot_device 当前无 subsystem_id 列(rebuild 逻辑标 TODO B11),
待 B11 加列后启用 DB 重建查询。
Co-Authored-By: Claude Sonnet (B10 subagent) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context, orchestrator) <noreply@anthropic.com>
|
2026-04-23 21:08:00 +08:00 |
|
|
|
11dcb57ff3
|
feat(trajectory): 新增轨迹检测与 Beacon 注册表
|
2026-03-31 22:53:06 +08:00 |
|
|
|
26c4ce07eb
|
feat(iot,ops): 区域设备关联接口返回更多设备信息,修复 N+1 和代码质量问题
- IotDeviceSimpleRespDTO 新增 nickname、serialNumber、state、deviceType 字段
- IotDeviceQueryApi 新增 batchGetDevices 批量查询接口
- IotDeviceQueryApiImpl 提取 toSimpleDTO 统一转换、通过产品缓存解析 productName、
移除 blanket try-catch 让异常正确传播、删除无用 import
- AreaDeviceRelationRespVO 新增 nickname、serialNumber、deviceState、deviceType 字段
- AreaDeviceRelationServiceImpl.listByAreaId 改为批量查询避免 N+1 RPC、
增加 null 防护;bindDevice 改为 fail-fast 不再存脏数据
- ErrorCodeConstants 新增 IOT_SERVICE_UNAVAILABLE 错误码
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
2026-03-07 21:06:10 +08:00 |
|
|
|
13571faa59
|
refactor(iot,ops): 重构客流计数器重置为按区域删除阈值 key
- ResetTrafficCounterReqDTO: 废弃 newBaseValue 字段
- IotDeviceControlApiImpl: 重置逻辑改为通过区域关联查询后删除阈值 key
- CleanOrderEventListener: 简化异步重置调用,移除 triggerData 依赖
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
2026-02-03 15:37:23 +08:00 |
|
|
|
955c825e2c
|
feat(ops,iot): 保洁前端 API 层和区域管理新增
新增保洁业务前端 API 接口层(工牌、工单、仪表盘)和运营区域管理完整功能,包含 Service/Controller/Test 三层结构。
主要功能:
1. IoT 设备查询 API(RPC 接口)
- IotDeviceQueryApi: 提供设备简化信息查询
- IotDeviceSimpleRespDTO: 设备简化 DTO
2. 保洁工牌管理
- CleanBadgeService/Impl: 工牌通知、优先级调整、手动完成
- BadgeNotifyReqDTO/UpgradePriorityReqDTO/ManualCompleteOrderReqDTO
3. 保洁工单管理
- CleanWorkOrderService/Impl: 工单时间线查询
4. 保洁仪表盘
- CleanDashboardService/Impl: 快速统计(待处理/进行中/已完成/在线工牌数)
- QuickStatsRespDTO: 快速统计 DTO
5. 运营区域管理(Ops Biz)
- OpsBusAreaService/Impl: 区域 CRUD(支持树形结构、分页查询)
- AreaDeviceRelationService/Impl: 区域设备关联管理(绑定/解绑/批量更新)
- OpsBusAreaMapper/AreaDeviceRelationMapper: 扩展 MyBatis 批量方法
- 7 个 VO 类:CreateReqVO/UpdateReqVO/PageReqVO/RespVO/BindReqVO/RelationRespVO/DeviceUpdateReqVO
6. 前端 Controller(Ops Server)
- OpsBusAreaController: 区域管理 REST API(11 个接口)
- AreaDeviceRelationController: 设备关联 REST API(8 个接口)
- CleanBadgeController: 工牌管理 REST API(5 个接口)
- CleanDashboardController: 仪表盘 REST API(1 个接口)
- CleanDeviceController: 设备管理 REST API(2 个接口)
- CleanWorkOrderController: 工单管理 REST API(2 个接口)
7. 测试覆盖
- OpsBusAreaServiceTest: 区域服务测试(284 行)
- AreaDeviceRelationServiceTest: 设备关联测试(240 行)
- OpsBusAreaControllerTest: 区域 Controller 测试(186 行)
- AreaDeviceRelationControllerTest: 设备关联 Controller 测试(182 行)
8. API 层扩展
- ErrorCodeConstants: 错误码常量(区域、设备关联)
- NotifyTypeEnum: 通知类型枚举(语音、文本、震动)
- 4 个 Badge/Order DTO: BadgeStatusRespDTO/BadgeRealtimeStatusRespDTO/OrderTimelineRespDTO
9. RPC 配置
- RpcConfiguration: 注入 IotDeviceQueryApi
影响模块:Ops API、Ops Biz、Ops Server、Ops Environment Biz、IoT API、IoT Server
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
2026-02-02 22:42:45 +08:00 |
|
|
|
5142b38d12
|
refactor(ops): optimize badge device status management and add sync job
Java CI with Maven / build (11) (push) Has been cancelled
Java CI with Maven / build (17) (push) Has been cancelled
Java CI with Maven / build (8) (push) Has been cancelled
|
2026-01-29 11:35:11 +08:00 |
|
|
|
64928f5a3f
|
feat(ops): add-iot-clean-order-integration阶段3-客流计数器重置
|
2026-01-17 17:44:30 +08:00 |
|
|
|
de08aea83f
|
feat(iot): 定义设备控制与属性查询 API
|
2026-01-15 16:14:21 +08:00 |
|
|
|
8ccfafe2bb
|
first commit
Java CI with Maven / build (11) (push) Has been cancelled
Java CI with Maven / build (17) (push) Has been cancelled
Java CI with Maven / build (8) (push) Has been cancelled
|
2025-12-31 11:48:19 +08:00 |
|