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

7.1 KiB
Raw Blame History

Context

当前仓库已经存在资产域审计日志能力,核心入口为 internal/service/asset_audit,并由 iot_carddeviceasset 等多个 Service 在写操作节点调用。现状问题不是“没有日志”,而是很多 operation_content 更偏向研发排障视角,包含大量 card_iddevice_idtarget_shop_idbinding_id 之类的内部主键,对业务人员不友好。

设备实时状态方面,后台管理端通过 asset.Service.fetchDeviceGatewayInfo() 从 Gateway 获取完整设备信息C 端再通过 mapDeviceGatewayInfoToClientInfo() 复用该结果。rsrprsrqrssisinr 已完整透出,但缺少“人能直接看懂”的归纳结论,因此同一问题会在 B 端与 C 端重复解释。

约束如下:

  • 必须遵循 Handler -> Service -> Store -> Model 分层,不在 Handler 中拼复杂业务判断。
  • 不新增自动化测试文件,本次仅规划实现与手工验证路径。
  • 审计日志优化必须兼容现有字段,避免破坏现有依赖方。
  • 信号综合字段只新增,不替换或删除原始信号字段。

Goals / Non-Goals

Goals:

  • 让资产操作审计日志的 before_data/after_data 在保留内部 ID 的同时,补足业务可读字段。
  • 为设备实时状态新增 signal_qualitysignal_bad_reason 两个综合字段。
  • 统一 B 端与 C 端对信号综合字段的输出文案和判定逻辑。
  • 将“怀疑原因”设计为面向小白的提示语,而不是通信指标术语解释。

Non-Goals:

  • 不调整店铺删除时“店铺下仍有账号”的业务规则。
  • 不处理“禁用企业账号看不到”的假问题。
  • 不修改现有原始信号字段 rsrprsrqrssisinr 的保留与含义。
  • 不新增独立的信号诊断接口或独立日志查询接口。

Decisions

决策1审计日志采用“补充可读字段”而不是“替换内部字段”

选择:保留现有 ..._id..._idstarget_shop_id 等内部字段,同时补充可读字段,如 iccidiccidsdevice_virtual_nodevice_imeishop_nameenterprise_name

理由

  • 兼容已有日志消费方与排障场景。
  • 业务查看与研发定位可同时满足,不需要二选一。
  • 变更影响更小,不需要迁移历史日志结构。

备选方案:直接把内部 ID 字段改写为名称或业务标识。 放弃原因:会损失排障精度,也可能影响已存在的日志解析逻辑。

决策2可读字段在各业务写入点就近补齐

选择:在 iot_carddeviceasset 等具体业务 Service 组装审计参数时,就近把业务标识和名称补进 BeforeData / AfterDataasset_audit 负责统一封装但不做过度猜测。

理由

  • 具体业务 Service 最清楚当前上下文里哪张卡、哪台设备、哪家店铺是本次操作对象。
  • 避免在 asset_audit 层引入大量额外查询和猜测逻辑。
  • 更符合现有项目里“Service 负责业务语义拼装”的边界。

备选方案:在 asset_audit 中根据 ID 反查名称并自动补全。 放弃原因:会让通用审计层承担过多领域知识,也会增加额外查询成本和隐式行为。

决策3信号综合字段在 B 端统一计算C 端复用映射结果

选择:在后台管理端 Gateway 映射链路中新增统一的信号摘要计算函数,先产出 DeviceGatewayInfo.signal_qualityDeviceGatewayInfo.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_nodevice_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 以更明确表达分配回收语义。