openspec 创建

This commit is contained in:
2026-07-24 09:41:02 +08:00
parent 42991c7593
commit 304e42c43e
7 changed files with 710 additions and 0 deletions

View File

@@ -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 一起延期

View File

@@ -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** 只能看到排除说明,不得出现可实施任务或发布依赖

View File

@@ -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 重新启用延期验证与治理清单,全部完成前不得声明生产验收通过