首页 / 业务知识 / 核心领域模型与业务规则
核心领域模型与业务规则
设备归属、订阅-权益-Seat、支付事实分层、SIM 生命周期、告警规则模型与跨模块约束。
设备归属与绑定
设备归属不能只看单行字段。iot_device.owner_user_id 表示当前归属,但完整绑定过程经过三类记录:
| 实体/表 | 职责 | 关键约束 |
|---|---|---|
iot_bind_session | 绑定会话:记录一次绑定尝试的中间状态 | session_key 唯一;设备与会员状态查询有组合索引 |
iot_binding_task | 绑定任务:连接设备、订阅 Seat 与支付后的最终执行 | 租户内 task_no、pay_order_no 及未完成 session/pre-bind/device guard 唯一,用于幂等和并发防重 |
iot_device_share | 设备分享:from_user_id / to_user_id 表示双方,状态和有效期决定是否生效 | 分享状态 + 有效期判定 |
绑定过程通过 task/session 记录中间状态,不以单行设备归属字段替代完整流程;绑定涉及订阅 Seat 占位与支付时走 Saga(见下)。
订阅-权益-Seat 模型
| 实体 | 表达的事实 |
|---|---|
subscription_product / subscription_product_capability | 可售套餐与套餐包含的能力码 |
subscription_active | 当前生效的订阅(权益主体) |
subscription_record | 订阅变更历史(开通/续费/过期/转移) |
subscription_seat | 权益席位占用(设备或成员);对已占用 session/device guard 唯一,释放后恢复 |
subscription_transfer | 订阅转移记录 |
绑定 Saga 事件流(topic entrax-subscription-binding-saga-v1,Tag 即事件类型,统一契约常量避免两模块各自维护字符串):
- IoT 发起绑定 → 发布
subscription.seat.reserve.requested(Seat 预占请求) - Subscription 预占 Seat → 回发
subscription.seat.reserved(成功)或subscription.seat.reserve-failed/subscription.seat.payment-required(需先支付) - 需要支付时走
pay完成支付 → 发布subscription.paid.activation.requested→ 激活后回发subscription.paid.activation-completed - IoT 完成绑定 → 回发
iot.binding.completed;任一步失败 → 发布subscription.seat.release.requested→subscription.seat.released补偿释放
消费方:IotBindingSagaListener(RocketMQ,consumerGroup subscription-binding-saga-iot-v1)接收 Seat 结果并调用 IotBindingTaskService.handleSubscriptionResult。
权益校验对外暴露为 gRPC
SubscriptionEntitlementService:HasDeviceCapability / BatchHasDeviceCapability / ListDeviceCapabilities / GetRequiredProducts,供 Go 设备网关等外部系统校验设备能力。支付事实分层
Pay 模块把一次支付拆成多个独立事实,分别落表并各自维护状态机:
| 事实 | 表/服务 | 说明 |
|---|---|---|
| 支付订单 | pay_order | 业务订单,唯一约束:租户订单号、app_id + merchant_order_id |
| 支付尝试 | pay_payment_attempt | 与提供商的一次交互;唯一约束:公开 attempt ID、客户端幂等键、提供商幂等键 |
| 异步通知 | 通知 + PayNotifyJob | 提供商回调经校验后驱动状态迁移,失败进重试 |
| 对账 | PayReconciliationCaseJob、ReconciliationCaseService | 以提供商流水核对,差异生成 case 处理 |
| 未知状态恢复 | PayUnknownAttemptRecoveryJob | 订单过期、超时未回调的尝试自动查询并恢复 |
| 退款 / 结算 | PayRefundFactService、SettlementService、PayTransferSyncJob | 退款、结算、转账各自独立事实与同步 |
不能只用
pay_order.status 推断所有提供商状态;对账与未知状态恢复是支付可靠性关键,任何状态推断都必须回到各事实表。SIM 生命周期
SIM 模块管理卡档案从采购到回收的完整生命周期,涉及与供应商系统的多轮异步交互:
- 采购/入库:
SimProviderOrder、SimImeiPool管理批次与 IMEI 池 - Profile 激活:
SimProfile维护 eSIM profile 档案;SimBinding绑定到设备 - 供应商同步:
SimProviderSyncJob+SimSyncController同步供应商状态,回调SimCallbackProcessJob处理并幂等去重 - 用量与计费:
SimCdr消费 CDR 生成用量快照,SimSubscription关联订阅 - 告警与回收:
SimAlert/SimAlertPolicy阈值告警;生命周期事件SimLifecycleEvent记录状态流转
关键机制:供应商回调幂等、批任务(SimBatchTask)重试、数据保留策略。
告警规则模型
告警能力由 Java alarm(配置面)与 Go alertsvr(执行面)共同构成:
| 组成 | 职责 | 代码位置 |
|---|---|---|
规则 alarm_rule | 触发器(条件类型/操作符/配置 JSON)+ 过滤器逻辑 | Java AlarmRuleController;gRPC AlarmRuleService.GetEnabledRulesByDeviceName |
过滤器 alarm_rule_filter | 附加过滤条件,嵌套在规则下 | gRPC AlarmRuleFilter 消息 |
模板 alarm_rule_template | 规则模板,App 端可选规则快速配置 | AppAlarmRuleTemplateController |
记录 alarm_record | 命中后的告警记录与处理状态 | AlarmRecordController、AppAlarmRecordController |
| 执行评估 | 消费设备数据执行 WHEN-THEN 判断 | Go alertsvr alarmEvaluator.go + ruleIndexCache + stateCache |
规则配置(Java)与规则执行(Go)通过 gRPC 契约解耦:Go 启动时拉取设备启用的规则并本地缓存,事件到达后在缓存上评估,避免每次判断都回源 Java。
关键跨模块关系与约束
| 关系 | 涉及模块 | 约束/原则 |
|---|---|---|
| 设备绑定 | iot + member + subscription + pay | 绑定任务幂等(task_no/订单号唯一);Seat 预占 + 支付 + 激活走 Saga |
| 订阅权益校验 | subscription → Go 网关 | gRPC 按 deviceName 校验能力;产品/能力码由 subscription 维护 |
| 告警规则下发 | alarm → alertsvr | gRPC 查询启用规则,执行侧本地缓存;规则变更需主动失效缓存 |
| 轨迹数据 | Go geosvr/tripsvr → Java prod-gps | Go 高频写 TDengine;Java 只读报表,严禁高频写关系库 |
| 用户语义 | system/member/notify/alarm/gps | 后台接收人走 system_users,APP 用户走 member_user,查询前必须确认表语义 |
| 事件可靠性 | 跨语言消息 | 多副本消费指定 Queue Group;不可丢失消息用 JetStream;消费处理幂等 |