diff --git a/openspec/changes/complete-july-iteration-test-release/.openspec.yaml b/openspec/changes/complete-july-iteration-test-release/.openspec.yaml new file mode 100644 index 0000000..5e6d53a --- /dev/null +++ b/openspec/changes/complete-july-iteration-test-release/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-07-24 diff --git a/openspec/changes/complete-july-iteration-test-release/design.md b/openspec/changes/complete-july-iteration-test-release/design.md new file mode 100644 index 0000000..97284c7 --- /dev/null +++ b/openspec/changes/complete-july-iteration-test-release/design.md @@ -0,0 +1,237 @@ +## Context + +### 当前状态 + +七月标准评审稿覆盖 28 条技术/业务线,但实施信息分散在 28 份相关 PRD、121 张七月业务/公共基础 Tickets、22 张全局审计 Tickets、代码、迁移、文档和提交记录中。现有状态存在四类偏差: + +1. **完成状态漂移**:TECH 公共基础 12/12 与 UR55 5/5 已完成;UR45 代码已落地但两张 Ticket 仍为 `ready-for-agent`;UR46 四张票仅标记“后端 done”;UR60、UR86 后端已完成但仍有人工作与历史抽样;顶层 PRD 状态普遍未同步。 +2. **依赖不可执行**:公共通知、UR37、UR48、UR49 存在不存在文件、尚未拆票占位符或标题漂移;多个需求仍把未完成的全局 Audit Event 发布门禁作为 blocker。 +3. **跨文档冲突**:`openspec/config.yaml` 仍描述旧 `Handler → Service → Store → Model` 单一路径、`{code,message,...}` 和强制 TDD,而当前 `AGENTS.md`、DDD 规范及用户本次决策已经明确三通道、`{code,msg,...}` 和测试环境临时豁免。 +4. **发布目标改变**:目标是 2026-07-27 前部署测试环境,不是生产验收。全局审计提交 `ff44305` 只完成 Integration Log 基础、Access Log 加固和离线覆盖门禁;`integrationlog.Repository` 未装配生产组合根,`cmd/audit-coverage` 不在运行时,现有代码可安全冻结。 + +### 权威来源与利益相关方 + +- 用户本次确认决定是审计/测试/里程碑范围的最高优先级。 +- 七月标准评审稿是业务冲突裁决来源;冻结 PRD 保留详细不变量、API、状态机和异常闭环;既有 Ticket 保留已评审纵向切片;代码和提交只证明完成状态。 +- 利益相关方包括后端、前端、产品、测试环境验收负责人、运维,以及企微、支付、Gateway、运营商与对象存储配置负责人。 + +### 约束 + +- 技术栈固定为 Go 1.25.4、Fiber v2、GORM、PostgreSQL、Redis、Asynq、Viper、Zap、sonic、Validator,不新增替代依赖。 +- 数据库不使用外键或 GORM 关联标签;金额以分为单位;生命周期状态用 `int`,类型/方式用 `string`。 +- API 使用 `{code,msg,data,timestamp}`、`pkg/errors`、后端权限与数据范围、默认 20/最大 100 分页。 +- 触碰式迁移以完整用例为单位,禁止顺手重构未触碰旧代码。 +- 本 Change 只写 OpenSpec 规划产物;不修改业务代码、不运行测试、不提交 Git。 + +## Goals / Non-Goals + +**Goals:** + +- 建立唯一、稳定、可勾选的 28 线总台账和后续唯一实施入口。 +- 真实表达后端、前端、验证、发布四个维度,不把代码存在等同验收完成。 +- 保留冻结业务规则,将全部未完成工作组织为三批可执行纵向切片,并消除悬空和模糊依赖。 +- 在不削弱资金、审批、异步与外部调用可靠性的前提下,形成测试环境快速交付顺序。 +- 冻结现有审计代码并解除 Audit Event 对测试环境的阻塞,同时明确生产前恢复清单。 +- 统一前后端契约、停机部署、回滚和延期验证边界。 + +**Non-Goals:** + +- 不重写、废弃或回填全部原 PRD/Tickets,也不再创建一批 `.scratch/issues`。 +- 不实施任何七月业务代码、迁移、前端页面或运行时配置。 +- 不加入需求16,不创建 `distribution` 领域或任何分销/提现能力。 +- 不继续开发 Audit Event Writer、审计中心、历史投影、审计导出、保留清理或一次性审计切换。 +- 不删除 `ff44305`、`pkg/sanitizer`、`tb_integration_log` 迁移或其他已有可靠性代码。 +- 不新增/运行自动化测试,不执行真实外部验收;这些只作为生产前延期项。 + +## Decisions + +### 1. 使用三个总控 capability,而不是复制 28 份业务规格 + +本 Change 使用 `july-iteration-master-ledger`、`july-iteration-delivery-contract`、`july-iteration-test-release-gate` 三个新能力。业务细节继续引用标准评审稿与冻结 PRD,`tasks.md` 则把每条线落实为具体纵向任务。 + +**理由**:统一 Change 的职责是建立权威台账、执行依赖和发布契约;完整复制 28 份 PRD 会制造第二套易漂移业务真相。 + +**否决方案**:为每个 UR 建一个重复 spec。该方案文件数量大、易与冻结 PRD 不一致,也违背“不重写原 PRD”的定位。 + +### 2. 多维状态替代单一完成状态 + +每条线记录后端、前端、验证、发布四维状态,并允许“元数据待收口”。初始证据如下: + +| 稳定编号 | 初始后端状态 | 前端/验证状态 | 证据结论 | +|---|---|---|---| +| `JULY-TECH-FOUNDATION` | 已完成 | 本仓交付完成 | PRD `completed`、12/12 Tickets、提交 `17782d5`/`7e0171a` | +| `JULY-UR55` | 已完成 | 跨仓状态不可独立证明 | 5/5 Tickets、提交 `9818537` 等;PRD 顶层滞后 | +| `JULY-UR45` | 后端完成 | 前端/人工待确认 | 提交 `55bdc3a`;2 张 Ticket 元数据未收口 | +| `JULY-UR46` | 后端完成 | 前端/人工未完成 | 4/4 `done(后端)`、提交 `8d65b26` 等 | +| `JULY-UR60` | 后端完成 | 前端联调/人工未完成 | 2 completed + 1 ready-for-human | +| `JULY-UR86` | 后端完成 | 前端/历史抽样未完成 | 1 completed + 1 blocked、提交 `c58773e` | +| 其余 22 条 | 未开始 | 未开始 | PRD/Tickets 均未形成业务实现证据 | + +**理由**:防止把“代码已存在”“测试曾写过”“Ticket 元数据完成”“测试环境部署”混为同一事实。 + +**否决方案**:只使用 `[x]/[ ]` 标记整条需求。它无法表达后端完成但前端、人工或生产门禁未完成。 + +### 3. 按当前 DDD 三通道覆盖旧配置中的单一路径 + +任务采用:复杂写 `Handler → Application → Domain → Repository/Infrastructure`;简单写 `Handler → Application 事务脚本 → Persistence`;读取 `Handler → Query → GORM/DTO`。旧 `Handler → Service → Store → Model` 只保留给未触碰旧用例。 + +依赖注入继续使用结构体字段/构造器显式注入 Application、Query、Repository、Adapter、Outbox、Integration Log 与配置;Domain 不依赖 Fiber/GORM/Redis。常量进入 `pkg/constants`,Redis Key 由函数生成。 + +**理由**:这是当前 `AGENTS.md` 和 DDD 规范的触碰式演进合同,比 `openspec/config.yaml` 的旧上下文更新且更具体。 + +**否决方案**:强制所有新需求继续堆入旧 Service,或全仓一次性 DDD 重构;前者扩大旧 Service,后者超出当前完整用例边界。 + +### 4. 三批实施与稳定依赖图 + +```mermaid +flowchart TD + PF[JULY-TECH-FOUNDATION 已完成] + N[B1-01 公共通知] + W[B1-02 UR37 企微] + C[B1-03 UR38 信用钱包] + S[B1-04 UR94 卡状态] + G[B1-05 UR43 系列授权] + L[B1-06 UR47 限速] + P[B1-07 UR48 支付方式] + O[B1-08 UR96 业务员] + X[B1-09 UR98 换货继承] + R40[B2-01 UR40 可售策略] + R73[B2-02 UR73 复机] + R53[B2-03 UR53 实名筛选] + R62[B2-04 UR62 H5 顺序] + R97[B2-05 UR97 余额预警] + R36[B2-06 UR36 批量订购] + R49[B2-07 UR49 设备批量] + R34[B3-01 UR34 充值] + R35[B3-02 UR35 退款] + R57[B3-03 UR57 禁止换货] + R33[B3-04 UR33 临期] + R44[B3-05 UR44 摘要] + R42[B3-06 UR42 导出] + PF --> N & W & C & S & G & L & P & O & X + S --> R73 & R53 & R62 + C --> R97 & R36 & R34 & R35 + O --> R97 & R33 + N --> R97 & R34 & R35 & R33 + R40 --> R36 & R33 + R36 --> R49 + W --> R34 & R35 & R44 + R35 --> R57 & R44 + R34 --> R44 + R33 --> R42 + R44 --> R42 +``` + +UR46 已完成后端并作为 B3-04/B3-06 的已满足后端依赖;UR55 已满足 UR46。UR45、UR46、UR60、UR86 只进入最终前端/人工/元数据收口,不重复实现后端。 + +**理由**:先交付公共写入、资金和外部系统边界,再交付依赖它们的业务,最后组合复杂业务,可消除原 `.scratch` 的悬空引用。 + +**否决方案**:按数据库、Service、Handler 水平排期,或让下游先各自复制公共能力;两者都会制造重复实现和不可验证中间态。 + +### 5. 原 Tickets 保留业务粒度,但统一移除测试与 Audit Event 阻塞 + +已有 Tickets 的业务切片 SHALL 在对应总任务内逐项映射;原本纯自动化 Harness、验收测试、真实外部门禁或 Audit Event 写入子项不在本测试环境实施。它们移动到“延期验证与生产门禁”,而不是被标记完成。不存在路径和占位符改为本 Change 的稳定任务号: + +- 公共通知 04 改依赖 `B1-08.6`,不再引用不存在的 UR96 文件名。 +- UR37-01~13 形成可供 UR35 使用的公共能力;原 UR37-14“退款首个真实企微门禁”改映射到生产前 `6.2`,不再保留“UR35 拆票后替换”的占位符,也不反向阻塞 UR35 代码实现。 +- UR48/UR49 发布依赖使用本 Change 任务号,不依赖漂移标题。 +- 所有 `.scratch/tech-global-audit/issues/01`、`19`、`20`、`21` 等 Audit Event 阻塞边在测试环境路径删除,转入生产前 `6.*` 延期清单。 + +**理由**:用户已明确授权测试和审计范围调整;保留旧 blocker 会让测试环境目标不可执行。 + +**否决方案**:修改原 Tickets。原 Tickets 需要保留评审历史,本 Change 只提供新的执行映射。 + +### 6. 前后端契约以“冻结字段 + 状态矩阵 + 人工验收点”管理 + +每条涉及 API 的纵向任务记录 Endpoint、请求字段、完整 `data`、用户类型、资源所有权、分页/排序/过滤、错误码、状态/枚举、前端页面与异常状态。响应包络一律为 `{code,msg,data,timestamp}`,参数错误使用 `CodeInvalidParam`,资源不存在/越权使用 `CodeForbidden` 统一语义。 + +当前仓库无前端源码,因此后端任务只交付 OpenAPI、样例、字段和框架无关交互;前端完成必须由外部仓库或人工证据单独勾选。新增 Handler 同步 `cmd/api/docs.go` 与 `cmd/gendocs/main.go`。 + +**理由**:可以防止后端代码完成被误记为全链路完成,同时给前端明确实现输入。 + +### 7. 资金、审批、异步与外部调用保留完整异常闭环 + +- **资金**:钱包余额/版本/流水是 Domain Ledger;扣款、冻结、入账、退款按唯一业务键、乐观锁/条件更新和同事务事实保证;支付成功与钱包入账分阶段,已收款不得因后续失败丢失。 +- **审批**:企微负责节点/审批人/意见/附件;本地保存业务快照、实例和终态处理。提交结果未知不盲重试;回调与轮询进入同一同步用例;通过后撤销按是否已产生资金事实分流。 +- **异步**:关键副作用同事务写 Outbox,Relay 投递 Asynq,消费者按至少一次与处理租约设计;任务五态和业务成功/失败计数分离。 +- **外部调用**:Integration Log 在请求/回调边界记录脱敏尝试、结果未知和恢复事实;支付、企微、Gateway、运营商状态不得由日志替代业务表。 +- **错误**:Application/Domain/Query 使用 `pkg/errors`,客户端不接收底层 SDK/GORM/Validator 错误;关键错误使用中文日志并携带稳定关联 ID。 + +Audit Event 在本测试里程碑不接入新业务,以上 Domain Ledger、Integration Log、Outbox、事务和幂等均不得延期。 + +### 8. 审计冻结对运行时无新增影响 + +边界保持:Access Log 负责 HTTP 调试;Audit Event 负责操作者治理但本轮冻结;Domain Ledger 负责金额/状态事实;Integration Log 负责外部交互;Outbox 负责可靠投递。 + +`ff44305` 的运行时分析为: + +- `integrationlog.Repository` 当前仅在自身测试实例化,未注入 API/Worker 生产组合根;冻结不会改变现行业务写路径。 +- `cmd/audit-coverage` 扫描仓库并生成离线基线,不属于运行时请求或 Worker。 +- `pkg/sanitizer` 已被 Access Log 复用敏感字段判定,递归遍历、路由策略、摘要和 50KB 截断仍由 logger 包执行,必须保留。 +- `000167_create_audit_integration_log` 只建独立表与索引,`audit_event_id` 为普通 bigint,无外键,可保留而不要求启用审计中心。 + +**理由**:保留已提交安全和可靠性能力,同时避免半成品 Audit Event 门禁阻塞业务。 + +**否决方案**:回滚 `ff44305` 或删除审计迁移;没有必要且会丢失 Access Log 加固和未来恢复基线。 + +### 9. 测试配置冲突由用户本次里程碑决策覆盖 + +本测试环境里程碑不生成/运行自动化测试。每个批次只执行 `gofmt`、必要生成、`go build ./...`、迁移/路由/Worker/配置部署检查。状态使用“代码完成、验证延期”,不写“PASS”。 + +`openspec/config.yaml` 的 TDD、覆盖率与 `{message}` 规则属于通用旧配置;本次用户明确决策、`AGENTS.md` 和本 Change 的 `{msg}` 契约优先。生产前必须重新恢复自动化、真实依赖、性能、安全、权限和人工验收。 + +**理由**:满足明确交期决定,同时用状态和延期清单控制风险,不伪造证据。 + +## Risks / Trade-offs + +- **[无自动化回归导致状态机、资金与权限缺陷更晚暴露]** → 每批强制构建和部署检查;测试环境限制访问与资金;所有未执行验证进入生产阻塞清单,禁止沿用豁免。 +- **[三批范围仍大,2026-07-27 前无法全部完成]** → 依赖 frontier 可并行,但下游只在具体上游完成后启动;状态台账实时反映未开始和代码完成/验证延期,不通过改状态掩盖延期。 +- **[原 Tickets 中审计与测试子项被误认为删除]** → 在任务映射中标注“测试环境豁免,转 D-*”,生产前必须恢复;原文件不修改。 +- **[Audit Event 未接入导致测试环境缺少操作者治理证据]** → 保留 Access Log、Domain Ledger、Integration Log 和关联 ID;限制为测试环境,生产前完成审计专项。 +- **[Integration Log Repository 未生产装配但下游以为已可用]** → 每个真正需要外部交互的业务纵向任务显式完成 Adapter/组合根装配;不能把迁移存在等同运行时接入。 +- **[前端仓库不在当前工作区导致后端状态被过度声明]** → 前端契约和人工验收独立复选框,后端无法代勾。 +- **[停机迁移后存在不可逆审批/支付/资金事实]** → 开放访问前验证失败可回退;产生事实后暂停生产者、保留流水/Outbox/Integration Log并前向修复,不清表、不恢复旧 Writer。 +- **[原 PRD 的依赖环阻塞执行]** → UR33 先交付临期 Query/通知,UR42 后接导出 Scene;UR34/35 先交付状态模型,UR44 再投影摘要,UR42 最后接 Scene。 +- **[旧配置与当前规范继续漂移]** → 本 Change 明确优先级;不在本次顺手修改 `openspec/config.yaml`,另行治理。 + +## Migration Plan + +### 规划到实施 + +1. 冻结本 Change 的 proposal/design/specs/tasks,后续不从分散 `.scratch` 目录直接启动七月新工作。 +2. 按 B1 → B2 → B3 的具体编号领取任务;同批无依赖项可并行,有依赖项顺序执行。 +3. 每个需求先完成冻结 PRD 的业务纵向切片,再执行该批 `gofmt`、必要生成、`go build ./...` 和部署检查。 +4. 完成 F1 已落地需求的元数据/前端/人工收口,再执行 F2 测试环境装配与停机部署。 +5. 测试环境运行期间保留 D 组延期项未勾选;生产发布另开恢复窗口逐项完成。 + +### 测试环境停机发布顺序 + +```mermaid +flowchart LR + Freeze[冻结版本与配置] --> Stop[维护模式/停止相关写入和 Worker] + Stop --> Migrate[执行增量迁移与前置数据检查] + Migrate --> Backend[发布 API、Relay、Worker] + Backend --> Frontend[发布匹配的前端版本] + Frontend --> Configure[装配企微/支付/Gateway/运营商/对象存储配置] + Configure --> Check[构建、路由、Worker、迁移、版本一致性部署检查] + Check --> Resume[恢复 Worker 与访问] +``` + +### 回滚 + +- 开放访问前:可回滚应用和确认可逆的迁移;未通过检查时保持维护模式。 +- 开放访问后:已产生的审批、支付、钱包流水、订单、退款、充值、通知、Outbox、Integration Log 与部分成功批量任务不得删除;暂停异常入口并前向修复。 +- 支付成功未入账、审批终态未处理、Outbox 积压必须由恢复 Worker 幂等完成,不能要求用户重复提交或重复付款。 +- 信用额度一旦产生负余额,不得回退到忽略信用边界的旧扣款逻辑。 + +### 生产发布前恢复门禁 + +- 自动化测试与完整构建、真实 PostgreSQL/Redis/Asynq 验证。 +- 真实企微模板/绑定/附件/回调/轮询,微信/支付宝预下单/查单/回调,Gateway 限速与运营商回调验收。 +- 前后端全链路、历史数据抽样、存量迁移和停机演练。 +- 权限、分页、N+1、性能、安全、Access Log 敏感矩阵与回滚演练。 +- 恢复 Audit Event Writer、业务覆盖、审计中心/历史投影和一次性发布门禁的评审与实施;不得沿用本测试豁免。 + +## Open Questions + +无阻塞性业务问题。实现期仍需由部署负责人提供企微、支付、Gateway、运营商、对象存储和前端仓库的测试环境配置与版本,但这些属于执行输入,不改变本 Change 的范围或架构决定。 diff --git a/openspec/changes/complete-july-iteration-test-release/proposal.md b/openspec/changes/complete-july-iteration-test-release/proposal.md new file mode 100644 index 0000000..29699f9 --- /dev/null +++ b/openspec/changes/complete-july-iteration-test-release/proposal.md @@ -0,0 +1,39 @@ +## Why + +七月迭代的标准评审稿、28 条技术/业务线、已评审 PRD、既有 Tickets、代码完成证据和发布约束目前分散在多个 `.scratch` 目录及提交记录中,已出现“代码已落地但元数据未收口”“后端完成被误认为整体验收完成”和跨 PRD 阻塞仍引用已暂缓审计专项等状态漂移。为在 2026-07-27 前形成可部署到测试环境的唯一剩余实施入口,需要建立一个统一、可勾选且保留来源追溯的 OpenSpec Change。 + +本 Change(功能 ID:`feature-july-iteration-test-release`)不重写既有 PRD,也不实施业务代码;它以已评审标准稿为冲突裁决来源,将既有 PRD 冻结为业务事实来源,并统一状态、依赖、纵向任务、测试环境发布门槛和生产前延期治理项。 + +## What Changes + +- 建立覆盖 28 条技术/业务线的唯一总台账,逐条记录稳定编号、来源 PRD/Ticket、主/辅助架构通道、具体上游任务、后端状态、前端状态、验证状态和发布状态。 +- 按真实证据预置状态:TECH 七月公共开发基础和 UR55 标记已完成;UR45 标记“后端完成、原 Ticket 元数据待收口”;UR46、UR60、UR86 仅标记后端完成,保留前端与人工验收未完成;其余 22 条线保持未开始。 +- 将已有 Tickets 直接纳入统一执行契约;将 UR33、UR34、UR35、UR42、UR44、UR53、UR57、UR62、UR73、UR97 的冻结 PRD 转换为可独立实施和验证的纵向任务,不再创建新的 `.scratch/issues`。 +- 按三批实施:共享核心与独立 frontier、共享核心下游、复杂业务;最终收口已落地需求的前端契约、测试环境装配、迁移和人工验收准备。 +- 将用户已确认的紧急交付决策写入契约:本里程碑目标是测试环境部署,不是生产验收;不新增 `_test.go`、不运行 `go test`、不执行真实 PostgreSQL/Redis/企微/支付/Gateway 自动验收,仅执行 `gofmt`、必要代码生成、按批次 `go build ./...` 与部署检查。 +- 暂缓全局 Audit Event 专项及其七月发布阻塞边:保留提交 `ff44305` 及既有审计代码、迁移和 Access Log 脱敏,不继续开发审计中心、Audit Event 写入、历史投影或一次性审计发布门禁;生产发布前必须恢复为延期治理项,不得永久标记 N/A。 +- 保留 Integration Log、Outbox、幂等、事务和外部调用恢复能力,它们继续作为业务可靠性设施,不随 Audit Event 暂缓而删除、回滚或绕过。 +- 永久排除已于 2026-07-14 移出本期的需求16;不得创建分销码、代理申请、分销关系、佣金提现相关表、API、页面、领域目录或迁移。 +- 统一接口与工程约束:Fiber、GORM、PostgreSQL、Redis、Asynq、Viper、Zap、sonic;复杂写、简单写、Query 三通道触碰式迁移;统一响应 `{code,msg,data,timestamp}`;错误使用 `pkg/errors`;列表默认 20、最大 100;数据权限、幂等、无外键和文档生成器更新继续遵守项目标准。 +- **BREAKING**:按冻结 PRD 和标准评审稿实施时,退款与平台线下充值将停机切换到企微审批并下线旧本地审批/入账动作接口;系列授权等明确要求同批切换的旧混合命令语义不保留长期兼容层。 + +## Capabilities + +### New Capabilities + +- `july-iteration-master-ledger`: 定义 28 条线的唯一稳定编号、来源权威、真实完成状态、具体依赖和需求16排除规则。 +- `july-iteration-delivery-contract`: 定义冻结业务来源、DDD 三通道、API/权限/分页/错误契约、可靠性设施及前后端纵向交付边界。 +- `july-iteration-test-release-gate`: 定义测试环境发布豁免、审计冻结边界、部署与回滚顺序、状态真实性以及生产发布前必须恢复的延期门禁。 + +### Modified Capabilities + +无。本 Change 不直接改写 `openspec/specs/` 中现有能力规格;七月业务行为以标准评审稿和各冻结 PRD 为来源,由上述三个总控能力约束统一实施与发布。 + +## Impact + +- **规划与权威关系**:后续七月迭代只从本 Change 的 `tasks.md` 领取剩余工作;原 `.scratch` PRD/Tickets 保留溯源和业务细节,不废弃、不另行扩展。冲突时依次以用户本次确认、七月标准评审稿、冻结 PRD、既有 Ticket 为准。 +- **后端**:后续实施将触及资产、套餐、钱包、订单、退款、充值、企微、通知、导出、Gateway、运营商回调、异步任务、系统配置及相关迁移、API/Worker 组合根;本次提案本身不修改这些业务代码。 +- **前端**:涉及后台管理端、代理端和 C 端 H5/公众号的页面、状态、上传、轮询、审批、支付、导出和人工验收契约;当前仓库无前端源码,只交付框架无关契约与联调清单。 +- **外部系统**:企业微信、微信支付、支付宝、Gateway、运营商回调、对象存储、PostgreSQL、Redis/Asynq;本测试环境里程碑仅完成装配与人工验收准备,真实外部验收延期。 +- **性能与安全**:继续要求 API P95 < 200ms、P99 < 500ms、数据库查询 < 50ms,列表分页、批量查询避免 N+1;Access Log 脱敏继续生效,敏感配置和底层错误不得对外泄露。 +- **文档**:后续每个纵向切片仍需同步中文功能文档、README 索引、OpenAPI 文档生成器及跨仓前端契约;本 Change 作为七月迭代唯一总台账和剩余实施入口。 diff --git a/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-delivery-contract/spec.md b/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-delivery-contract/spec.md new file mode 100644 index 0000000..dca2daa --- /dev/null +++ b/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-delivery-contract/spec.md @@ -0,0 +1,74 @@ +## ADDED Requirements + +### Requirement: 每个未完成需求必须按纵向业务切片实施 +每个未完成需求 MUST 形成可独立交付的纵向任务或任务组,覆盖该切片所需的数据、Application/Domain/Query、Infrastructure、Handler/API、Worker、文档、前端契约和装配,不得按“先建表、再 Service、再 Handler”拆成相互不可验证的水平任务。每个任务 MUST 标注完整业务边界和明确不迁移的旧代码范围。 + +#### Scenario: 实施复杂资金需求 +- **WHEN** 任务涉及钱包、充值、退款、佣金、审批或并发状态机 +- **THEN** 同一纵向切片 MUST 收口相关不变量、事务、幂等、可靠事件、API/Worker 与异常恢复,不得把核心规则分散留在旧 Service 和新 Domain 两处 + +#### Scenario: 实施局部查询需求 +- **WHEN** 任务仅增加列表筛选、详情投影、统计或导出读取 +- **THEN** 任务 MUST 使用 Query 或保留现有简单读取结构,不得为形式完整创建聚合根或迁移未触碰写逻辑 + +### Requirement: 实施必须遵守触碰式 DDD 三通道 +复杂写 MUST 采用 `Handler → Application UseCase → Domain → Repository/Infrastructure`;简单写 MUST 采用 `Handler → Application 事务脚本 → Persistence`;读取 MUST 采用 `Handler → Query → GORM/DTO`。尚未触碰的旧用例 MAY 保持 `Handler → Service → Store → Model`,但不得借本期需求扩大全仓迁移。 + +#### Scenario: 选择架构通道 +- **WHEN** 实施人员领取任一未完成纵向任务 +- **THEN** 任务中的主/辅助通道 MUST 与其状态机、金额、并发、外部副作用或纯读取性质一致,并按任务声明限制迁移范围 + +### Requirement: API 必须使用项目统一契约 +所有新增或修改 API MUST 使用 Fiber v2、Validator、`pkg/response` 和 `{code,msg,data,timestamp}` 响应包络;不得使用 `{message}` 替代 `msg`。错误 MUST 在 `pkg/errors` 中定义或复用,Handler 参数校验失败统一返回 `CodeInvalidParam`,资源不存在与越权使用不泄露存在性的 `CodeForbidden` 语义,禁止向客户端拼接底层错误。 + +#### Scenario: 参数校验失败 +- **WHEN** 调用方提交格式或范围无效的请求 +- **THEN** API MUST 返回统一包络与 `CodeInvalidParam`,日志可记录详细原因但响应不得暴露 Validator、GORM 或外部 SDK 错误 + +#### Scenario: 新增 Handler +- **WHEN** 某纵向任务新增 Handler 或路由 +- **THEN** 实施 MUST 同步真实路由、HTTP 方法注释、`cmd/api/docs.go` 和 `cmd/gendocs/main.go` 的文档生成器装配 + +### Requirement: 查询必须保持数据权限、分页和性能边界 +所有列表、详情、附件、导出和异步任务查询 MUST 以后端用户类型、店铺层级、企业范围与业务权限执行数据过滤;前端隐藏按钮不得作为授权边界。列表 MUST 默认分页 20、最大 100,并采用批量查询避免 N+1;目标性能仍为 API P95 < 200ms、P99 < 500ms、数据库查询 < 50ms。 + +#### Scenario: 越权访问资源 +- **WHEN** 用户请求不在其店铺、企业或业务权限范围内的资源 +- **THEN** 后端 MUST 拒绝访问且不得区分资源不存在与无权限,也不得通过通知跳转、附件引用或历史导出绕过当前权限 + +#### Scenario: 查询本页审批摘要 +- **WHEN** 列表需要同时展示提交人、审批摘要或关联资源 +- **THEN** Query MUST 按本页 ID 批量投影,不得逐行访问数据库或外部系统 + +### Requirement: 数据与常量必须遵守项目基础约束 +持久化 MUST 使用 GORM 与 PostgreSQL,不得直接使用 `database/sql`;表关联 MUST 通过 ID 显式维护,不得建立外键约束或 GORM 关联标签。常量 MUST 定义在 `pkg/constants` 并使用中文注释;Redis Key MUST 由 `Redis{Module}{Purpose}Key(params...)` 函数生成。状态类字段 MUST 使用 `int`,类型/方式类字段 MUST 使用 `string`,响应状态 MUST 提供对应中文名称字段。 + +#### Scenario: 新增迁移与状态字段 +- **WHEN** 纵向任务需要新表、索引或状态字段 +- **THEN** 迁移 MUST 增量、无外键、可按停机顺序执行,DTO 枚举说明 MUST 从常量原文同步且状态响应包含中文名称 + +### Requirement: 业务可靠性设施必须保持完整 +涉及跨事务副作用或外部系统的用例 MUST 保留事务、幂等、Outbox、Asynq 至少一次投递、Integration Log 和外部调用恢复能力。关键事件 MUST 与业务事实同事务写入 Outbox;消费者 MUST 使用状态条件、唯一业务键、处理租约或乐观锁保证幂等;`EnqueueTask` 载荷 MUST 传 struct 或 map,不得传预序列化 `[]byte`。 + +#### Scenario: 外部调用结果未知 +- **WHEN** 企微、支付、Gateway 或其他具有副作用的请求已经发出但结果未知 +- **THEN** 系统 MUST 保存可恢复的 Integration Log 和业务状态,不得伪装为明确失败后盲目重试或重复资金动作 + +#### Scenario: 可靠事件投递失败 +- **WHEN** Asynq 暂时不可用但业务事务与 Outbox 已提交 +- **THEN** 业务事实 MUST 保留,由 Relay/Worker 后续重试;不得删除 Outbox 或改用裸 goroutine + +### Requirement: 前后端契约必须随纵向切片共同冻结 +每条涉及页面或跨仓交互的任务 MUST 定义端别、页面入口、字段、枚举、金额/时间口径、权限、加载/空态/失败/重试/部分成功状态、轮询或刷新策略和人工验收点。当前仓库不含前端源码时 MUST 交付框架无关契约,不得虚构前端目录、组件库或状态管理方案。 + +#### Scenario: 后端完成但前端未实现 +- **WHEN** 后端 API 和字段已交付而前端仓库尚未完成页面 +- **THEN** 后端子项 MAY 标记完成,但前端状态、联调状态和发布状态 MUST 保持待完成 + +### Requirement: 冻结 PRD 的异常闭环必须保留 +资金、审批、异步批量、支付、Gateway 与运营商回调的正常、拒绝、失败、重复、并发、结果未知、迟到回调、部分成功和人工恢复规则 MUST 继续采用标准评审稿和对应冻结 PRD 的完整定义。本总 Change 不得以“快速测试环境交付”为由删除 Integration Log、Domain Ledger、Outbox、幂等、事务或补偿边界。 + +#### Scenario: 快速交付遇到复杂异常分支 +- **WHEN** 某异常分支实现成本高但已被冻结 PRD 定义为资金或外部调用安全边界 +- **THEN** 该分支 MUST 留在本轮业务实现范围,不能与自动化测试和 Audit Event 一起延期 + diff --git a/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-master-ledger/spec.md b/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-master-ledger/spec.md new file mode 100644 index 0000000..193d8b4 --- /dev/null +++ b/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-master-ledger/spec.md @@ -0,0 +1,52 @@ +## ADDED Requirements + +### Requirement: 七月迭代必须维护唯一的 28 线总台账 +系统规划 SHALL 以本 Change 的 `tasks.md` 作为七月迭代唯一需求总台账和剩余实施入口,并使用以下稳定编号且不得增删范围:`JULY-TECH-FOUNDATION`、`JULY-TECH-NOTIFICATION`、`JULY-UR33`、`JULY-UR34`、`JULY-UR35`、`JULY-UR36`、`JULY-UR37`、`JULY-UR38`、`JULY-UR40`、`JULY-UR42`、`JULY-UR43`、`JULY-UR44`、`JULY-UR45`、`JULY-UR46`、`JULY-UR47`、`JULY-UR48`、`JULY-UR49`、`JULY-UR53`、`JULY-UR55`、`JULY-UR57`、`JULY-UR60`、`JULY-UR62`、`JULY-UR73`、`JULY-UR86`、`JULY-UR94`、`JULY-UR96`、`JULY-UR97`、`JULY-UR98`。 + +#### Scenario: 核对总台账范围 +- **WHEN** 发布负责人统计本 Change 的七月技术/业务线 +- **THEN** 总数 MUST 恰为 28,且每个稳定编号恰好出现一次 + +### Requirement: 每条线必须保留来源与多维状态 +每条需求线 MUST 记录来源 PRD、既有 Ticket 或“由 PRD 直接转换”的任务来源、主架构通道、辅助通道、具体依赖、完整业务边界、明确不迁移范围、后端状态、前端状态、验证状态和发布状态。状态值 MUST 能区分“已完成”“后端代码完成、待前端/人工验收”“未开始”“代码完成、验证延期”,并允许记录元数据待收口,不得用单一完成布尔值覆盖多维事实。 + +#### Scenario: 代码存在但人工验收未完成 +- **WHEN** 某需求的后端代码与文档已经存在,但前端或人工验收尚未完成 +- **THEN** 后端状态 MUST 可标记完成,前端、验证和发布状态 MUST 保持未完成或延期 + +#### Scenario: 只有冻结 PRD +- **WHEN** 某需求只有已评审 PRD 而没有既有 Ticket +- **THEN** 总台账 MUST 直接建立纵向实施任务并引用该 PRD,不得额外创建 `.scratch/issues` + +### Requirement: 初始完成状态必须与仓库证据一致 +总台账初始状态 SHALL 认定:`JULY-TECH-FOUNDATION` 与 `JULY-UR55` 已完成;`JULY-UR45` 为后端完成但原 Ticket 元数据待收口;`JULY-UR46`、`JULY-UR60`、`JULY-UR86` 为后端完成但前端和/或人工验收未完成;其余 22 条线为未开始。任何预勾选 MUST 仅覆盖已有证据证明完成的子项。 + +#### Scenario: 预勾选已完成任务 +- **WHEN** 维护者打开初始 `tasks.md` +- **THEN** 已完成后端子项按上述证据预先勾选,未完成的前端、人工验收、延期验证和发布子项 MUST 保持未勾选 + +#### Scenario: 元数据与代码状态冲突 +- **WHEN** 原 Ticket 仍显示 `ready-for-agent` 但代码与提交证据证明后端已落地 +- **THEN** 总台账 MUST 记录“后端完成、元数据待收口”,不得回退代码状态或伪称全链路验收完成 + +### Requirement: 依赖必须引用稳定任务编号 +所有跨需求和同需求依赖 MUST 引用本 Change 中具体、稳定、可判定完成的任务编号。任务不得仅写“依赖公共能力”“依赖审计”或其他无法判断完成状态的模糊阻塞项;原 Ticket 的不存在路径、占位依赖或标题漂移 MUST 在总台账中改为有效任务编号。 + +#### Scenario: 迁移旧依赖 +- **WHEN** 原 Ticket 引用不存在文件、尚未拆票占位符或已暂缓的审计门禁 +- **THEN** 总台账 MUST 将其映射为有效的本 Change 任务编号,或删除已获授权取消的阻塞关系并记录原因 + +### Requirement: 权威来源必须有明确优先级 +业务行为 SHALL 以已评审七月标准稿和冻结 PRD 为来源,不得由本 Change 擅自重写。发生冲突时 MUST 按“用户本次明确决策 → 七月标准评审稿 → 对应冻结 PRD → 既有 Ticket → 代码现状”的顺序裁决;代码和提交记录仅用于校准完成状态,不得反向修改冻结业务规则。 + +#### Scenario: PRD 与标准稿冲突 +- **WHEN** 某 PRD 或 Ticket 的约束与七月标准评审稿不一致 +- **THEN** 总 Change MUST 采用标准评审稿并在任务中保留来源说明 + +### Requirement: 需求16必须持续排除 +需求16(代理分销码与佣金提现)MUST 保持移出本期。任何任务、依赖、迁移、领域目录、表、API、前端页面或验收清单均不得把该需求重新加入七月测试环境里程碑;店铺业务员仅表示业务归属和通知接收,不得推导分销或佣金关系。 + +#### Scenario: 审查七月范围 +- **WHEN** 实施或评审人员搜索需求16、distribution、分销码、代理申请或佣金提现 +- **THEN** 只能看到排除说明,不得出现可实施任务或发布依赖 + diff --git a/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-test-release-gate/spec.md b/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-test-release-gate/spec.md new file mode 100644 index 0000000..b095104 --- /dev/null +++ b/openspec/changes/complete-july-iteration-test-release/specs/july-iteration-test-release-gate/spec.md @@ -0,0 +1,63 @@ +## ADDED Requirements + +### Requirement: 本里程碑仅面向测试环境部署 +本 Change 的近期发布目标 SHALL 是在 2026-07-27 前部署到测试环境,不得将其描述为正式生产验收或七月迭代全链路完成。测试环境发布状态 MUST 与生产发布状态分开记录。 + +#### Scenario: 测试环境部署完成 +- **WHEN** 数据库迁移、API、Worker、前端和配置已按本 Change 装配到测试环境 +- **THEN** 发布状态 MAY 标记为“测试环境已部署”,但生产发布、真实外部验收和延期门禁 MUST 保持未完成 + +### Requirement: 自动化测试豁免仅限本次测试环境里程碑 +本轮实施 MUST 不新增 `_test.go`、不运行 `go test`,也不执行真实 PostgreSQL、Redis、企微、支付或 Gateway 自动验收。每批实现仅要求执行 `gofmt`、必要代码生成、`go build ./...` 和部署检查。自动化测试、真实外部验收和生产发布门禁 MUST 登记为延期项,未执行验证不得标记通过。 + +#### Scenario: 完成一批业务代码 +- **WHEN** 某实施批次完成代码修改 +- **THEN** 执行者 MUST 运行该批约定的格式化、必要生成、`go build ./...` 与部署检查,不得新增或运行自动化测试 + +#### Scenario: 未执行测试 +- **WHEN** 任务因本次豁免没有自动化或真实外部验证证据 +- **THEN** 验证状态 MUST 标记“代码完成、验证延期”或“待前端/人工验收”,不得标记“验收完成” + +### Requirement: Audit Event 专项不得阻塞测试环境里程碑 +`.scratch/tech-global-audit/issues/01`、`19`、`20`、`21` 及其他 Audit Event 写入、审计中心、历史投影、敏感读取、导出、保留清理和一次性审计切换任务 MUST 不进入本轮实现任务,也不得作为其他七月需求的测试环境阻塞项。提交 `ff44305` 已存在的审计代码 MUST 原样冻结,不删除、不回滚、不继续扩展。 + +#### Scenario: 下游原 Ticket 依赖全局审计 +- **WHEN** 某七月 PRD/Ticket 原先把 Audit Event 或一次性审计发布门禁列为 blocker +- **THEN** 本 Change MUST 移除该测试环境阻塞边,同时保留其生产发布前恢复义务 + +#### Scenario: 审计冻结代码存在 +- **WHEN** 构建包含 `integrationlog.Repository`、`cmd/audit-coverage`、`pkg/sanitizer` 或迁移 `000167_create_audit_integration_log` +- **THEN** 不得为冻结目的删除这些代码;未装配到生产组合根的审计组件不得被本轮业务主动启用 + +### Requirement: 可靠性日志与 Audit Event 必须保持边界清晰 +Access Log SHALL 继续负责 HTTP 调试并使用现有递归脱敏;Integration Log SHALL 记录外部交互及结果未知恢复事实;Domain Ledger SHALL 继续作为金额、订单、退款、充值、审批和状态的业务权威;Outbox SHALL 继续作为可靠副作用投递事实。Audit Event 仅作为“谁对什么做了什么”的治理能力暂缓,其他三类事实不得被停用或合并。 + +#### Scenario: 新业务调用外部系统 +- **WHEN** 本轮新业务调用企微、支付、Gateway 或接收运营商回调 +- **THEN** 仍 MUST 写 Integration Log 并保留幂等、事务与恢复语义,即使本次不写 Audit Event + +#### Scenario: Access Log 处理敏感正文 +- **WHEN** 登录、Token、支付、企微、运营商回调或文件路由产生请求响应日志 +- **THEN** 现有 Sanitizer 与安全摘要策略 MUST 继续生效,不得因审计冻结恢复原文记录 + +### Requirement: 测试环境发布必须按停机依赖顺序执行 +测试环境发布 MUST 按“确认变更与配置 → 停止相关写入和 Worker → 执行增量迁移 → 发布 API 与 Relay/Worker → 发布前端 → 装配企微/支付/Gateway/运营商/对象存储配置 → 执行部署检查 → 恢复 Worker 与访问”的顺序。涉及旧接口停用和新契约同批切换的需求 MUST 在解除访问前完成版本一致性检查。 + +#### Scenario: 部署检查失败 +- **WHEN** 迁移、构建、配置、路由、Worker 注册或前后端版本一致性检查失败 +- **THEN** 测试环境 MUST 保持维护或停止新入口,不得将该批标记部署完成 + +### Requirement: 回滚必须保留不可逆业务事实 +开放访问前失败 MAY 回滚应用和可逆迁移;一旦产生审批、支付、资金流水、订单、退款、充值、Outbox、Integration Log、通知或部分成功批量任务,回滚 MUST 保留这些事实,暂停异常生产者并采用前向修复。不得通过清表、恢复旧 Writer 或要求用户重复支付来回滚。 + +#### Scenario: 支付成功但钱包尚未入账 +- **WHEN** 测试环境回滚时存在已支付未入账充值 +- **THEN** 系统 MUST 保留支付与 Outbox/恢复事实,并在恢复后幂等完成入账,不得关闭原事实或要求重新支付 + +### Requirement: 生产发布不得继承测试豁免 +生产发布前 MUST 恢复并完成自动化测试、真实 PostgreSQL/Redis/企微/支付/Gateway 验收、前后端联调、历史数据抽样与迁移演练、性能/权限/安全检查,以及 Audit Event 专项的重新评审、写入覆盖和发布门禁。延期项 MUST 保持未勾选,直至产生真实证据;不得把本测试环境豁免升级为永久 N/A。 + +#### Scenario: 准备生产发布 +- **WHEN** 团队从测试环境里程碑推进正式生产 +- **THEN** 发布负责人 MUST 重新启用延期验证与治理清单,全部完成前不得声明生产验收通过 + diff --git a/openspec/changes/complete-july-iteration-test-release/tasks.md b/openspec/changes/complete-july-iteration-test-release/tasks.md new file mode 100644 index 0000000..0166ddd --- /dev/null +++ b/openspec/changes/complete-july-iteration-test-release/tasks.md @@ -0,0 +1,243 @@ +## 0. 七月迭代 28 线唯一总台账 + +状态口径:每条线同时记录“后端 / 前端 / 验证 / 发布”。`[x]` 只表示该行声明的范围已有仓库证据;`[ ]` 表示仍有实施、前端、人工、延期验证或发布工作。后续七月工作只从本文件领取,不再从分散 `.scratch` 目录直接启动。 + +- [x] 0.1 `JULY-TECH-FOUNDATION` TECH 七月公共开发基础|来源 `.scratch/tech-public-foundation/`|状态:已完成(PRD `completed`,12/12 Tickets 完成)|主通道 Infrastructure,辅助 Application/Query|发布:本仓公共基础已交付。 +- [ ] 0.2 `JULY-TECH-NOTIFICATION` TECH 公共站内通知|来源 `.scratch/tech-inapp-notifications/`(8 Tickets)|状态:未开始|主通道简单写 Application,辅助 Query/Infrastructure|依赖:0.1。 +- [ ] 0.3 `JULY-UR33` 套餐临期查询、Dashboard 与提醒|来源 `.scratch/ur33-package-expiry-reminder/PRD.md`(由 PRD 直接转任务)|状态:未开始|主通道 Query,辅助 Application/Infrastructure|依赖:0.2、0.9、0.14、0.26。 +- [ ] 0.4 `JULY-UR34` 代理在线扫码充值与平台线下代充值|来源 `.scratch/ur34-agent-recharge/PRD.md`|状态:未开始|主通道复杂写,辅助 Query/Payment/WeCom Adapter|依赖:0.2、0.7、0.8。 +- [ ] 0.5 `JULY-UR35` 退款企微审批与整单终结|来源 `.scratch/ur35-refund-wecom-approval/PRD.md`|状态:未开始|主通道复杂写,辅助 Query/WeCom Adapter|依赖:0.2、0.7、0.8。 +- [ ] 0.6 `JULY-UR36` 批量订购套餐|来源 `.scratch/ur36-bulk-package-purchase/`(11 Tickets)|状态:未开始|主通道 Application/Domain,辅助 Query/Infrastructure|依赖:0.8、0.9。 +- [ ] 0.7 `JULY-UR37` 企业微信审批公共能力|来源 `.scratch/ur37-wecom-approval-foundation/`(14 Tickets)|状态:未开始|主通道复杂写,辅助 Query/Infrastructure|依赖:0.1;首个退款组合依赖 0.5。 +- [ ] 0.8 `JULY-UR38` 代理主钱包信用额度|来源 `.scratch/ur38-agent-main-wallet-credit/`(10 Tickets)|状态:未开始|主通道复杂写,辅助简单写/Query|依赖:0.1。 +- [ ] 0.9 `JULY-UR40` 下架套餐历史用户续费|来源 `.scratch/ur40-off-shelf-package-renewal/`(8 Tickets)|状态:未开始|主通道 Domain Policy,辅助 Query|依赖:0.1。 +- [ ] 0.10 `JULY-UR42` 统一导出与字段权限|来源 `.scratch/ur42-unified-export-field-permissions/PRD.md`|状态:未开始|主通道 Query/DataSource,辅助简单写 Application|依赖:0.3、0.4、0.5、0.12、0.14。 +- [ ] 0.11 `JULY-UR43` 系列套餐批量授权|来源 `.scratch/ur43-series-package-bulk-authorization/`(3 Tickets)|状态:未开始|主通道复杂写,辅助 Query|依赖:0.1。 +- [ ] 0.12 `JULY-UR44` 列表提交人与审批摘要|来源 `.scratch/ur44-list-submitter-approval-summary/PRD.md`|状态:未开始|主通道 Query,辅助简单写/迁移|依赖:0.4、0.5、0.7。 +- [ ] 0.13 `JULY-UR45` 换货快照与新旧独立搜索|来源 `.scratch/ur45-exchange-asset-search/`(2 Tickets)|状态:后端完成、Ticket 元数据待收口;前端/人工待确认|主通道复杂写 + Query。 +- [ ] 0.14 `JULY-UR46` 预计最终到期时间|来源 `.scratch/ur46-estimated-final-expiry/`(4 Tickets)|状态:后端完成、前端/人工未完成|主通道 Query|依赖 0.19 已满足。 +- [ ] 0.15 `JULY-UR47` 卡片手动限速|来源 `.scratch/ur47-manual-card-speed-limit/`(4 Tickets)|状态:未开始|主通道 Application + Port/Adapter,辅助 Infrastructure|依赖:0.1。 +- [ ] 0.16 `JULY-UR48` 按资产类型限制支付方式|来源 `.scratch/ur48-asset-payment-methods/`(5 Tickets)|状态:未开始|主通道简单写 + 复杂写,辅助 Query|依赖:0.1。 +- [ ] 0.17 `JULY-UR49` 设备 CSV 批量分配|来源 `.scratch/ur49-device-batch-allocation-csv/`(5 Tickets)|状态:未开始|主通道 Application,辅助 Infrastructure/Query|依赖:0.6 的受控上传边界。 +- [ ] 0.18 `JULY-UR53` 卡和设备实名状态筛选|来源 `.scratch/ur53-asset-realname-filter/PRD.md`|状态:未开始|主通道 Query,辅助投影 Application/Infrastructure|依赖:0.25。 +- [x] 0.19 `JULY-UR55` 套餐生效条件覆盖与购买快照|来源 `.scratch/ur55-package-expiry-base/`|状态:5/5 Tickets 已完成;PRD 顶层状态滞后不影响代码完成证据|主通道简单写 + 复杂写。 +- [ ] 0.20 `JULY-UR57` 活跃退款资产禁止换货|来源 `.scratch/ur57-block-exchange-active-refund/PRD.md`|状态:未开始|主通道复杂写,辅助批量 Query|依赖:0.5。 +- [ ] 0.21 `JULY-UR60` 店铺联系电话精确查询|来源 `.scratch/ur60-shop-phone-search/`(3 Tickets)|状态:后端完成、前端联调/人工验收未完成|主通道旧架构简单 Query。 +- [ ] 0.22 `JULY-UR62` H5 购买与实名顺序配置|来源 `.scratch/ur62-h5-realname-order/PRD.md`|状态:未开始|主通道 Domain/Application,辅助简单写/Query|依赖:0.25。 +- [ ] 0.23 `JULY-UR73` 按运营商实名能力控制复机|来源 `.scratch/ur73-resume-realname-policy/PRD.md`|状态:未开始|主通道复杂写,辅助 Gateway/Outbox|依赖:0.25。 +- [ ] 0.24 `JULY-UR86` 资产前代/后代换货链|来源 `.scratch/ur86-asset-exchange-trace/`(2 Tickets)|状态:后端完成、前端验收与历史抽样未完成|主通道 Query。 +- [ ] 0.25 `JULY-UR94` 卡状态公共写入与运营商回调|来源 `.scratch/ur94-card-state-events-callbacks/`(13 Tickets)|状态:未开始|主通道复杂写,辅助 Adapter/Query|依赖:0.1。 +- [ ] 0.26 `JULY-UR96` 店铺业务员归属|来源 `.scratch/ur96-shop-business-owner/`(6 Tickets)|状态:未开始|主通道简单写,辅助 Query/Port|依赖:0.1。 +- [ ] 0.27 `JULY-UR97` 钱包低余额预警|来源 `.scratch/ur97-wallet-low-balance-alert/PRD.md`|状态:未开始|主通道复杂写,辅助 Query/Outbox/Notification|依赖:0.2、0.8、0.26。 +- [ ] 0.28 `JULY-UR98` 换货新资产继承店铺|来源 `.scratch/ur98-exchange-inherit-shop/`(4 Tickets)|状态:未开始|主通道复杂写,辅助 Query/Infrastructure|依赖:0.1。 + +需求16保持排除:无对应复选框、实现任务、迁移或发布依赖;店铺业务员不得恢复分销或佣金语义。 + +## 1. 已完成后端证据与剩余元数据收口 + +- [x] 1.1 固化 TECH 公共基础完成证据:12 张 Ticket、Outbox/Relay、幂等、五态任务、受控配置、Access Log 安全能力、迁移与交接文档;明确它不等于通知、审计或业务消费者已完成。 +- [x] 1.2 固化 UR55 后端完成证据:创建/编辑覆盖值、同步购买快照、自动购包快照、激活与排队只消费快照共 5 张 Ticket;不重复实现后端。 +- [x] 1.3 固化 UR45 后端完成证据:统一换货资产快照和新旧资产独立搜索均已有代码/文档/提交;不回填历史快照、不顺带迁移 UR86/UR98。 +- [ ] 1.4 收口 UR45 原 PRD/Ticket 元数据并向前端交付新旧资产筛选契约;保持“后端完成、前端/人工待验收”,不得把元数据修正记为重新实现。 +- [x] 1.5 固化 UR46 四个后端 Query 切片完成证据:后台详情、卡列表、设备列表、C 端资产信息;不写汇总表、不重复计算第二套到期字段。 +- [x] 1.6 固化 UR60 后端完成证据:分页校验、联系电话 11 位精确过滤/索引、企业账号路由限制;保留前端与人工任务未完成。 +- [x] 1.7 固化 UR86 后端完成证据:前代和后代 Query、权限投影与索引;不新建换货关系表、不修改换货状态机。 +- [x] 1.8 冻结提交 `ff44305` 现有审计代码:保留 Integration Log 基础、离线 `cmd/audit-coverage`、Access Log 敏感字段判定复用和无外键迁移 `000167`;不装配 Audit Event、不继续开发审计中心,生产恢复见 6.5。 + +## 2. 第一批:共享核心与独立 frontier + +### B1-01 公共站内通知(`JULY-TECH-NOTIFICATION`) + +- [ ] 2.1 映射原通知 Ticket 01:交付后台明确接收账号的通知写入、`event_id + recipient` 幂等、未读查询与单条已读完整纵向切片。【主:简单写 Application;辅:Query/Infrastructure|边界:通知事实与当前账号读取|不迁移:业务触发规则、WebSocket|依赖:1.1】 +- [ ] 2.2 映射原 Ticket 02:交付后台通知筛选、分类汇总、稳定分页和全部/按分类已读。【主:Query;辅:简单写|边界:当前接收人数据|不迁移:业务列表|依赖:2.1】 +- [ ] 2.3 映射原 Ticket 03:交付个人客户通知投递、简化列表与已读 API。【主:简单写 + Query|边界:personal_customer 接收人|不迁移:后台权限模型|依赖:2.1】 +- [ ] 2.4 映射原 Ticket 04:交付店铺主账号、平台业务员及其他动态接收人的 Port/Adapter 解析。【主:Application + Port/Adapter|边界:只解析稳定接收人,不复制业务触发|不迁移:店铺层级|依赖:2.1、2.63】 +- [ ] 2.5 映射原 Ticket 05:交付受控 `ref_type/ref_id/ref_key` 目标解析、跳转白名单与跳转后二次权限校验。【主:Query|辅:Application|边界:通知目标解析|不迁移:任意 URL、业务权限实现|依赖:2.1】 +- [ ] 2.6 映射原 Ticket 06:交付通知保留、分批清理、失败可观测与安全日志。【主:Infrastructure|辅:Query|边界:通知记录生命周期|不迁移:Audit Event、外部消息渠道|依赖:2.1】 +- [ ] 2.7 映射原 Ticket 07:冻结后台与 C 端通知页面、30 秒轮询、铃铛/抽屉/中心、加载/空态/失败与受控跳转契约,并更新 OpenAPI/中文文档。【主:Query/API 契约|不迁移:前端框架选择|依赖:2.2、2.3、2.5】 +- [ ] 2.8 映射原 Ticket 08 为测试环境发布检查:完成通知 Handler/路由/文档生成器、Worker/模板注册与生产组合根装配;仅执行本批格式化、必要生成、构建和部署检查,自动化与正式发布门禁转 6.2/6.5。【主:Infrastructure|依赖:2.2-2.7】 + +### B1-02 企业微信审批公共能力(`JULY-UR37`) + +- [ ] 2.9 映射原 UR37-01:交付企微连接状态、Token 缓存/锁、安全 Viper 配置与 WeCom Adapter;所有外部尝试接入 Integration Log。【主:Infrastructure Adapter|不迁移:业务退款/充值|依赖:1.1】 +- [ ] 2.10 映射原 UR37-02:交付平台/超管五分钟扫码绑定会话、本人查询/解绑与超管强制解绑;代理不绑定。【主:复杂写 Application/Domain|辅:Query|边界:账号与 userid 一对一|不迁移:组织模型|依赖:2.9】 +- [ ] 2.11 映射原 UR37-03:交付稳定场景、不可变模板版本、控件映射校验与首次发布。【主:复杂写|辅:Adapter/Query|边界:模板版本事实|不迁移:本地审批节点|依赖:2.9】 +- [ ] 2.12 映射原 UR37-04:交付业务创建前置校验、真实提交人/企微发起身份快照、审批实例与业务单/Outbox 同事务 Port。【主:Application + Port|边界:公共审批创建事务|不迁移:业务金额规则|依赖:2.10、2.11】 +- [ ] 2.13 映射原 UR37-05:交付本地业务附件权威存储、企微副本上传、异步 `applyevent`、结果未知状态和 Integration Log。【主:Application/Infrastructure|边界:一次审批技术提交|不迁移:业务附件权限|依赖:2.12】 +- [ ] 2.14 映射原 UR37-06:交付场景暂停、提交租约、模板换版/指纹验证、原子恢复与失效告警。【主:复杂写|辅:Scheduled Job|边界:新提交开关,不中断存量实例|不迁移:业务终态|依赖:2.11、2.13】 +- [ ] 2.15 映射原 UR37-07:交付加密回调验签解密、权威 `getapprovaldetail` 同步、状态条件更新与首次终态 Outbox。【主:复杂写|辅:Adapter|边界:审批镜像状态|不迁移:终态业务处理|依赖:2.13】 +- [ ] 2.16 映射原 UR37-08:交付两分钟轮询补偿、回调/轮询共用同步用例、处理租约与终态事件幂等。【主:Application|辅:Worker|不迁移:退款/充值 Worker|依赖:2.15】 +- [ ] 2.17 映射原 UR37-09:交付审批运行列表/详情、业务摘要、权限主体投影和稳定分页,代理不得看到审批人/内部意见/附件。【主:Query|边界:公共审批读取|不迁移:业务列表|依赖:2.10、2.11、2.15】 +- [ ] 2.18 映射原 UR37-10:交付提交结果未知的“绑定已有 sp_no”和“确认未创建后重发”受控恢复,保留每次技术尝试与 Integration Log。【主:复杂写|辅:Adapter|不迁移:新业务审批申请|依赖:2.13、2.15、2.17】 +- [ ] 2.19 映射原 UR37-11:消费首次终态事件并向真实业务提交人发送审批结果通知,按实例/接收人防重。【主:Application|辅:Notification Adapter|不迁移:业务到账通知|依赖:2.8、2.16】 +- [ ] 2.20 映射原 UR37-12:交付存量审批迁移契约、`legacy` 只读投影、平台绑定/代理固定账号前置检查与异常清单。【主:Application/Infrastructure|辅:Query|不迁移:伪造历史企微实例|依赖:2.10-2.15】 +- [ ] 2.21 映射原 UR37-13:冻结企微配置页、个人绑定、审批运行/详情/恢复与业务摘要的跨仓契约,补 OpenAPI、文档生成器和中文文档。【主:API/Query 契约|不迁移:前端技术栈|依赖:2.10、2.11、2.17、2.18】 +- [ ] 2.22 完成 UR37 公共能力的测试环境装配:配置模板/回调/轮询 Worker、路由与组合根并执行构建/部署检查;原 UR37-14“退款首个真实企微门禁”整体转 6.2,不阻塞 B3 退款代码实现。【主:Infrastructure|依赖:2.9-2.21】 + +### B1-03 代理主钱包信用额度(`JULY-UR38`) + +- [ ] 2.23 映射原 UR38-01:扩展主钱包信用字段、CHECK/索引/版本与 Wallet Domain 不变量;迁移前核对现有约束和异常数据。【主:复杂写 Domain|辅:Infrastructure|不迁移:员工/佣金/资产钱包|依赖:1.1】 +- [ ] 2.24 映射原 UR38-02:交付客户角色“仅新建店铺使用”的默认信用模板、权限与 API/前端契约。【主:简单写 Application|辅:Query|不迁移:已有钱包追溯更新|依赖:2.23】 +- [ ] 2.25 映射原 UR38-03:新建店铺事务内原子复制默认角色信用快照到代理主钱包。【主:复杂写 Application|边界:店铺 + 钱包创建事务|不迁移:其他店铺创建规则|依赖:2.24】 +- [ ] 2.26 映射原 UR38-04:交付平台独立权限调整店铺实际额度、版本冲突、降低/关闭边界和变更前后投影。【主:复杂写 Domain|辅:Query|不迁移:代理自助调额|依赖:2.23】 +- [ ] 2.27 映射原 UR38-05:统一代理订单、代购和钱包支付扣款用例,使用有效信用、版本/锁、唯一流水和同事务事实。【主:复杂写 Domain|不迁移:无关订单创建|依赖:2.23】 +- [ ] 2.28 映射原 UR38-06:统一代理主钱包冻结/解冻,维持 `balance-frozen+credit>=0` 与幂等流水。【主:复杂写 Domain|不迁移:佣金冻结|依赖:2.23、2.27】 +- [ ] 2.29 映射原 UR38-07:统一充值入账与人工调整用例,按唯一业务号、版本和流水幂等;只提供 UR34 可复用能力。【主:复杂写 Domain|不迁移:支付/企微/通知|依赖:2.23】 +- [ ] 2.30 映射原 UR38-08:统一代理订单退款回充,仅按原扣款流水定位原主钱包并幂等回溯。【主:复杂写 Domain|不迁移:渠道退款/资产钱包退款|依赖:2.27、2.29】 +- [ ] 2.31 映射原 UR38-09:资金概况 Query 返回信用开关、额度、现金可用、总可用、欠款和版本,前端不得自行计算。【主:Query|不迁移:钱包写入|依赖:2.23、2.26】 +- [ ] 2.32 映射原 UR38-10 为测试环境停机切换:完成所有主钱包写入口接入、迁移/API/前端契约/组合根装配与本批构建部署检查;并发/真实资金验收转 6.1/6.3。【主:Infrastructure/Application 收口|依赖:2.24-2.31】 + +### B1-04 卡状态公共写入与运营商回调(`JULY-UR94`) + +- [ ] 2.33 映射原 UR94-01:扫描 19 位 ICCID 冲突并交付未删除范围部分唯一索引与发布前异常清单。【主:Infrastructure|不迁移:ICCID 归一化|依赖:1.1】 +- [ ] 2.34 映射原 UR94-02:交付实名观测的唯一 `ApplyCardObservation` 写入闭环、锁/条件更新、领域事实与 Outbox。【主:复杂写 Domain/Application|不迁移:轮询调度|依赖:2.33】 +- [ ] 2.35 映射原 UR94-03:将流量观测收口到同一公共写入用例并保持已有周期/资格语义。【主:复杂写 Domain|不迁移:套餐轮询|依赖:2.34】 +- [ ] 2.36 映射原 UR94-04:将网络状态观测收口到同一用例并保持停复机业务边界。【主:复杂写 Domain|不迁移:复机资格(由 3.2 负责)|依赖:2.34】 +- [ ] 2.37 映射原 UR94-05:一次性切换三个现有轮询结果写入口到公共用例,保持 PostgreSQL 配置、Redis 分片、间隔、开关和失败重排不变。【主:Application/Infrastructure|不迁移:轮询调度|依赖:2.34-2.36】 +- [ ] 2.38 映射原 UR94-06:交付同场景可合并的立即/3/5 分钟观测序列、单次请求互斥、最小间隔与 Integration Log。【主:Application|辅:Asynq/Adapter|不迁移:自动退避状态|依赖:2.34-2.36】 +- [ ] 2.39 映射原 UR94-07:在查询资产、获取实名链接等成功边界接入观测序列,不新增显式同步 API。【主:Application Adapter|不迁移:读取 Query 业务|依赖:2.38】 +- [ ] 2.40 映射原 UR94-08:在停复机、购包和套餐激活成功边界接入观测序列,仅负责触发不复制业务资格。【主:Application Adapter|不迁移:UR73/套餐规则|依赖:2.38】 +- [ ] 2.41 映射原 UR94-09:在切卡、重启等设备控制成功边界接入观测序列并解析最终卡。【主:Application Adapter|不迁移:设备控制规则|依赖:2.38】 +- [ ] 2.42 映射原 UR94-10:交付电信实名回调 Translator、19/20 位精确路由、幂等入站 Integration Log 和成功应答。【主:Infrastructure Adapter|辅:Application|依赖:2.33、2.34、2.38】 +- [ ] 2.43 映射原 UR94-11:交付移动实名成功回调的对应防腐层与公共写入接入。【主:Infrastructure Adapter|依赖:2.33、2.34、2.38】 +- [ ] 2.44 映射原 UR94-12:交付联通解除实名回调的留痕与约定成功应答,不修改本地实名状态。【主:Infrastructure Adapter|边界:Integration Log only|依赖:2.33】 +- [ ] 2.45 映射原 UR94-13 为测试环境发布检查:装配回调 Handler/路由/文档生成器、观测 Worker、Gateway Adapter 与配置,执行格式化、必要生成、构建和部署检查;真实运营商/Gateway验证转 6.4。【主:Infrastructure|依赖:2.37-2.44】 + +### B1-05~B1-09 独立 frontier + +- [ ] 2.46 `JULY-UR43` 映射原 Ticket 01:首次系列授权在同一事务创建系列授权和至少一条套餐授权,复用现有套餐 Query,已授权项置灰。【主:复杂写;辅:Query|不迁移:授权模型/候选 API|依赖:1.1】 +- [ ] 2.47 `JULY-UR43` 映射原 Ticket 02:`operation_type=authorize|update_cost|remove` 三类原子命令,最多 100 项、同价幂等、异价冲突。【主:复杂写|不迁移:混合命令兼容|依赖:2.46】 +- [ ] 2.48 `JULY-UR43` 映射原 Ticket 03:交付首次/后续管理前端契约、三类价格语义、OpenAPI/文档生成器与同批切换部署检查。【主:API/Query 契约|依赖:2.46、2.47】 +- [ ] 2.49 `JULY-UR47` 映射原 Ticket 01:修复同一设备多当前卡并建立部分唯一约束,异常数据先入清单。【主:Infrastructure|不迁移:绑定历史|依赖:1.1】 +- [ ] 2.50 `JULY-UR47` 映射原 Ticket 02:交付语义化 `speed_level` 到账号/运营商渠道 `code` 的 Gateway Adapter、能力校验与 Integration Log。【主:Port/Adapter|不迁移:自动限速|依赖:2.49】 +- [ ] 2.51 `JULY-UR47` 映射原 Ticket 03:交付统一资产手动限速 API,设备解析当前卡,区分不限速与 0kbps,外部结果未知可恢复;Audit Event 延期到 6.5。【主:Application|辅:Adapter|不迁移:套餐限速|依赖:2.49、2.50】 +- [ ] 2.52 `JULY-UR47` 映射原 Ticket 04:交付卡/设备详情限速能力、固定档位、失败状态、OpenAPI/文档生成器与测试环境配置/构建检查;真实 Gateway 验收转 6.4。【主:Query/API 契约|依赖:2.49-2.51】 +- [ ] 2.53 `JULY-UR48` 映射原 Ticket 01:复用受控系统配置读取/更新,向资产展示允许支付方式并提供安全默认值。【主:简单写 + Query|不迁移:通用配置中心|依赖:1.1】 +- [ ] 2.54 `JULY-UR48` 映射原 Ticket 02:限制普通资产钱包充值为资产允许集合与微信/支付宝交集,钱包不得作为充值渠道。【主:复杂写 Policy|不迁移:C 端全部充值|依赖:2.53】 +- [ ] 2.55 `JULY-UR48` 映射原 Ticket 03:订单创建时必填并固化支付方式快照,强充按同一方式拉起且钱包不能给自身强充。【主:复杂写 Domain|不迁移:其他订单状态|依赖:2.53】 +- [ ] 2.56 `JULY-UR48` 映射原 Ticket 04:支付时只执行订单快照方式并按最新资产配置二次校验,需要换方式时取消旧单重建。【主:复杂写 Domain|不迁移:支付方式替换接口|依赖:2.53、2.55】 +- [ ] 2.57 `JULY-UR48` 映射原 Ticket 05:交付后台配置、C 端支付页/强充/取消重建契约、OpenAPI/文档生成器与测试环境构建部署检查;真实支付验证转 6.3。【主:API/前端契约|依赖:2.54-2.56】 +- [ ] 2.58 `JULY-UR96` 映射原 Ticket 01:为店铺增加 nullable 平台业务员字段、索引与启用平台账号约束,不回填历史。【主:Infrastructure|不迁移:店铺层级/分销|依赖:1.1】 +- [ ] 2.59 `JULY-UR96` 映射原 Ticket 02:平台创建店铺时显式设置或按规则继承业务员,并在同一用例保存快照。【主:简单写 Application|不迁移:信用模板(由 UR38)|依赖:2.58】 +- [ ] 2.60 `JULY-UR96` 映射原 Ticket 03:代理创建直属下级店铺时安全继承当前业务员,不允许代理指定其他平台账号。【主:简单写|不迁移:店铺权限|依赖:2.59】 +- [ ] 2.61 `JULY-UR96` 映射原 Ticket 04:交付业务员编辑权限、停用/删除后的历史保留和重绑;Audit Event 延期 6.5。【主:简单写|不迁移:账号生命周期|依赖:2.58】 +- [ ] 2.62 `JULY-UR96` 映射原 Ticket 05:店铺创建/编辑/列表/详情/筛选返回业务员投影、候选账号与手机号摘要。【主:Query|不迁移:数据范围|依赖:2.58】 +- [ ] 2.63 `JULY-UR96` 映射原 Ticket 06:交付主账号与可用业务员接收人解析 Port、OpenAPI/前端契约与测试环境构建部署检查。【主:Port/Adapter + Query|不迁移:通知触发规则|依赖:2.59-2.62】 +- [ ] 2.64 `JULY-UR98` 映射原 Ticket 01:建立换货分配记录与目标资产归属校正基础,目标已属其他店铺时拒绝。【主:Infrastructure/Domain|不迁移:历史回填|依赖:1.1】 +- [ ] 2.65 `JULY-UR98` 映射原 Ticket 02:换货完成事务内让新资产继承旧店铺并保留旧资产归属,钱包/套餐迁移仍只受 `migrate_data` 控制。【主:复杂写 Domain/Application|不迁移:整个换货模块|依赖:2.64】 +- [ ] 2.66 `JULY-UR98` 映射原 Ticket 03:创建/发货/完成接口投影继承店铺和只读展示信息,禁止前端提交目标店铺。【主:Query/API 契约|依赖:2.65】 +- [ ] 2.67 `JULY-UR98` 映射原 Ticket 04:交付前端展示、迁移/路由/文档生成器、测试环境构建与部署检查;人工换货链验证转 5.5/6.6。【主:Infrastructure/API 契约|依赖:2.65、2.66】 +- [ ] 2.68 第一批批次检查:对本批修改执行 `gofmt`、必要代码生成、`go build ./...`,核对迁移所有权、Handler 文档生成器、API/Worker/Relay 组合根和配置样例;不新增/运行测试。 + +## 3. 第二批:共享核心下游 + +### B2-01 UR40 统一套餐可售策略 + +- [ ] 3.1 映射原 UR40-01:建立统一套餐可售决策与真实历史资格,禁用永不可买、下架仅资产所有人凭有效历史续费。【主:Domain Policy|不迁移:订单全模块|依赖:1.1】 +- [ ] 3.2 映射原 UR40-02:正常套餐商城 Query 只展示在售可购项。【主:Query|不迁移:购买写入|依赖:3.1】 +- [ ] 3.3 映射原 UR40-03:当前套餐投影提供 `renew_only` 续费入口与原因。【主:Query|依赖:3.1】 +- [ ] 3.4 映射原 UR40-04:历史套餐投影按真实使用资格提供续费入口。【主:Query|依赖:3.1】 +- [ ] 3.5 映射原 UR40-05:C 端订单创建重新校验续费资格、资产所有权和套餐状态。【主:复杂写 Domain/Application|依赖:3.1】 +- [ ] 3.6 映射原 UR40-06:后台代购、自动购包等非个人入口统一禁止下架套餐绕过。【主:复杂写 Policy 接入|不迁移:入口其他规则|依赖:3.1】 +- [ ] 3.7 映射原 UR40-08:交付跨入口 API/前端契约、OpenAPI/文档生成器与构建部署检查;原 Ticket 07 Audit Event 迁入 6.5,不在本轮实现。【主:API/发布契约|依赖:3.2-3.6】 + +### B2-02~B2-05 卡状态与钱包下游 + +- [ ] 3.8 `JULY-UR73` 统一所有后台/OpenAPI 复机入口的资格用例:`realname_link_type=none` 不要求实名,`template/gateway` 必须已实名,未知配置拒绝且不调用 Gateway。【主:复杂写 Domain/Application|不迁移:其他风险/套餐/保护期规则|依赖:2.45】 +- [ ] 3.9 `JULY-UR73` 复机成功后写 Integration Log、可靠触发 0/3/5 观测并由公共卡状态收敛;Gateway 成功不直接改本地网络状态。【主:Application + Adapter/Outbox|不迁移:观测实现|依赖:3.8、2.38】 +- [ ] 3.10 `JULY-UR73` 交付复机失败中文错误、API/前端契约、OpenAPI/文档生成器与构建部署检查;真实 Gateway 验收转 6.4。【主:API 契约|依赖:3.8、3.9】 +- [ ] 3.11 `JULY-UR53` 建立设备实名可重建投影、历史初始化和卡实名/绑定/解绑/换卡事件消费者;任一有效绑定卡实名即设备实名。【主:Application 投影|辅:Outbox/Infrastructure|不迁移:卡实名真相|依赖:2.34】 +- [ ] 3.12 `JULY-UR53` 为卡/设备列表增加可区分未传与显式 0 的实名状态过滤、字段与索引,保持权限/分页。【主:Query|依赖:3.11】 +- [ ] 3.13 `JULY-UR53` 交付前端筛选、OpenAPI/文档生成器、投影 Worker 装配和构建部署检查;历史/事件真实验证转 6.1。【主:API/Infrastructure|依赖:3.11、3.12】 +- [ ] 3.14 `JULY-UR62` 建立“运营商能力 + 资产视角 + realname_policy”的统一有效策略与购买/实名资格用例;设备 before-order 要求全部有效卡实名。【主:Domain/Application|不迁移:运营商配置协议|依赖:2.45】 +- [ ] 3.15 `JULY-UR62` 交付卡/设备 1~500 条批量策略更新,全量校验后事务内全成全败,并扫描冲突数据。【主:简单写 Application|不迁移:新字段|依赖:3.14】 +- [ ] 3.16 `JULY-UR62` 扩展 C 端 asset info 和所有充值/订单/实名入口只消费统一有效策略,交付前端流程、OpenAPI/文档生成器与构建部署检查。【主:Query + Application 接入|不迁移:前端自行推断|依赖:3.14、3.15】 +- [ ] 3.17 `JULY-UR97` 在所有代理主钱包写入口完成前后现金可用快照,只有 `before>10000 && after<=10000` 产生稳定低余额事件,持续低位不重复、回升后重布防。【主:复杂写 Wallet Domain|不迁移:信用/佣金/资产钱包|依赖:2.32】 +- [ ] 3.18 `JULY-UR97` 同事务保存钱包/流水/Outbox,消费事件并向店铺主账号和可用业务员按事件/接收人幂等通知。【主:Application + Outbox/Notification|不迁移:外部通知|依赖:2.8、2.63、3.17】 +- [ ] 3.19 `JULY-UR97` 扩展资金概况 `cash_available/low_balance_warning` 与前端提示,不提供阈值配置。【主:Query/API 契约|依赖:3.17】 +- [ ] 3.20 `JULY-UR97` 完成钱包入口接入清单、Worker/模板、OpenAPI/文档生成器和构建部署检查;并发/通知真实验证转 6.1/6.6。【主:Infrastructure 收口|依赖:3.17-3.19】 + +### B2-06 UR36 批量订购套餐 + +- [ ] 3.21 映射原 UR36-01:交付统一资产解析后的批次内唯一资产识别,跨不同标识仍按资产类型+ID 判重。【主:Application/Domain|不迁移:资产解析白名单|依赖:1.1】 +- [ ] 3.22 映射原 UR36-02:交付 `purpose=bulk_purchase` 受控预签名上传、对象归属/类型/10MB 校验和稳定 file_key。【主:Infrastructure/Application|不迁移:通用对象存储框架|依赖:1.1】 +- [ ] 3.23 映射原 UR36-04:复用 `3.1` 的统一后台套餐可售策略并按结算代理重新校验授权/成本价。【主:Domain Policy|依赖:3.1】 +- [ ] 3.24 映射原 UR36-05:提供可复用单资产套餐订购命令,订单、钱包/线下支付、流水和套餐使用保持一个业务单元。【主:复杂写 Domain/Application|不迁移:批次状态|依赖:2.27、3.23】 +- [ ] 3.25 映射原 UR36-06:幂等创建批量任务,固化请求指纹、套餐/支付/凭证/文件快照并可靠投递处理事件。【主:Application + Outbox|不迁移:同步解析 CSV|依赖:3.22】 +- [ ] 3.26 映射原 UR36-07:Worker 校验 UTF-8/BOM、固定表头/未知列/语法/空文件/1000 行,合法后持久化逐行明细,文件错误整体失败。【主:Infrastructure/Application|不迁移:逐行业务|依赖:3.21、3.25】 +- [ ] 3.27 映射原 UR36-08:按行号独立事务完成 offline 行订购,整批凭证快照、部分成功与失败明细可追踪。【主:复杂写|不迁移:财务核销|依赖:3.24、3.26】 +- [ ] 3.28 映射原 UR36-09:wallet 批次严格按行号逐行扣各资产结算代理主钱包,租约/幂等支持恢复且余额不足只失败当前行。【主:复杂写|不迁移:整批预占|依赖:2.27、3.27】 +- [ ] 3.29 映射原 UR36-10:交付任务/明细 Query、五态、计数摘要、失败详情、轮询与前端四阶段契约。【主:Query/API 契约|不迁移:创建人隔离新规则|依赖:3.28】 +- [ ] 3.30 映射原 UR36-11 为测试环境装配:完成迁移、上传/任务 Handler、Worker/Outbox、OpenAPI/文档生成器和构建部署检查;原 UR36-03 集成 Harness、真实依赖/全链门禁转 6.1/6.3。【主:Infrastructure|依赖:3.21-3.29】 + +### B2-07 UR49 设备 CSV 批量分配 + +- [ ] 3.31 映射原 UR49-01:基于 `3.22` 受控上传和公共五态建立设备批量任务/失败明细/租约基础,一任务只允许 `assign_shop` 或 `assign_series`。【主:Application/Infrastructure|不迁移:通用批量平台|依赖:3.22、3.30】 +- [ ] 3.32 映射原 UR49-02:交付 CSV 批量分配代理完整切片,批量查设备、平台库存/直属下级权限、已是目标幂等、其他店铺拒绝。【主:Application|不迁移:回收流程|依赖:3.31】 +- [ ] 3.33 映射原 UR49-03:交付 CSV 批量分配套餐系列完整切片,校验归属和有效授权,已是目标幂等且不修改 shop_id。【主:Application|不迁移:套餐授权模型|依赖:3.31】 +- [ ] 3.34 映射原 UR49-04:冻结前端双入口、上传/进度/失败明细契约,补 OpenAPI/文档生成器。【主:API/前端契约|依赖:3.32、3.33】 +- [ ] 3.35 映射原 UR49-05 为测试环境装配:完成迁移、Handler、Worker、路由、对象存储用途与构建部署检查;真实链路/自动化门禁转 6.1/6.3。【主:Infrastructure|依赖:3.31-3.34】 +- [ ] 3.36 第二批批次检查:执行 `gofmt`、必要代码生成、`go build ./...`,核对迁移、Handler 文档生成器、Worker/Outbox/Integration Log、配置和跨批依赖;不新增/运行测试。 + +## 4. 第三批:复杂业务与组合 Query + +### B3-01 UR34 代理充值 + +- [ ] 4.1 交付在线/线下充值共用的状态模型、幂等指纹、支付/审批/处理三套状态、迁移与 Query 投影。【主:复杂写 + Query|不迁移:C 端支付全模块|依赖:2.32】 +- [ ] 4.2 交付代理当前店铺可用支付方式与在线充值创建:100 元~100 万元、新 request_id 新业务单/支付单、微信 Native/支付宝 PreCreate、结果未知恢复和 qr_content 原样返回。【主:复杂写 + Payment Adapter|不迁移:二维码图片/多通道池|依赖:2.29、2.57】 +- [ ] 4.3 交付支付回调与受控查单共用确认用例:渠道/配置/金额/交易号/业务关联校验,迟到成功优先,支付事实与入账 Outbox 同事务。【主:复杂写|辅:Integration Log/Outbox|不迁移:前端轮询触发查单|依赖:4.2】 +- [ ] 4.4 交付钱包入账 Worker:唯一流水、版本、处理租约、状态恢复和目标主账号/真实提交人到账通知,支付已成功时失败不得回滚收款事实。【主:复杂写 Wallet Application|不迁移:人工重复入账|依赖:2.29、2.8、4.3】 +- [ ] 4.5 交付平台/超管线下代充值创建、1~5 付款凭证、固定金额与企微实例;审批通过入账、驳回终结、撤销分流,旧 offline-pay/reject 停机下线。【主:复杂写|辅:WeCom/Worker|不迁移:本地审批/操作密码|依赖:2.22、4.1、4.4】 +- [ ] 4.6 交付充值列表/详情/payment-status、代理店铺层级权限、前端二维码/轮询/审批/处理状态、OpenAPI/文档生成器和测试环境构建部署检查;真实支付/企微验收转 6.2/6.3。【主:Query/API 契约|依赖:4.2-4.5】 + +### B3-02 UR35 退款 + +- [ ] 4.7 交付退款固定申请金额、业务凭证、真实提交人、唯一企微实例与三套状态迁移;创建前校验无其他活跃退款。【主:复杂写|不迁移:本地审批/旧原单重提|依赖:2.22】 +- [ ] 4.8 交付退款创建纵向切片:后端读取实收金额、保存 1~5 本地凭证和审批快照、写提交 Outbox;删除 approve/reject/return/resubmit/manual-complete 路由。【主:复杂写 Application|不迁移:渠道自动退款|依赖:4.7】 +- [ ] 4.9 交付企微首次终态消费与退款处理租约:拒绝/撤销终结;通过后按支付类型处理资金,代理主钱包只按原扣款流水回溯,非代理资金由人工退款事实确认。【主:复杂写|不迁移:资产钱包自动回充|依赖:2.30、4.8】 +- [ ] 4.10 交付整单终结的订单、已发放/未发放佣金、全部有效套餐、下一套餐激活或停止资产的持久化步骤幂等与失败恢复。【主:复杂写 Domain/Application|不迁移:未触碰订单/佣金模块|依赖:4.9、2.40】 +- [ ] 4.11 交付退款列表/详情、店铺层级权限、代理最小审批投影、处理失败摘要和前端只读状态;更新 OpenAPI/文档生成器。【主:Query/API 契约|依赖:4.7-4.10】 +- [ ] 4.12 完成退款/企微/Worker/迁移测试环境装配和构建部署检查;真实企微、资金/佣金/套餐人工验收及自动化转 6.1/6.2/6.3。【主:Infrastructure|依赖:4.8-4.11】 + +### B3-03~B3-06 下游业务 + +- [ ] 4.13 `JULY-UR57` 在换货创建完整用例的任何副作用前,批量判定活跃退款(状态 1/历史 4,或状态 2 且处理未成功)并以统一禁止错误拒绝;不新增预检查 API、不改退款/换货状态机。【主:复杂写;辅:Query|依赖:4.7】 +- [ ] 4.14 `JULY-UR57` 更新换货 API/前端错误契约、中文文档和构建部署检查;拒绝路径 Audit Event 延期 6.5。【主:API 契约|依赖:4.13】 +- [ ] 4.15 `JULY-UR33` 交付复用 UR46 的 0~15 天临期 Query、3 天内置顶、列表/Dashboard/C 端/续费投影;只接受可准确推算事实。【主:Query|不迁移:到期算法第二套实现|依赖:1.5、3.7、2.63】 +- [ ] 4.16 `JULY-UR33` 交付每日扫描、15/7/3 最近节点、防重记录与 Outbox/通知消费;漏跑不补多条,站内通知失败不修改套餐事实。【主:Application/Infrastructure|不迁移:短信/企微提醒|依赖:2.8、4.15】 +- [ ] 4.17 `JULY-UR33` 接入 `expiring_asset` 导出输入契约、前端临期页/Dashboard/高亮/续费与 OpenAPI/文档生成器;实际 DataSource 实现在 4.23。【主:Query/API 契约|依赖:4.15】 +- [ ] 4.18 `JULY-UR33` 完成迁移、定时任务、Worker/模板、路由与测试环境构建部署检查;时间边界/通知真实验证转 6.1/6.6。【主:Infrastructure|依赖:4.15-4.17】 +- [ ] 4.19 `JULY-UR44` 为退款、充值、换货新增提交人不可变快照和历史回填(含软删除账号,缺失显示未知),新建时同事务冻结。【主:简单写/迁移|不迁移:业务状态机|依赖:4.1、4.7】 +- [ ] 4.20 `JULY-UR44` 扩展三类列表,以本页实例批量投影 approval_source/status/current approver/processing;代理当前审批人固定为空,换货固定 none。【主:Query|不迁移:实时调用企微|依赖:2.17、4.19】 +- [ ] 4.21 `JULY-UR44` 交付前端列/状态/权限、OpenAPI/文档生成器和构建部署检查。【主:API 契约|依赖:4.20】 +- [ ] 4.22 `JULY-UR42` 交付代码字段 Registry、角色 Scene 字段授权全量替换、超管全目录、普通账号并集交集和零字段拒绝。【主:简单写 Application|辅:Query|不迁移:菜单/行权限|依赖:1.1】 +- [ ] 4.23 `JULY-UR42` 创建导出任务时快照字段/表头/过滤/数据范围/脱敏级别,扩展各 Scene DataSource,Count/Fetch 条件一致且无 N+1。【主:Query/DataSource|辅:Application|不迁移:第二套导出框架|依赖:4.6、4.11、4.17、4.20、1.5】 +- [ ] 4.24 `JULY-UR42` 交付稳定不可枚举 attachment_ref、前端登录恢复落地页和按当前业务权限生成短期下载 URL;不得输出对象 Key/media_id/预签名 URL。【主:Query/Infrastructure|不迁移:公开 Bucket|依赖:2.13、4.23】 +- [ ] 4.25 `JULY-UR42` 交付角色字段配置、导出入口/任务/失败/附件页面契约,更新 OpenAPI/文档生成器和中文文档。【主:API/前端契约|依赖:4.22-4.24】 +- [ ] 4.26 `JULY-UR42` 完成权限表/附件引用迁移、Export Worker/对象存储/配置装配和测试环境构建部署检查;文件内容/性能/权限自动化转 6.1/6.3。【主:Infrastructure|依赖:4.22-4.25】 +- [ ] 4.27 第三批批次检查:执行 `gofmt`、必要代码生成、`go build ./...`,核对资金/审批/支付/导出迁移、Handler 文档生成器、Worker/Outbox/Integration Log、旧路由下线与配置;不新增/运行测试。 + +## 5. 最终收口与测试环境部署 + +- [ ] 5.1 收口 UR45:修正 PRD/Ticket 元数据,向前端交付新旧资产独立搜索并完成页面/人工验收;后端不重复实现。 +- [ ] 5.2 收口 UR46:完成后台详情、卡/设备列表和 C 端预计最终到期字段的前端展示与人工一致性验收;后端四票保持“已完成”。 +- [ ] 5.3 收口 UR60:完成联系电话精确筛选前端、加载/空态/非法参数展示与浏览器人工联调;维护窗口确认索引部署。 +- [ ] 5.4 收口 UR86:完成前代/后代标签与受控跳转前端验收,并在维护窗口抽样历史数据;不得因未抽样把后端状态回退。 +- [ ] 5.5 联合收口 UR98/UR45/UR86:确认换货新资产继承店铺、旧资产保留归属、新旧搜索和双向链路契约在同一前后端版本一致。 +- [ ] 5.6 冻结测试环境版本、迁移清单、API/Worker/Relay/前端版本、配置样例和回滚负责人;确认需求16无代码/迁移/入口。 +- [ ] 5.7 进入维护模式,停止相关写入与旧 Worker;执行增量迁移和前置数据清单,失败时保持维护且不开放访问。 +- [ ] 5.8 发布 API、Relay/Worker、匹配前端版本,装配企微、支付、Gateway、运营商、对象存储与 Redis/Asynq 测试环境配置。 +- [ ] 5.9 执行最终允许门禁:`gofmt` 检查、必要代码生成、`go build ./...`、迁移版本、路由/OpenAPI、Worker 注册、配置就绪和前后端版本一致性检查;不运行 `go test` 或真实依赖自动验收。 +- [ ] 5.10 恢复 Worker 与测试环境访问,记录每条线实际状态;只能标记“测试环境已部署/待人工验收”,不得标记生产验收完成。 +- [ ] 5.11 发布后若产生审批、支付、资金、Outbox、Integration Log、通知或部分成功任务事实,回滚仅暂停异常入口并前向修复,不清表、不恢复旧 Writer、不要求重复付款。 + +## 6. 延期验证与生产发布门禁(本次不得预勾选) + +- [ ] 6.1 恢复并完成所有单元、集成、HTTP、业务流程、并发、迁移、权限、性能与回归自动化;补齐本轮未新增的 `_test.go`,运行完整 `go test ./...` 并保留最终代码证据。 +- [ ] 6.2 完成真实企业微信模板、平台本人绑定、代理固定成员、附件、提交、加密回调、轮询、同意/拒绝/撤销/删除/结果未知恢复,以及退款和线下充值终态验收。 +- [ ] 6.3 完成真实 PostgreSQL、Redis/Asynq、对象存储、微信 Native、支付宝 PreCreate/TradeQuery/回调、支付成功未入账恢复与导出文件验收。 +- [ ] 6.4 完成真实 Gateway 限速账号/运营商档位、设备当前卡、失败/结果未知,以及移动/联通/电信运营商回调和 19/20 位 ICCID 验收。 +- [ ] 6.5 恢复全局 Audit Event 治理:重新评审 `.scratch/tech-global-audit/` 22 张票,完成 Writer、业务覆盖、历史投影、审计中心、系统配置/Outbox 正式 Adapter、敏感读取/导出/保留与一次性发布门禁;不得把测试环境冻结改为永久 N/A。 +- [ ] 6.6 完成后台、代理端、C 端全部页面与真实人工验收矩阵,包括异步部分成功、权限空态、通知、临期、换货历史抽样、余额预警和状态展示。 +- [ ] 6.7 完成生产存量数据核对、进行中退款/充值迁移、企微模板与账号准备、支付/Gateway配置、停机发布与回滚演练、性能/安全/Access Log 脱敏门禁。 +- [ ] 6.8 只有 6.1~6.7 全部具备真实证据后,才可把生产发布和七月迭代验收标记完成;测试环境豁免不得继承到生产。