## 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` 以更明确表达分配回收语义。

## 实施记录（2026-04-30）

- 已覆盖的审计写入主链路：`internal/service/iot_card/service.go` 单卡分配/回收，`internal/service/device/service.go` 设备分配/回收，`internal/service/device/binding.go` 绑卡/解绑，配合 `internal/service/iot_card/audit.go` 与 `internal/service/device/audit.go` 统一补齐可读字段。
- 审计查询侧已同步扩展字段说明：`internal/service/asset_audit/operation_content.go` 新增 `iccids`、`device_virtual_no`、`device_virtual_nos`、`target_shop_name`、`source_shop_name` 等说明口径。
- 设备实时状态已统一在 B 端计算 `signal_quality` 与 `signal_bad_reason`，再由 C 端 DTO 复用映射结果。
- 已完成静态验证：`go build ./...`。
- 已完成文档验证：`GOCACHE=/tmp/jh-gocache go run cmd/gendocs/main.go`，`docs/admin-openapi.yaml` 中可见 `signal_quality`、`signal_bad_reason` 与新增 DTO 字段。
- 待补联调验证：当前会话未直接调用后台管理端 / C 端接口，也未触发新的资产操作写入，因此仍需在联调环境补做新日志样本与接口返回抽样。
