ur37 issues
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
# 01 — 交付企微连接状态与安全 Adapter 闭环
|
||||||
|
|
||||||
|
**What to build:** 超级管理员可以查看企微连接、Token 获取和代理固定代提交成员是否就绪;企微 Token 与成员读取通过统一安全 Adapter 执行,每次真实外部尝试均可追踪,但任何接口、日志或审计都不会泄露 Secret、Token 或固定成员原始 `userid`。
|
||||||
|
|
||||||
|
**Blocked by:** `.scratch/tech-global-audit/issues/02-integration-log-attempt-loop.md` — 02 — 交付可恢复的 Integration Log 尝试闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 主通道为 Infrastructure,辅助通道为 Query。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口企微部署配置、Access Token 缓存与并发刷新、成员可用性读取、连接状态投影和外部尝试记录。明确不建立审批状态机,不创建审批实例,不提供敏感配置在线编辑,也不迁移退款或充值逻辑。
|
||||||
|
|
||||||
|
- [ ] 企微连接使用部署配置提供 CorpID、AgentID、AgentSecret、回调密钥、绑定回调地址、后台固定 Origin、代理固定代提交成员、请求超时和轮询间隔;敏感值不进入通用配置表。
|
||||||
|
- [ ] Access Token 使用 Redis 缓存,TTL 为企微 `expires_in` 减 300 秒,并通过有期限锁避免多进程并发刷新;Redis 异常时不会把空值或过期值伪装为有效 Token。
|
||||||
|
- [ ] 成员读取可以确认代理固定成员属于当前企业、已启用且在应用可见范围内,只向超级管理员返回就绪状态和显示名,不返回原始 `userid`。
|
||||||
|
- [ ] 连接状态接口仅允许超级管理员访问,返回配置就绪、最近连通、最近安全错误摘要、回调最近成功和 Token 最近获取时间,使用统一响应结构。
|
||||||
|
- [ ] Token 和成员外部调用写 Integration Log,记录操作、耗时、企微错误码和安全关联标识,不记录令牌、密钥、完整响应或固定成员原始标识。
|
||||||
|
- [ ] WeCom Adapter 契约测试覆盖 Token 获取、缓存命中、并发刷新、企微非零错误、超时、成员失效、Redis 锁恢复及敏感信息不泄漏;新增 Handler 同步路由、RouteSpec 和两个 OpenAPI 文档生成器。
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# 02 — 完成平台账号本人扫码绑定闭环
|
||||||
|
|
||||||
|
**What to build:** 平台账号和超级管理员可以从本人会话发起官方企微 Web 登录扫码,安全完成本人绑定、查看结果、换绑或解绑;超级管理员可以查看平台绑定清单并强制解绑冲突成员,代理账号始终不能创建或管理企微绑定。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 01 — 交付企微连接状态与安全 Adapter 闭环
|
||||||
|
- `.scratch/tech-global-audit/issues/01-audit-event-write-loop.md` — 01 — 交付不可变 Audit Event 写入闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 复杂写,采用 Application + Domain + Repository/WeCom Adapter;绑定清单为辅助 Query。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口系统账号与企微成员一对一绑定、一次性会话、本人解绑和超级管理员强制解绑。明确不改变账号认证、角色或店铺模型,不允许人工录入 `userid`,不为代理建立绑定。
|
||||||
|
|
||||||
|
- [ ] 只有当前已登录且启用的平台账号或超级管理员可以为自己创建绑定会话;随机 `state` 五分钟有效且原子读取删除,独立 `session_id` 十分钟内可查询结果。
|
||||||
|
- [ ] 回调只从服务端会话确定目标账号,调用 `auth/getuserinfo` 验证企业成员;前端不能传入或覆盖账号 ID、后台 Origin 或企微成员事实。
|
||||||
|
- [ ] 账号 ID 与企微 `userid` 均保持一对一唯一;非企业成员、过期或重复 state、成员已绑定其他账号均安全拒绝,换绑必须由本人重新扫码。
|
||||||
|
- [ ] 回调成功页只向服务端配置的固定 Origin 发送结果,原页面可以通过 `session_id` 轮询兜底;响应和页面不泄露 Token 或其他账号信息。
|
||||||
|
- [ ] 平台账号只能查询和解绑本人;超级管理员可分页查看绑定状态并强制解绑,代理访问所有绑定接口均被拒绝。
|
||||||
|
- [ ] 绑定、换绑、解绑和强制解绑写统一 Audit Event;测试覆盖并发唯一性、会话单次消费、权限、停用账号及历史审批身份快照不随绑定变化;新增 Handler 同步路由、RouteSpec 和两个 OpenAPI 文档生成器。
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 03 — 发布审批场景与首个模板版本
|
||||||
|
|
||||||
|
**What to build:** 超级管理员可以按稳定场景查看退款和线下充值审批配置,读取企微模板并通过可视化字段映射发布首个不可变模板版本;发布前由后端重新核对模板、控件类型和必填映射,业务代码不再依赖易变的模板 ID 或控件 ID。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 01 — 交付企微连接状态与安全 Adapter 闭环
|
||||||
|
- `.scratch/tech-public-foundation/issues/01-public-migration-ownership-and-gates.md` — 01 — 建立公共迁移所有权与检查门禁
|
||||||
|
- `.scratch/tech-global-audit/issues/01-audit-event-write-loop.md` — 01 — 交付不可变 Audit Event 写入闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 复杂写,采用 Application + Domain + Repository/WeCom Adapter;场景与版本列表为辅助 Query。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口稳定场景、不可变模板版本、模板读取、字段映射校验和首次发布。明确不实现运行中安全换版,不创建业务审批实例,不接入退款或充值创建。
|
||||||
|
|
||||||
|
- [ ] 初始化稳定场景 `refund_approval` 与 `offline_recharge_approval`,场景状态固定为 `0=已暂停、1=启用、2=暂停中`,模板版本状态固定为 `0=已停用、1=启用、2=失效`。
|
||||||
|
- [ ] 模板版本保存递增版本号、企微模板标识、名称、控件映射、模板快照、指纹、验证结果和发布快照;历史版本不可修改,每个场景至多一个启用版本。
|
||||||
|
- [ ] 模板读取接口只接受稳定场景和企微模板标识,向前端返回可映射控件事实;前端不能把控件名称、类型或原始映射 JSON 作为可信发布依据。
|
||||||
|
- [ ] 发布前重新从企微读取模板,验证可访问性、控件存在、类型匹配及全部必填业务字段映射;退款和线下充值字段集合符合 PRD,金额字段只用于展示。
|
||||||
|
- [ ] 首次发布在单一事务内写不可变版本、设置当前版本并启用场景;失败时不留下半发布版本或错误的当前版本引用。
|
||||||
|
- [ ] 模板读取、验证和发布写 Integration Log/Audit Event;真实 PostgreSQL 与可编程 Adapter 测试覆盖唯一约束、映射缺失、类型错误、指纹和事务回滚;新增 Handler 同步路由、RouteSpec 和两个 OpenAPI 文档生成器。
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 04 — 提供审批创建前置检查与事务接入契约
|
||||||
|
|
||||||
|
**What to build:** 退款和线下充值创建用例可以通过稳定公共接缝确认场景、当前模板和实际企微发起身份可用,并在自己的业务事务中原子创建唯一审批实例及提交 Outbox;任一前置失败时不会留下业务单、审批实例或待补提事件。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 02 — 完成平台账号本人扫码绑定闭环
|
||||||
|
- 03 — 发布审批场景与首个模板版本
|
||||||
|
- `.scratch/tech-public-foundation/issues/02-transactional-public-outbox-write.md` — 02 — 在业务事务中可靠写入公共 Outbox
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 主通道为复杂写 Application + Domain,辅助通道为 Application Port/Adapter。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口审批创建前置判定、真实业务提交人和企微发起身份快照、唯一审批实例以及事务内提交事件。明确不创建退款单或充值单,不定义其金额和活跃业务规则,不调用远程企微。
|
||||||
|
|
||||||
|
- [ ] 前置检查按稳定场景读取当前启用模板,并拒绝暂停中、已暂停、模板缺失或模板失效;失败发生在调用方写入任何业务事实前。
|
||||||
|
- [ ] 平台和超级管理员使用本人启用且成员可用的绑定;代理仅可在允许代理发起的退款场景使用部署配置固定成员,线下充值不允许代理发起。
|
||||||
|
- [ ] 审批实例冻结业务类型、业务 ID/编号、场景、模板版本与映射、业务快照、真实提交人账号/名称/角色/店铺快照、企微发起身份及 `self_binding/agent_proxy` 来源。
|
||||||
|
- [ ] `(biz_type,biz_id)` 唯一,非空 `sp_no` 全局唯一;状态初始为 `0=提交中`,不使用审批轮次,不建立数据库外键或 GORM 关联标签。
|
||||||
|
- [ ] 调用方可使用同一 GORM 事务创建业务事实、审批实例和结构化 `WeComApprovalSubmissionRequested` Outbox;任一步失败整体回滚,事务中不调用 Redis、Asynq、对象存储或企微。
|
||||||
|
- [ ] 公共状态常量、中文状态名及公开 DTO 描述保持唯一来源;集成测试以代表性测试业务事实验证前置失败零落库、事务回滚、并发唯一性和成功只产生一组审批事实。
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 05 — 完成附件上传与企微异步提交闭环
|
||||||
|
|
||||||
|
**What to build:** 审批提交 Worker 可以从公共 Outbox 可靠领取审批实例,使用冻结的模板、业务快照和企微发起身份上传附件副本并调用企微发起审批;成功后绑定唯一 `sp_no`,明确失败可安全重试,已发送但响应未知时停止自动重发并等待人工恢复。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 04 — 提供审批创建前置检查与事务接入契约
|
||||||
|
- `.scratch/tech-public-foundation/issues/03-outbox-at-least-once-delivery.md` — 03 — 完成 Outbox 到 Asynq 的至少一次投递闭环
|
||||||
|
- `.scratch/tech-global-audit/issues/02-integration-log-attempt-loop.md` — 02 — 交付可恢复的 Integration Log 尝试闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 复杂写 Application + Domain,外部调用位于 Infrastructure WeCom Adapter。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口技术提交尝试、提交租约、附件副本上传、企微表单构造和提交结果分类。明确不处理企微审批终态,不执行退款或充值资金动作,不把临时企微资料变成永久业务事实。
|
||||||
|
|
||||||
|
- [ ] Worker 通过审批状态和 `submit_lease_until` 条件领取、续租并在所有退出路径释放租约;并发 Worker 同一时刻只有租约所有者可以提交。
|
||||||
|
- [ ] 本地私有对象 Key 是申请附件权威引用;Worker 使用受控临时文件上传企微,临时 `media_id`、预签名 URL 和文件内容不进入永久业务快照、普通日志或响应。
|
||||||
|
- [ ] 企微表单严格使用实例冻结的模板映射、真实业务提交人和实际企微发起身份,审批人配置完全使用企微模板,不由系统计算或提交。
|
||||||
|
- [ ] 成功响应原子绑定唯一 `sp_no` 并进入审批中;企微明确未创建时进入提交失败,可在同一实例上技术重试且保留尝试历史。
|
||||||
|
- [ ] 可证明未发送的建连失败允许自动重试;请求已发送后超时或连接中断进入提交结果未知,持久化未知事实后禁止自动再次调用 `applyevent`。
|
||||||
|
- [ ] 测试覆盖 Outbox 重投、并发领取、租约过期恢复、部分附件失败、明确失败、未发送失败、响应未知、成功绑定和结构化 Asynq 载荷,且不依赖真实企微网络。
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# 06 — 完成场景安全暂停、模板换版与失效检测
|
||||||
|
|
||||||
|
**What to build:** 超级管理员可以把场景安全切换到暂停中,停止新提交租约并等待已有租约释放后完成暂停,再发布新的不可变模板版本并恢复场景;后台定期发现启用模板不可访问或指纹变化时会自动暂停场景并告警。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 03 — 发布审批场景与首个模板版本
|
||||||
|
- 05 — 完成附件上传与企微异步提交闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 复杂写 Application + Domain,模板验证调度为辅助 Infrastructure。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口场景暂停状态机、租约排空、模板原子切换、恢复和定期有效性检查。明确不停止暂停前已经创建的审批同步或终态处理,不自动发现新的企微模板 ID。
|
||||||
|
|
||||||
|
- [ ] 状态接口只接受目标已暂停或启用以及必填原因;暂停中由系统维护,前端不能直接写入,非法转换或乐观锁冲突安全失败。
|
||||||
|
- [ ] 进入暂停中后立即拒绝新业务前置检查和新提交租约,但已有有效租约可以续租直至完成;所有未过期租约消失后才进入已暂停。
|
||||||
|
- [ ] 新版本发布前重新读取和验证企微模板;事务内停用旧版本、写新版本、切换当前版本并恢复场景,任一步失败保持场景暂停且旧事实不被改写。
|
||||||
|
- [ ] 后台按十分钟默认间隔验证启用模板;模板不可访问或指纹变化时标记版本失效、暂停对应场景并产生安全告警,不猜测替代模板 ID。
|
||||||
|
- [ ] 场景暂停和恢复不影响已创建实例继续接收回调、轮询和终态处理;历史实例始终使用创建时冻结的版本和映射。
|
||||||
|
- [ ] 测试覆盖暂停等待、停止发租约、租约续期/自然释放、首次与再次发布、发布回滚、模板失效、指纹变化、并发状态更新和 Audit Event 完整性。
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 07 — 接入加密回调与权威详情同步
|
||||||
|
|
||||||
|
**What to build:** 企业微信可以完成审批回调 URL 校验并推送加密事件;系统验签、解密和核对企业身份后快速记录回调并触发统一同步,最终始终以 `getapprovaldetail` 保存审批状态、审批人、意见、附件元数据和时间线。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 05 — 完成附件上传与企微异步提交闭环
|
||||||
|
- `.scratch/tech-global-audit/issues/02-integration-log-attempt-loop.md` — 02 — 交付可恢复的 Integration Log 尝试闭环
|
||||||
|
- `.scratch/tech-public-foundation/issues/10-sensitive-route-safe-summaries.md` — 10 — 为敏感接口提供安全摘要策略
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 主通道为复杂写 Application + Domain,回调协议和企微详情位于 Infrastructure Adapter。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口回调协议、安全入站记录和单实例权威状态同步。明确不实现批量轮询,不消费退款或充值终态,不把回调载荷中的状态当成业务权威。
|
||||||
|
|
||||||
|
- [ ] GET 回调按企微协议完成 URL 校验;POST 回调校验 SHA1 签名、AES-CBC 解密并核对 `receiveID=CorpID`,错误签名、密文或企业身份安全拒绝。
|
||||||
|
- [ ] 入站回调先保存脱敏 Integration Log 与幂等标识,只记录事件类型、安全资源标识、大小、哈希和结果,不记录密文、明文、签名、Nonce 或密钥。
|
||||||
|
- [ ] 有效回调快速触发统一 `SyncApprovalStatus` 并按企微约定响应;重复事件、乱序事件和同步任务重复投递不直接改写状态。
|
||||||
|
- [ ] 同步用例调用 `getapprovaldetail` 作为唯一权威,保存审批详情、审批人名称快照、意见、附件元数据、时间线和最后同步时间。
|
||||||
|
- [ ] 审批实例以乐观锁和合法状态转换更新;详情未变化时只更新必要轮询事实,不产生第二个等价业务事件。
|
||||||
|
- [ ] 真实 Fiber 回调测试使用测试 Token/AES Key 构造签名密文,覆盖 URL 校验、签名/解密/CorpID 错误、重复事件、快速响应和权威同步;新增 Handler 同步路由、RouteSpec 和两个 OpenAPI 文档生成器。
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# 08 — 完成轮询补偿与终态只发布一次
|
||||||
|
|
||||||
|
**What to build:** 系统可以每两分钟并发安全地领取最久未同步的审批实例并查询企微权威详情;无论回调、轮询或重复任务谁先到,审批首次进入终态时都只发布一次对应业务终态事件,并对撤销、删除和通过后撤销保留明确异常语义。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 07 — 接入加密回调与权威详情同步
|
||||||
|
- `.scratch/tech-public-foundation/issues/03-outbox-at-least-once-delivery.md` — 03 — 完成 Outbox 到 Asynq 的至少一次投递闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 复杂写 Application + Domain,轮询调度和领取为辅助 Infrastructure。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口轮询资格、并发领取、审批终态状态机及事务内业务事件发布。明确不实现退款退款、充值入账或其他下游消费者,不把审批通过等同于业务处理成功。
|
||||||
|
|
||||||
|
- [ ] 轮询默认每两分钟扫描提交中、审批中和需要恢复同步的实例,单批最多 100 条,按最久未轮询优先并以稳定主键打破并列。
|
||||||
|
- [ ] 多实例通过轮询租约或条件领取避免同一时刻重复占用;详情失败记录安全摘要并重新安排,进程中断后过期租约可恢复。
|
||||||
|
- [ ] 回调、轮询和手动同步复用同一状态同步用例,审批中、通过、驳回、撤销、通过后撤销、删除及提交异常均遵守公共状态机。
|
||||||
|
- [ ] 首次进入终态时在保存审批状态的同一 PostgreSQL 事务写稳定业务终态 Outbox;状态未变化、重复终态或乐观锁冲突重试不会产生第二个事件。
|
||||||
|
- [ ] 审批状态与 `business_process_result/business_processed_at` 独立;通过后撤销在业务未执行时阻断后续处理,已执行时不自动冲正并产生 critical Audit Event 与告警事件。
|
||||||
|
- [ ] 测试覆盖轮询资格、批量上限、稳定排序、多实例领取、回调与轮询并发、重复终态、乱序状态、乐观锁冲突、撤销异常和每个业务终态最多一个 Outbox。
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 09 — 交付审批运行查询、权限投影与立即同步
|
||||||
|
|
||||||
|
**What to build:** 超级管理员或具备企微审批运营权限的平台账号可以筛选审批运行记录、查看其原业务权限允许的完整审批详情并立即同步;代理和无业务权限的平台账号不能借企微运营接口看到审批人、意见、附件或其他业务资料。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 02 — 完成平台账号本人扫码绑定闭环
|
||||||
|
- 03 — 发布审批场景与首个模板版本
|
||||||
|
- 07 — 接入加密回调与权威详情同步
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 主通道为 Query,立即同步为辅助复杂写 Application。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口审批运行列表、详情、专项权限、原业务权限复核和主体信息投影。明确不提供本地通过、驳回、退回或资金处理动作,不迁移退款/充值自己的列表和详情 Query。
|
||||||
|
|
||||||
|
- [ ] 运行列表支持业务类型、审批状态、`sp_no`、业务单号、业务处理结果和分页过滤,默认每页 20、最大 100,按更新时间倒序并以 ID 稳定排序。
|
||||||
|
- [ ] 列表和详情返回公共状态及中文名称、模板版本、真实业务提交人、企微身份来源、同步时间、业务处理结果和异常标识,审批与业务处理状态独立展示。
|
||||||
|
- [ ] 只有超级管理员或具备独立企微审批运营权限的平台账号可访问运行接口;该权限不授予场景、模板、绑定管理或异常恢复能力。
|
||||||
|
- [ ] 完整详情必须再次通过对应退款或充值业务权限 Adapter;无权、资源不存在和引用失效使用统一禁止访问语义,企微运营权限不能绕过业务数据范围。
|
||||||
|
- [ ] 平台完整投影可以包含审批人、意见、时间线和审批附件元数据;供业务详情复用的代理投影只包含真实提交人、审批状态/时间和业务处理结果,不返回企微内部标识。
|
||||||
|
- [ ] 立即同步只调用统一权威详情同步,不执行审批动作;Query 和 Fiber 集成测试覆盖角色权限、业务权限、分页排序、无 N+1、附件权限和越权一致性;新增 Handler 同步路由、RouteSpec 和两个 OpenAPI 文档生成器。
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# 10 — 完成提交结果未知的高风险恢复闭环
|
||||||
|
|
||||||
|
**What to build:** 超级管理员或具备企微审批异常恢复权限的平台账号可以为提交结果未知的实例安全绑定已存在的 `sp_no`,或在人工确认企微未创建后重新发送同一审批;系统完整保留恢复原因、校验依据、前后状态和每次技术尝试,避免重复企微审批。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 05 — 完成附件上传与企微异步提交闭环
|
||||||
|
- 07 — 接入加密回调与权威详情同步
|
||||||
|
- 09 — 交付审批运行查询、权限投影与立即同步
|
||||||
|
- `.scratch/tech-global-audit/issues/01-audit-event-write-loop.md` — 01 — 交付不可变 Audit Event 写入闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 复杂写 Application + Domain,企微核对位于 Infrastructure Adapter。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口提交结果未知的两个明确恢复动作和高风险审计。明确不允许编辑业务申请、不创建业务审批轮次、不恢复已经进入明确终态的审批,退款驳回后的再次申请仍属于 UR#35 新业务单。
|
||||||
|
|
||||||
|
- [ ] 两个恢复接口只允许超级管理员或具备独立异常恢复权限的平台账号调用,请求必须包含非空恢复原因;企微运营权限本身不能执行恢复。
|
||||||
|
- [ ] 绑定已有 `sp_no` 前查询企微详情并核对企业、模板版本、实际企微发起身份及来源、业务场景、真实业务提交人字段和提交业务快照,任一不匹配均拒绝绑定。
|
||||||
|
- [ ] 成功绑定使用非空 `sp_no` 全局唯一约束和预期状态条件更新,随后进入统一权威同步;重复调用不能覆盖其他实例或制造第二次终态。
|
||||||
|
- [ ] 确认未创建后重新发送保留原尝试,并在同一审批实例记录新的技术提交尝试;不创建新业务 ID、审批实例或审批轮次。
|
||||||
|
- [ ] 已经进入通过、驳回、撤销、通过后撤销、删除等明确终态的实例禁止恢复;并发恢复、重复操作和状态变化时安全失败。
|
||||||
|
- [ ] 两种恢复均写高风险 Audit Event 并保留 Integration Log;测试覆盖无权限、非法状态、`sp_no` 不存在、逐项快照不匹配、成功绑定、重新发送、重复并发和审计事务完整性;新增 Handler 同步路由、RouteSpec 和两个 OpenAPI 文档生成器。
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# 11 — 向真实业务提交人发送审批结果通知
|
||||||
|
|
||||||
|
**What to build:** 企微审批首次进入终态后,系统可以通过公共通知能力可靠通知真实业务提交人;代理由固定企微成员代提交时仍只把代理本人视为申请人,通过后撤销等高风险异常可按规则通知申请人和当前财务角色账号。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 08 — 完成轮询补偿与终态只发布一次
|
||||||
|
- `.scratch/tech-inapp-notifications/issues/08-notification-release-gate.md` — 08 — 完成公共通知发布门禁与下游接入契约
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** Application + Port/Adapter,复用公共 Outbox 和通知消费者。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口企微审批结果通知事件、接收人语义、受控模板与目标引用。明确不复制通知模型、Worker、未读接口或前端消息中心,不发送企微待办,不承担退款到账通知。
|
||||||
|
|
||||||
|
- [ ] 通过、驳回、撤销、删除和通过后撤销使用受控通知类型、稳定事件 ID、审批实例/业务引用和最小结构化模板字段。
|
||||||
|
- [ ] 普通审批结果接收人固定为审批实例冻结的真实业务提交人账号 ID,绝不使用实际企微发起 `userid` 或代理固定代提交账号替代。
|
||||||
|
- [ ] 通过后撤销且业务已经处理时,除申请人外按公共通知接缝解析当前可用财务角色账号;同一账号多重命中只生成一条通知。
|
||||||
|
- [ ] 重复回调、轮询、Outbox 和通知 Worker 消费不会生成重复通知;账号已停用或删除时遵循公共通知无接收人语义,不无限重试。
|
||||||
|
- [ ] 通知只保存受控审批或来源业务引用,目标解析时重新验证当前权限,不保存任意 URL、审批附件、意见或企微内部身份。
|
||||||
|
- [ ] 端到端测试覆盖平台本人发起、代理代提交、通过/驳回、通过后撤销、多接收人去重、停用提交人、重复事件和受控目标权限变化。
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# 12 — 交付历史审批与待处理数据迁移接缝
|
||||||
|
|
||||||
|
**What to build:** 发布人员可以幂等盘点退款和线下充值的历史本地审批,把已结束记录保留为只读 `legacy` 事实,并对仍待处理记录执行真实提交人、企微身份、模板和业务资料预检,输出可迁移项与明确待人工处理清单。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 02 — 完成平台账号本人扫码绑定闭环
|
||||||
|
- 03 — 发布审批场景与首个模板版本
|
||||||
|
- 04 — 提供审批创建前置检查与事务接入契约
|
||||||
|
- 05 — 完成附件上传与企微异步提交闭环
|
||||||
|
- 06 — 完成场景安全暂停、模板换版与失效检测
|
||||||
|
- 07 — 接入加密回调与权威详情同步
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 主通道为 Infrastructure,辅助通道为 Application。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口公共审批迁移分类、预检、幂等实例创建接缝和回滚边界。明确不猜测退款或充值业务事实,不修改其金额、资金或处理状态;各业务表字段回填和旧路由下线分别由 UR#35、UR#34 的纵向切片负责。
|
||||||
|
|
||||||
|
- [ ] 历史已结束的本地审批只投影为 `approval_source=legacy`,保留原业务事实,不创建虚假 `sp_no`、企微审批人、意见、附件或时间线。
|
||||||
|
- [ ] 待处理记录按业务类型核对真实创建人、账号类型、本人绑定或固定代理身份、当前场景/模板以及业务提供的必需快照和附件事实。
|
||||||
|
- [ ] 满足条件的记录可通过公共事务接缝幂等创建唯一企微审批实例及提交事件;重复执行不会生成第二个实例、`sp_no` 或 Outbox。
|
||||||
|
- [ ] 缺少平台绑定、代理固定身份、真实提交人、模板、金额或附件等事实时进入结构化待处理清单,不继续调用旧审批动作,也不由迁移脚本猜测或补造。
|
||||||
|
- [ ] 应用回滚保留已经形成的企微实例、身份/模板快照、Outbox、Integration Log 和 Audit Event;真实企微审批开始后不得恢复旧本地审批按钮。
|
||||||
|
- [ ] 迁移测试覆盖历史终态、平台/代理待处理、缺失事实、重复执行、并发唯一性、停止条件、安全输出和只清理本次隔离夹具。
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# 13 — 冻结企微后台与个人中心前端契约
|
||||||
|
|
||||||
|
**What to build:** 前后端可以依据稳定契约实现 `/system/wecom`、个人中心企微绑定、审批运行列表/详情和异常恢复交互;契约明确每种角色可见入口、服务端状态、加载与失败表现、高风险确认和禁止出现的本地审批动作。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 02 — 完成平台账号本人扫码绑定闭环
|
||||||
|
- 03 — 发布审批场景与首个模板版本
|
||||||
|
- 09 — 交付审批运行查询、权限投影与立即同步
|
||||||
|
- 10 — 完成提交结果未知的高风险恢复闭环
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 跨仓前端契约与验收,后端接口分别保持 Query 或 Application 原通道。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口 OpenAPI、页面状态、权限菜单、交互和人工验收包。当前仓库不包含前端源码,因此明确不伪装为前端实现,不修改退款或充值业务页面;后续前端仓按本契约实施。
|
||||||
|
|
||||||
|
- [ ] `/system/wecom` 仅超级管理员可见,展示连接状态、代理固定成员、场景、模板版本/映射、平台绑定清单和异常入口,不提供 Secret 或固定 `userid` 编辑。
|
||||||
|
- [ ] 平台和超级管理员个人中心展示本人绑定状态、成员名称、最近验证时间及绑定/换绑/解绑;代理不展示绑定入口,扫码失败可通过会话轮询恢复。
|
||||||
|
- [ ] `/operations/wecom-approvals` 只对超级管理员或具备运营权限的平台账号显示,覆盖筛选、分页、详情、立即同步和业务处理结果;无业务权限时不显示敏感资料。
|
||||||
|
- [ ] 提交结果未知仅对具备恢复权限的主体展示两个高风险动作,均要求原因和二次确认;页面明确区分绑定已有单号与确认未创建后重发。
|
||||||
|
- [ ] 所有页面覆盖加载、真实空态、筛选空态、403、网络失败、场景暂停中、模板失效、绑定过期、提交失败、结果未知及通过后撤销告警。
|
||||||
|
- [ ] 页面和 OpenAPI 不出现本地通过、拒绝、退回、重提、审批金额修改或人工确认资金按钮;完成中文验收说明、OpenAPI 校验和接口文档索引更新。
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# 14 — 以退款场景完成真实企微发布门禁
|
||||||
|
|
||||||
|
**What to build:** 发布负责人可以使用退款审批场景完成公共企微能力的真实端到端验收:平台本人或代理固定成员发起包含真实附件和真实提交人的审批,人工同意或拒绝,经加密回调或轮询同步到本地,并验证重复事件不会产生重复退款终态事件;验收结果形成不含敏感信息的发布与回滚报告。
|
||||||
|
|
||||||
|
**Blocked by:**
|
||||||
|
|
||||||
|
- 01 — 交付企微连接状态与安全 Adapter 闭环
|
||||||
|
- 02 — 完成平台账号本人扫码绑定闭环
|
||||||
|
- 03 — 发布审批场景与首个模板版本
|
||||||
|
- 04 — 提供审批创建前置检查与事务接入契约
|
||||||
|
- 05 — 完成附件上传与企微异步提交闭环
|
||||||
|
- 06 — 完成场景安全暂停、模板换版与失效检测
|
||||||
|
- 07 — 接入加密回调与权威详情同步
|
||||||
|
- 08 — 完成轮询补偿与终态只发布一次
|
||||||
|
- 09 — 交付审批运行查询、权限投影与立即同步
|
||||||
|
- 10 — 完成提交结果未知的高风险恢复闭环
|
||||||
|
- 11 — 向真实业务提交人发送审批结果通知
|
||||||
|
- 12 — 交付历史审批与待处理数据迁移接缝
|
||||||
|
- 13 — 冻结企微后台与个人中心前端契约
|
||||||
|
- `.scratch/tech-public-foundation/issues/12-foundation-release-gate-and-integration-contract.md` — 12 — 建立公共基础发布门禁和下游接入契约
|
||||||
|
- UR#35 退款企微审批的“退款创建接入公共审批并消费终态事件”纵向 Ticket;UR#35 拆票后必须在本票实施前替换为其具体文件引用
|
||||||
|
|
||||||
|
**Status:** ready-for-agent
|
||||||
|
|
||||||
|
**架构通道:** 主通道为 Infrastructure 与端到端发布验收,辅助通道为跨 PRD Application 契约。
|
||||||
|
|
||||||
|
**完整业务边界:** 本票收口 UR#37 公共能力与首个退款业务切片的真实企微联合门禁。公共能力只验证审批实例、提交、同步和终态事件的正确性;退款金额、资金、佣金、套餐终结和业务幂等仍由 UR#35 对应纵向 Ticket 收口,不在本票重复实现。
|
||||||
|
|
||||||
|
- [ ] 使用真实退款模板和唯一隔离夹具,通过真实 HTTP 退款创建链路分别验证平台本人绑定发起与代理固定成员代发,企微表单正确展示真实业务提交人、退款快照和真实附件。
|
||||||
|
- [ ] 人工完成至少一次同意和一次拒绝,验证加密回调可以原样转发并完整验签解密;丢弃一次回调后由两分钟轮询恢复到同一权威结果。
|
||||||
|
- [ ] 重复回调、重复轮询和重复任务不会产生第二个审批终态 Outbox;退款终态消费者的资金正确性与幂等结论引用 UR#35 具体 Ticket 的验收结果。
|
||||||
|
- [ ] 自动化 Adapter 继续覆盖超时、响应未知、重复/乱序、撤销、删除、通过后撤销和限流等不适合稳定人工制造的异常。
|
||||||
|
- [ ] 发布检查确认真实密钥已轮换且仅由部署配置提供,回调/可信域名、模板映射、平台绑定、代理固定成员、Worker、监控和通知均就绪;任一门禁失败不得开放退款创建。
|
||||||
|
- [ ] 验收报告只包含运行 ID、业务安全标识、状态、计数和时间,不包含密钥、Token、原始 `userid`、对象 Key、临时 `media_id` 或个人敏感信息;回滚说明保留已形成的全部审批事实并采用向前修复。
|
||||||
Reference in New Issue
Block a user