Files
junhong_cmp_fiber/openspec/changes/archive/2026-04-09-add-asset-realname-time/design.md
huang 6dfc5c0301
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m5s
feat: 资产解析接口新增实名时间字段
- AssetResolveResponse 新增 real_name_at 字段:card 类型取 first_realname_at,device 类型取绑定卡中最小的实名时间
- BoundCardInfo 新增 real_name_at 字段:各卡自己的 first_realname_at
- RefreshCardDataFromGateway 手动刷新路径补写实名时间:检测到 0→1 变化时同步写入 first_realname_at
- 同步更新 asset-resolve 规格文档

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 12:12:28 +08:00

46 lines
2.5 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
`IotCard` 表已有 `first_realname_at` 字段记录卡每次从未实名0变为已实名1的时间戳轮询路径在每次 `0→1` 时覆盖写入,字段名为"首次"但实际是"最近一次")。该字段目前仅用于内部业务触发(首次实名激活任务),未对外暴露。
**当前问题**
1. `AssetResolveResponse``BoundCardInfo` DTO 没有 `real_name_at` 字段
2. 手动刷新路径(`RefreshCardDataFromGateway`)在更新 `real_name_status` 时漏写 `first_realname_at`
3. `Device` model 无实名时间,设备视角需从绑定卡聚合
## Goals / Non-Goals
**Goals:**
-`GET /api/admin/assets/resolve/:identifier` 响应中暴露实名时间
- 卡视角直接返回 `IotCard.first_realname_at`
- 设备视角返回当前绑定卡 `first_realname_at` 的最小值
- `BoundCardInfo` 列表中每张卡返回各自的实名时间
- 修复手动刷新路径漏写 `first_realname_at` 的 bug
**Non-Goals:**
- 不新增数据库字段(`first_realname_at` 已存在)
- 不修改实名检查轮询逻辑
- 不对设备 model 新增字段(运行时聚合,不持久化)
- 不改变 `triggerFirstRealnameActivation` 的触发条件
## Decisions
### 决策1复用 `first_realname_at` 而非新增字段
`first_realname_at` 在每次 `0→1` 时覆盖写入,语义上等同于"最近一次实名时间"。新增字段需要迁移,收益不成比例。
**替代方案**:新增 `realname_at` 字段,明确"最近一次"语义。
**放弃原因**:需要数据库迁移,且历史卡数据无法回填,反而不如 `first_realname_at` 完整。
### 决策2设备实名时间运行时聚合不持久化
设备无实名时间字段,从绑定卡内存聚合(`buildDeviceResolveResponse` 已查询全部绑定卡),只需遍历取 `MIN(first_realname_at)` 即可,无需额外查询。
### 决策3手动刷新路径与轮询路径对齐
`RefreshCardDataFromGateway``real_name_status` 由非已实名变为已实名时,同步写入 `first_realname_at`,逻辑与 `polling_realname_handler.go``isFirstRealname` 条件完全一致。
## Risks / Trade-offs
- **字段名语义不对齐**`first_realname_at` 叫"首次"但实为"最近一次"。→ 通过 DTO 字段命名为 `real_name_at` 对外屏蔽内部字段名API 消费者不感知。
- **设备实名时间仅限当前绑定卡**:历史上曾绑定过的卡不计入。→ 与业务定义一致(设备换卡后旧卡脱离关系)。