Files
junhong_cmp_fiber/openspec/changes/archive/2026-09-20-add-h5-popup-account-names/design.md
break 863607639f
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
归档
2026-09-20 10:46:34 +08:00

53 lines
3.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
参见 `proposal.md` 的 Why。当前运营弹窗配置读取链路由 Query 直接读取配置模型并映射为统一响应 DTO配置表只保存 `creator``updater` 账号 ID账号名称位于 `tb_account.username`。列表与详情共用响应 DTO但当前映射函数没有账号名称输入。
项目要求读取使用 Query/GORM关联通过 ID 显式查询,不新增 GORM 关联或数据库外键。账号采用软删除,历史配置需要能解析已删除账号。
## Goals / Non-Goals
**Goals:**
- 列表和详情使用同一账号名称语义与响应字段。
- 列表名称补充保持常数次查询,不产生 N+1。
- 名称查询错误沿既有稳定错误链返回。
**Non-Goals:**
- 不保存创建人或更新人的名称快照。
- 不修改配置写入、版本、启停、排序或权限语义。
- 不修改账号删除策略或数据库 Schema。
## Decisions
### 1. 在响应 DTO 增加 `creator_name` 与 `updater_name`
保留 `creator``updater`,新增同语义名称字段。这样现有调用方保持兼容,后台可直接展示名称。未采用替换 ID 或嵌套账号对象,因为都会扩大契约变更并增加前端迁移成本。
### 2. Query 批量读取当前账号名称
列表先读取当页配置,再收集非零且去重后的创建人、更新人 ID通过一次 `Unscoped` GORM 查询读取 `id, username`,生成名称映射后投影响应。详情复用同一批量加载函数,以单元素 ID 集合获得相同语义。
未采用 SQL JOIN当前 Query 已先执行总数与分页读取,独立批量查询更容易保持 Count、排序和配置模型扫描不变也符合项目显式关联约束。未采用逐条账号查询避免 N+1。
### 3. 已删除账号可见,缺失账号返回空名称
账号查询使用 `Unscoped`,因此软删除账号仍能提供历史用户名。映射中没有对应记录时保留字符串零值,表示账号事实已不存在。该行为不制造占位文案,避免把展示策略固化到 API。
### 4. 查询失败不得静默降级
账号名称查询失败包装为稳定数据库错误并终止列表或详情响应。静默返回空名称会把数据库故障与“账号记录不存在”混为同一可观察结果,违反契约。
## Risks / Trade-offs
- [账号用户名后续可修改,历史配置展示的是当前用户名而非操作时快照] → 本次明确只补充当前账号名称;若业务要求历史身份不可变,应另建名称快照变更。
- [列表增加一次账号查询] → 对当页 ID 去重并只选择 `id, username`,查询数量固定为一次。
- [历史脏数据引用不存在账号] → 保留账号 ID名称返回空字符串使调用方仍能识别原始关联值。
## Migration Plan
1. 更新响应 DTO 与 Query 投影。
2. 重新生成 OpenAPI 文档并构建 API、Worker。
3. 在维护者指定的隔离环境请求列表和详情,核对正常账号、软删除账号及不存在账号三种结果。
4. 回滚只需恢复应用代码与生成文档;无数据库迁移或数据回滚。