Files
junhong_cmp_fiber/.scratch/ur45-exchange-asset-search/issues/02-independent-old-new-asset-search.md
2026-07-22 12:37:05 +09:00

4.4 KiB
Raw Blame History

02 — 提供新旧资产独立搜索的换货列表契约

What to build: 运营人员在换货列表中可以分别提交 old_asset_keywordnew_asset_keyword,通过 IoT 卡的 ICCID、接入号、虚拟号或设备的虚拟号、IMEI、SN 搜索对应一侧的换货资产。两个关键词同时提交时按 AND 组合,并继续与状态、流程类型、创建时间、分页和现有店铺数据范围共同生效;旧通用 identifier 不再属于新接口契约。该列表能力包含接口发布、真实 PostgreSQL 性能证据和前端同维护窗口切换所需的完整验收契约,可独立交付。

Blocked by: None — can start immediately.

Status: ready-for-agent

架构通道: 主通道为 Query。仅将本次明显复杂化的换货列表读取用例收口为查询能力可直接使用 GORM、子查询或固定次数批量查询完成候选解析、权限过滤和 DTO 投影;不得让列表读取经过聚合根或执行写操作。

完整业务边界: 本票收口列表请求校验、候选资产解析、新旧资产主键过滤、权限、分页计数、排序、响应投影、错误转换、OpenAPI 发布、性能验证和前端联调验收说明。明确不迁移换货详情及其他读取接口,不创建换货聚合根,不修改换货写侧状态规则,不保留通用 identifier 的第二套长期搜索语义;不实现 UR#86 资产前代/后代关系或 UR#98 店铺继承。当前仓库未包含可实施该页面的前端工程,因此前端工作以接口契约和人工验收清单交付,不虚构前端代码改动。

  • 列表请求新增最长 100 字符的 old_asset_keywordnew_asset_keyword,并从新契约移除通用 identifier;空值不增加对应过滤条件。
  • 仅提供旧资产关键词时只按 old_asset_type + old_asset_id 过滤,绝不因新资产命中而返回;仅提供新资产关键词时规则对称。
  • 两个关键词同时提供时按 AND 组合,并与状态、流程类型、创建时间范围和分页条件按 AND 组合。
  • IoT 卡候选支持对 ICCID、接入号和虚拟号做包含匹配设备候选支持对虚拟号、IMEI 和 SN 做包含匹配;候选资产必须排除软删除记录。
  • 换货单通过资产类型和资产主键命中,因此历史非规范快照不回填、不改写,但仍能通过所关联资产的任一受支持标识搜索到。
  • 无候选资产或无换货单命中时返回成功的空分页;候选查询或换货单查询发生数据库错误时返回脱敏 500不得降级为空结果。
  • 最终换货单查询继续排除软删除记录并应用现有店铺数据范围;平台、超级管理员和代理账号的既有可见范围不被候选资产解析绕过。
  • 候选解析和换货单过滤使用数据库子查询或固定次数批量查询,不按换货单逐行反查资产;totalitems 使用完全相同的过滤条件,结果按创建时间倒序。
  • Handler 对完整请求 DTO 执行校验;非法关键词长度、分页、状态、流程类型或时间参数统一返回 HTTP 400、code=1001msg=参数验证失败,详细原因仅记录中文日志。
  • HTTP 集成测试覆盖仅旧关键词、仅新关键词、双关键词 AND、状态与时间组合、空参数、无匹配、非法参数、历史快照、数据库故障和各类账号数据权限。
  • 响应保持统一外层结构并继续分别返回新旧资产类型、ID、快照标识、状态及状态名称。
  • OpenAPI 中的换货列表只公开 old_asset_keywordnew_asset_keyword包含长度限制、AND 语义和中文说明,不再公开通用 identifier;重新生成文档并验证请求、响应和错误契约与实现一致。
  • 使用真实 PostgreSQL 和代表性大结果集验证查询次数固定、无逐行资产反查、total 与分页结果一致,并记录查询计划或等价证据;性能满足项目列表接口目标。
  • UR#45 中文功能总结补充搜索契约、权限与脱敏错误边界、性能结果、发布回滚方式和前端联调注意事项README 中的 UR#45 索引可以定位该说明。
  • 前端人工验收清单明确要求:将单一资产输入框拆为旧资产和新资产输入框;空值不提交;双条件按 AND 提交;表格不混列新旧资产;前端不解析标识、不本地过滤当前页;清空、分页、空态和失败反馈沿用现有交互。