Files
junhong_cmp_fiber/openspec/changes/improve-audit-log-readability-and-signal-summary/design.md
huang 5425e2ce19 保留提案基线以便团队 worktree 按契约执行
Constraint: omx team 默认使用独立 worktree,要求 leader 工作区干净
Rejected: git stash 提案文件 | 会让 worker 无法读取当前提案契约
Confidence: high
Scope-risk: narrow
Directive: 后续实现必须继续严格按 tasks.md 顺序推进,不得擅自跳步
Tested: git status 仅剩未跟踪的 .omx 上下文文件
Not-tested: 未验证提案内容本身的实现正确性
2026-04-30 15:11:32 +08:00

114 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
当前仓库已经存在资产域审计日志能力,核心入口为 `internal/service/asset_audit`,并由 `iot_card``device``asset` 等多个 Service 在写操作节点调用。现状问题不是“没有日志”,而是很多 `operation_content` 更偏向研发排障视角,包含大量 `card_id``device_id``target_shop_id``binding_id` 之类的内部主键,对业务人员不友好。
设备实时状态方面,后台管理端通过 `asset.Service.fetchDeviceGatewayInfo()` 从 Gateway 获取完整设备信息C 端再通过 `mapDeviceGatewayInfoToClientInfo()` 复用该结果。`rsrp``rsrq``rssi``sinr` 已完整透出,但缺少“人能直接看懂”的归纳结论,因此同一问题会在 B 端与 C 端重复解释。
约束如下:
- 必须遵循 `Handler -> Service -> Store -> Model` 分层,不在 Handler 中拼复杂业务判断。
- 不新增自动化测试文件,本次仅规划实现与手工验证路径。
- 审计日志优化必须兼容现有字段,避免破坏现有依赖方。
- 信号综合字段只新增,不替换或删除原始信号字段。
## Goals / Non-Goals
**Goals:**
- 让资产操作审计日志的 `before_data/after_data` 在保留内部 ID 的同时,补足业务可读字段。
- 为设备实时状态新增 `signal_quality``signal_bad_reason` 两个综合字段。
- 统一 B 端与 C 端对信号综合字段的输出文案和判定逻辑。
- 将“怀疑原因”设计为面向小白的提示语,而不是通信指标术语解释。
**Non-Goals:**
- 不调整店铺删除时“店铺下仍有账号”的业务规则。
- 不处理“禁用企业账号看不到”的假问题。
- 不修改现有原始信号字段 `rsrp``rsrq``rssi``sinr` 的保留与含义。
- 不新增独立的信号诊断接口或独立日志查询接口。
## Decisions
### 决策1审计日志采用“补充可读字段”而不是“替换内部字段”
**选择**:保留现有 `..._id``..._ids``target_shop_id` 等内部字段,同时补充可读字段,如 `iccid``iccids``device_virtual_no``device_imei``shop_name``enterprise_name`
**理由**
- 兼容已有日志消费方与排障场景。
- 业务查看与研发定位可同时满足,不需要二选一。
- 变更影响更小,不需要迁移历史日志结构。
**备选方案**:直接把内部 ID 字段改写为名称或业务标识。
**放弃原因**:会损失排障精度,也可能影响已存在的日志解析逻辑。
### 决策2可读字段在各业务写入点就近补齐
**选择**:在 `iot_card``device``asset` 等具体业务 Service 组装审计参数时,就近把业务标识和名称补进 `BeforeData` / `AfterData``asset_audit` 负责统一封装但不做过度猜测。
**理由**
- 具体业务 Service 最清楚当前上下文里哪张卡、哪台设备、哪家店铺是本次操作对象。
- 避免在 `asset_audit` 层引入大量额外查询和猜测逻辑。
- 更符合现有项目里“Service 负责业务语义拼装”的边界。
**备选方案**:在 `asset_audit` 中根据 ID 反查名称并自动补全。
**放弃原因**:会让通用审计层承担过多领域知识,也会增加额外查询成本和隐式行为。
### 决策3信号综合字段在 B 端统一计算C 端复用映射结果
**选择**:在后台管理端 Gateway 映射链路中新增统一的信号摘要计算函数,先产出 `DeviceGatewayInfo.signal_quality``DeviceGatewayInfo.signal_bad_reason`,再由 C 端映射函数直接透传。
**理由**
- 避免 B 端和 C 端分别实现一套阈值和文案,造成口径漂移。
- 现有 C 端本来就是从 B 端 DTO 映射,复用成本最低。
- 未来如果要调阈值或文案,只需要维护一处。
**备选方案**B 端与 C 端各自计算。
**放弃原因**:重复逻辑多,后续难保证一致。
### 决策4信号综合字段采用“结果 + 怀疑原因”的轻量模型
**选择**
- `signal_quality` 使用固定的用户可读枚举:`信号很好 / 信号正常 / 信号较弱 / 信号很差 / 暂无数据`
- `signal_bad_reason` 使用怀疑式提示语:`怀疑当前位置信号覆盖较弱 / 怀疑周围干扰较多 / 怀疑设备所处位置遮挡较强 / 怀疑网络环境不稳定 / 暂时无法判断`
**理由**
- 适合小白用户快速理解,不要求其理解通信指标定义。
- “怀疑”语气符合基于多指标估算而非绝对诊断的产品事实。
- 可在不暴露复杂阈值的前提下给出下一步判断方向。
**备选方案**直接输出“RSRP 低 / SINR 低 / RSRQ 差”等技术术语。
**放弃原因**:对非技术用户不友好,无法满足本次需求目标。
### 决策5信号判定使用固定优先级规则避免多原因并列
**选择**:当多个原始指标同时异常时,按固定优先级输出单一 `signal_bad_reason`,优先表达最容易被用户理解的问题类型;当数据缺失或不足时输出“暂时无法判断”。
**理由**
- 单字段只返回一个原因,前端展示更稳定。
- 避免一次返回多个原因造成文案冗长和理解负担。
- 更适合现有 DTO 结构,不需要额外数组字段。
**备选方案**:返回原因列表。
**放弃原因**:复杂度更高,也不符合“只新增两个字段”的收敛目标。
## Risks / Trade-offs
- **[风险] 审计日志可读字段补充不一致** → **缓解**:在设计中约束“同类资源尽量使用统一字段名”,例如卡统一使用 `iccid`/`iccids`,设备统一使用 `device_virtual_no``device_imei`
- **[风险] 信号怀疑原因与真实现场不完全一致** → **缓解**:文案统一使用“怀疑”语气,并保留原始四个指标供专业人员复核。
- **[风险] 设备实时 DTO 新增字段后文档未同步** → **缓解**:实现阶段同步更新 DTO 描述与生成文档。
- **[权衡] 不在审计通用层自动反查名称会保留部分业务代码重复** → **接受**:本次优先保持边界清晰与最小侵入。
## Migration Plan
1. 在变更目录中明确审计日志与信号摘要的规格要求。
2. 实现阶段先补充 B 端设备实时 DTO 与统一信号摘要函数,再同步 C 端映射。
3. 分批调整资产审计日志主要写入点,优先覆盖当前已确认大量写入内部主键的链路。
4. 生成并检查接口文档,确认新增字段在后台管理端与 C 端响应中可见。
5. 通过手工接口调用与数据库日志抽样确认行为符合预期。
**回滚策略:**
- 若信号摘要文案或阈值不符合预期,可仅回滚摘要计算与 DTO 新字段,不影响原始四个指标。
- 若审计日志可读字段补充引发问题,可回滚具体写入点变更,保留现有日志表与基础审计能力。
## Open Questions
- `signal_bad_reason` 的优先级阈值最终是否需要沉淀到 `pkg/constants` 作为可复用常量,还是先在单一计算函数中集中维护。
- 审计日志中店铺相关字段是否统一使用 `shop_name`,还是区分 `source_shop_name` / `target_shop_name` 以更明确表达分配回收语义。