11 KiB
ADDED Requirements
Requirement: 以当前代码重新建立审计覆盖基线
实施前系统团队 MUST 重新扫描当前仓库的 HTTP RouteSpec、Handler、Application、旧 Service、Asynq Worker、定时任务、外部回调、GORM Model、Outbox 消费者、Integration Log 接入点和旧审计 Writer,并 SHALL 形成可复核的逐入口覆盖清单。清单 MUST 覆盖平台、代理、企业、个人客户、Open API 和系统自动入口,并 MUST 为每项记录代码入口、业务领域、动作、操作者来源、资源、事务边界、结果策略以及 Audit Event、Domain Ledger、Integration Log、Outbox 的使用决定或明确 N/A 理由。
Scenario: 发现七月后新增的定时任务
- WHEN 当前代码包含在线充值恢复、订单过期、告警、企微审批恢复、数据清理、通知清理、套餐临期提醒或流量落盘等计划任务
- THEN 新覆盖清单按当前代码逐项登记,而不是沿用旧清单中的定时任务数量
Scenario: 普通查询入口分类
- WHEN 扫描发现列表、详情、统计或其他纯读取入口
- THEN 清单将普通读取的 Audit Event 标记为 N/A 并写明理由,且不将其伪装为业务动作
- AND 对 Action Registry 标记的敏感读取另行登记读取审计、目标资源和失败关闭策略
Requirement: 历史清单仅作遗漏参考
七月旧 490 项覆盖清单、旧 22 张 Ticket 和历史自动分类 MUST NOT 被直接视为本 Change 的现行实施契约。系统团队 SHALL 将其作为遗漏比对材料,并 MUST 对当前代码重新进行业务语义分类。自动扫描结果 MUST 经过业务和研发复核,MUST 排除依赖注入 Setter、纯查询、装配方法和没有业务副作用的技术入口等误报。
Scenario: 自动扫描把 Setter 识别为写操作
- WHEN 候选清单包含
SetXxx依赖注入方法或类似装配入口 - THEN 评审将其标记为非生产业务动作并排除,且不会为其生成 Action Registry 项
Scenario: 旧清单缺少新入口
- WHEN 当前路由、Worker 或 Scheduler 中存在旧 490 项清单没有的入口
- THEN 新清单补充该入口并按当前业务事实分类,旧统计数字不得覆盖当前扫描结果
Requirement: 领域与资源盘点完整性
覆盖清单和 Resource Registry MUST 至少核验账号权限、店铺企业、个人客户、卡设备与卡槽绑定、资产分配与企业授权、换货、套餐与套餐权益、订单支付退款充值、代理及资产钱包、佣金提现、审批与企微、配置与运营商、导入批量、导出、敏感读取、通知、轮询监控、Integration Log、Outbox 和异步任务。每个领域 MUST 明确其一等资源、稳定标识快照、多资源关系、资金或状态 Domain Ledger 以及明确不迁移的旧代码范围。
Scenario: 盘点设备领域
- WHEN 团队评审设备写入口
- THEN 盘点同时覆盖设备、绑定卡、卡槽关系、分配记录、企业授权、套餐权益、钱包和个人客户绑定,而不是只登记设备主表
Scenario: 盘点资金领域
- WHEN 团队评审订单、退款、充值、佣金或提现入口
- THEN 清单明确钱包、唯一交易流水、业务单据和 Outbox 的权威事实边界,Audit Event 不替代 Domain Ledger
Requirement: 受评审的 Action Registry
每个需要审计的完整业务用例 MUST 对应稳定 Action Registry 条目。条目 MUST 声明动作编码、中文名、领域、风险等级、允许来源、主要及受影响资源、资源角色、必须快照字段、前后数据策略、禁止字段、成功事务策略、失败策略和外部可见性。新增或修改非查询业务入口时 MUST 同步更新 Registry 与覆盖清单;未登记动作 MUST 在验证门禁中失败,不得运行时静默使用任意字符串。
Scenario: 新增设备卡槽切换动作
- WHEN 新增或迁移设备当前卡切换用例
- THEN Registry 明确设备、旧卡、新卡和两个绑定关系的资源角色与快照要求,并由覆盖门禁校验该入口已登记
Scenario: 动作决定不记录 Audit Event
- WHEN 业务评审确认某入口是普通查询或不产生审计事实
- THEN 覆盖清单记录明确且可复核的 N/A 理由,而不是留空或删除该入口
Requirement: 按完整纵向用例渐进切换
审计接入 SHALL 按可独立验证的纵向业务用例执行 expand → migrate → contract,MUST NOT 按“先全仓建表、再全仓改 Service、最后统一切换”的水平分层方式迁移。每个迁移单元 MUST 标明其主架构通道为复杂写、简单写、Query、Infrastructure 或 Application + Port/Adapter,MUST 收口该用例的完整事务、不变量、资源关联、成功/失败审计和查询可见性,并 MUST 明确本单元不迁移的旧范围。
Scenario: 迁移钱包扣款用例
- WHEN 钱包扣款纵向切片进入迁移
- THEN 同一切片完成 Domain/Application 资金规则、钱包和流水持久化、同事务 Audit Event、必要 Outbox、失败短事务及可查询验证,不把审计留给后续水平任务
Scenario: 迁移简单配置写入
- WHEN 单表配置更新没有复杂状态机或金额不变量
- THEN 使用 Application 事务脚本接入 Audit Writer,不为审计形式强行创建聚合或多余接口
Scenario: 迁移只读调查视角
- WHEN 实现平台审计或资源时间线查询
- THEN 使用
Handler → Query → GORM/DTO,不让查询经过聚合根或修改状态
Requirement: 单个纵向切片的切换门禁
每个纵向用例只有在以下条件全部满足后 SHALL 停止旧 Writer:真实业务成功事件可查、失败或拒绝事件可查、主要和受影响资源时间线均可定位该操作、事务策略符合风险等级、安全凭据不落库、Action Registry 与覆盖清单已更新、目标用例的旧 Writer 调用归零。未满足任一条件时 MUST 不得宣称该切片切换完成。
Scenario: 换货切片准备停写旧资产日志
- WHEN 换货用例计划停止旧资产 operation log
- THEN 门禁验证换货单、旧新卡或设备、设备绑定卡、钱包、套餐权益和客户绑定均按实际变化可追踪,并确认该用例不再调用旧 Writer
Scenario: 批量任务仅记录根事件
- WHEN 批量分配或购包任务只有批次根事件而单资源时间线没有子事件
- THEN 切换门禁失败,旧 Writer 不得在该用例中停写
Requirement: 旧 Operation Log 的前向停写与历史保留
统一 Audit Event 切换完成的用例 MUST 停止向账号和资产 operation log 新增记录。旧表 SHALL 原样保留,MUST NOT 在线回填、转换或接入新审计中心;新审计中心的完整时间范围从切换点开始。手动轮询日志继续承担任务运行状态和历史事实,MUST NOT 因统一审计切换而提前停写。
Scenario: 查询切换前账号历史
- WHEN 平台查询统一审计上线前的账号操作
- THEN 新审计中心不返回旧账号 operation log 记录
- AND 旧表继续原样保留,不为其创建 Audit Event 或 Event Resource
Scenario: 手动轮询任务仍在运行
- WHEN 统一 Audit Event 已记录人工触发动作
- THEN 手动轮询日志仍保存任务运行状态和结果,Audit Event 只表达谁触发了任务及业务关联
Requirement: 旧 Writer 归零验证
项目 MUST 维护旧账号审计 Writer、旧资产审计 Writer、裸 goroutine 审计调用和直接旧表写入的显式清单。最终 contract 阶段 MUST 通过静态扫描与真实业务验证证明已迁移用例的旧调用归零;既有旧资产历史查询和必要的手动轮询运行写入 MUST 被明确白名单化,且旧历史查询不得进入新审计路由或统一 Query。
Scenario: 发现旧账号 Writer 的异步调用
- WHEN 迁移用例仍通过裸 goroutine 或旧 account audit service 写入账号 operation log
- THEN 最终切换门禁失败并定位该调用点
Scenario: 仅保留独立旧表查询
- WHEN 代码只通过既有独立历史入口读取旧 operation log
- THEN 静态门禁允许该只读依赖,但禁止新审计 Query 依赖旧表,并禁止 Create、Update 或直接表写入
Requirement: 发布总门禁
正式发布前 MUST 满足:当前入口清单无未分类项;所有资金、权限、关键配置、敏感读取和人工状态变更均有事务与失败策略;Action Registry 和 Resource Registry 与代码一致;多资源、批量、设备卡槽、换货和外部回调场景通过验收;平台、代理和企业身份边界符合契约;安全凭据不落库;旧 Writer 按已迁移范围归零;查询分页、索引和无 N+1 证据满足项目性能目标;每日归档、月度最终复核、清理阻断和在线窗口语义通过验收;第一阶段没有面向用户的审计导出、归档查询/恢复或业务删除接口。
Scenario: 存在未分类生产写入口
- WHEN 覆盖清单与当前代码比对发现一个未分类的生产非查询入口
- THEN 发布总门禁失败,直到该入口完成业务评审并登记 Audit Event 或 N/A 决定
Scenario: Integration Log 调查接口包含恢复操作
- WHEN OpenAPI 或路由检查发现 Integration Log 查询中心提供重试、补偿、绑定或恢复写接口
- THEN 第一阶段发布门禁失败
Requirement: 切换监控与前向修复
切换期间系统 MUST 监控 Audit Event 写入成功率和延迟、失败短事务二次失败、未知动作或资源、凭据删除命中、批量根子事件数量差异、归档/清理状态以及旧 Writer 调用。已提交的 Audit Event MUST 不因回滚部署、人工数据修复或业务纠错而删除;错误审计事实 MUST 通过更正事件或前向迁移修复。只有 Retention Worker 可在归档完整性门禁通过后删除 PostgreSQL 中已归档的上月 Audit/Integration 数据。发布回滚 MUST 只影响后续流量路由,MUST 保留数据库当前月 Audit Event、Integration Log 和全部 Domain Ledger,不得删除或回滚已验证完成的对象存储备份。
Scenario: 审计失败率超过发布阈值
- WHEN 切换后关键成功审计写入失败率或延迟超过发布阈值
- THEN 发布流程停止扩大迁移范围,并按失败用例前向修复;已经提交的审计和业务事实不被删除
Scenario: 归档校验未完成时到达月初
- WHEN 上月任一自然日的 Audit 或 Integration 缺少成功 manifest,或对象数量、大小、SHA-256 与数据库最终内容不一致
- THEN 系统阻止整月在线清理并告警
- AND 新业务审计继续正常写入,不因对象存储故障回滚
Scenario: 批量根子事件数量异常
- WHEN 批量根事件的成功计数与可查询子事件数量不一致
- THEN 监控告警并阻止该纵向切片进入 contract 阶段