Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
AUG26-008。
- 迁移 000214–000217:tb_shop 全局唯一且不可修改的随机分销码(含存量回填)、
tb_agent_distribution_registration 待审批注册记录、tb_withdrawal_qualification 资料版本、
tb_commission_withdrawal_request_attempt 审批尝试记录,以及提现申请的 latest_*/异常标记列;
不修改既有迁移,down 在存在本 Change 业务事实或新类型场景行时拒绝破坏性回滚。
- 公开接口 POST /api/c/v1/agent-distribution-registrations:无认证,复用既有短信验证码校验、
消费与限流;无效分销码、停用上级、验证码无效或已消费统一返回「分销码不可用」且不落库,
审批通过前不创建店铺、账号或钱包。
- 审批通过才在同一事务内建启用店铺、代理主账号、钱包、上级层级与业务员快照,驳回不建实体,
重复回调不重复建实体,提交后清理上级下级缓存。
- 提现资料资格按不可变版本保存,替换合同或法人身份证即新增版本并同事务失效旧有效版本;
超管作废原因必填;代理停用与店铺删除联动失效。
- 提现每次提交或重提新增不可变审批尝试记录并冻结金额;企业微信通过仅一次从冻结扣减、
保持状态 2 并写 paid_at(不使用状态 4),驳回/cancelled/deleted 仅一次释放,
通过后撤销不回滚、不重新冻结、只写正交异常标记;加锁顺序统一为申请→尝试→钱包。
- 本地人工终审对已关联审批实例的申请返回状态冲突,approval_instance_id 为空的存量申请保持既有行为,
不新增任何配置开关。
- 补齐审批业务类型注册点全集:业务类型与场景字段常量、场景 DTO 两处枚举与中文描述、
场景字段白名单/合法类型/中文名、数据库 CHECK、Worker 决策消费者与装配、审批审计资源映射,
以及三个新审计资源与 13 个审计动作;失败/拒绝审计改为必达。
- 新增后台路由与 OpenAPI:资格提交/查询/作废、提现申请/重提/详情、店铺详情返回只读分销码。
- 归档本 Change:主 Spec 新增 agent-distribution-withdrawal 能力(5 个 Requirement)。
验证(junhong_cmp_test + Redis DB 6,显式 DB_*,未重置整库):
- 迁移 up → version 217 且 dirty=false → down 3 → up 回 217,fixture 复核残留为 0。
- 受控状态机脚手架 227 项通过 / 0 项失败,覆盖 18 组场景(幂等与乱序回调、资金冻结/释放/重提、
退款回扣 × 在途提现并发、负向场景拒绝审计与 14 个动作码审计真实落库)。
- gofmt 空、go build/go vet 通过、gendocs 与工作区逐字节一致、context-health 通过、
openspec validate --strict 通过、doctor healthy;自动化测试按项目决策为 N/A。
运行期前置(未完成,非代码交付物):由超管经 PUT /api/admin/wecom/scenes/{business_type} 为
agent_distribution_approval、withdrawal_qualification_approval、commission_withdrawal_approval
配置启用场景与模板控件映射;未配置时相应提交失败关闭。
9.9 KiB
9.9 KiB
1. 分销与注册
- 1.1 为
tb_shop新增全局唯一、不可修改的随机distribution_code(新成对迁移 + 条件唯一索引,编号按实施时最大编号顺延);在internal/application/shop/create.go建店事务内生成并处理唯一冲突重试;同步scripts/migration/lib/shop_sql.py使批量导入店铺同样生成分销码;不提供人工指定或编辑入口。 - 1.2 新增
tb_agent_distribution_registration(分销码、上级店铺、手机号、密码哈希、状态、审批实例与时间戳)及模型、状态常量、审计资源常量与 registry 条目;不创建status=2的店铺或账号;同一手机号驳回后再次扫码为新记录。 - 1.3 实现公开接口
POST /api/c/v1/agent-distribution-registrations:经internal/routes.Register注册,且在internal/routes/personal.go的Use()之前;复用既有验证码校验、消费与限流;锁定上级店铺并校验启用,无效码、停用上级、验证码无效或已消费统一返回“分销码不可用”且不落库;新 Handler 同步pkg/openapi/handlers.go、cmd/api/docs.go、cmd/gendocs/main.go与 bootstrap 装配。 - 1.4 注册
agent_distribution_approval决策消费者:通过时同一事务建启用店铺、代理主账号、所需钱包、上级层级与上级业务员快照,标记注册记录并写审计,提交后清理上级店铺下级缓存;驳回仅标记不建实体;条件更新保证重复回调不重复建账号、层级或钱包。 - 1.5 新增
tb_withdrawal_qualification(主体类型、签约主体代码、法人身份证号、合同与身份证正反面附件、可选营业执照/门头照/发票及其主体代码、状态与失效原因、审批实例)与模型、常量;附件每项单对象键,总数不超过企微 6 附件上限。 - 1.6 实现资格提交、替换、作废与停用失效:
POST /api/admin/shops/:shop_id/withdrawal-qualifications(仅本人代理店铺)、超管作废POST /api/admin/withdrawal-qualifications/:id/void(原因必填)、代理停用联动失效;替换合同或身份证时同一事务新增版本并使旧有效版本失效;注册withdrawal_qualification_approval消费者,驳回不影响既有有效版本。 - 1.7 为分销码生成、注册通过/驳回、资格提交/替换/作废/停用失效补齐事务内审计;日志与审计不记录密码、完整证件号或附件内容。
2. 提现
- 2.1 新增
tb_commission_withdrawal_request_attempt(request_id、attempt_no、金额/手续费/费率/实际到账快照、收款信息、申请级发票快照、提交人、审批实例、释放时间)及唯一约束与索引;为tb_commission_withdrawal_request追加latest_attempt_id、latest_approval_instance_id、通过时间与异常标记/原因列。 - 2.2 改造
CreateWithdrawalRequest:增加有效资格校验;事务内锁定佣金钱包、冻结金额、写尝试记录、创建审批实例(business_id= 尝试记录主键)、回填latest_*、写钱包流水与审计;余额不足、资格无效或非本人代理均不创建申请或冻结。 - 2.3 实现驳回后重提:仅已驳回申请可由本人代理修改金额、收款信息与本次发票;事务内先释放旧未结算尝试的冻结,再按新金额冻结并新增尝试记录与新审批实例,历史快照与审批结果不被覆盖,不产生第二笔冻结。
- 2.4 注册
commission_withdrawal_approval终态消费者:通过仅一次从冻结余额扣减、保持WithdrawalStatusApproved=2 并写paid_at;驳回与cancelled/deleted仅一次释放本次尝试冻结并写释放时间;revoked_after_approved不回滚、不重新冻结、不自动重提,写正交异常标记与原因供详情展示;重复、乱序与未知结果由既有交付租约与查询恢复收敛。 - 2.5 本地人工终审边界:
internal/service/commission_withdrawal的通过/驳回在申请已关联审批实例时拒绝并返回状态冲突,不新增任何配置开关;approval_instance_id为空的存量申请保持既有兼容处理;错误交全局 ErrorHandler。 - 2.6 注册资格、提现申请与提现详情的后台路由及 OpenAPI,保障自身店铺与数据范围校验;公开接口不得承载资格、提现或后台查询操作。
3. 审批业务类型注册点
- 3.1
pkg/constants/approval.go:新增agent_distribution_approval、withdrawal_qualification_approval、commission_withdrawal_approval三个业务类型常量与各场景业务字段常量,注释写明business_id取值语义。 - 3.2
internal/model/dto/wecom_scene_dto.go:两处business_typeenum 与中文 description 同步新增三个类型(ENG-DTO-001)。 - 3.3
internal/application/wecom/scene.go:sceneBusinessFields白名单、validApprovalBusinessType、业务类型中文名三处新增。 - 3.4 新成对迁移扩展
chk_wecom_approval_scene_business纳入三个新类型;down在存在新类型场景行时拒绝破坏性回滚并报明确异常;不修改既有迁移,编号按实施时最大编号顺延。 - 3.5
cmd/worker/main.go:新增三个决策 handler 的依赖装配并注册到BusinessDecisionHandlerdispatcher(缺注册时按既有规则返回服务不可用)。 - 3.6
internal/infrastructure/audit/approval.go的approvalBusinessResource新增三个业务类型的资源映射(缺映射会 fail-closed);pkg/constants/audit.go与internal/infrastructure/audit/registry.go新增分销注册记录、资格资料版本、提现审批尝试记录三个审计资源(提现单资源已存在,无需新增)。 - 3.7 运行期前置:上线前由超级管理员经
PUT /api/admin/wecom/scenes/{business_type}为三个业务类型配置启用场景与模板控件映射;迁移不写入模板,未配置时相应提交失败关闭。待维护者执行:配置agent_distribution_approval、withdrawal_qualification_approval、commission_withdrawal_approval的启用场景与控件映射(资格 6 个附件控件对应file_list,必填合同/法人身份证正反面、可选营业执照/门头照/发票);验收证据为GET /api/admin/wecom/scenes返回三类型启用记录及control_mapping,字段清单经GET /api/admin/wecom/scenes/{business_type}/fields核对。本项为运行期配置数据,不是代码交付物,故未勾选。
4. 验证
- 4.1 按 ENG-TEST-001 在
junhong_cmp_testPostgreSQL + Redis DB 6 验证:迁移up/down/up;从本地工作区以显式DB_*参数执行scripts/migrate.sh;仅创建、删除本 Change 自己的 fixture,禁止重置整库。验证:以显式DB_*(junhong_cmp_test)执行./scripts/migrate.sh up(214/215/216/217 全部成功)→version为 217 且dirty=false→down 3→ 再up回 217;down守卫按设计拒绝破坏性回滚(存在tb_agent_distribution_registration行时 000214 拒绝、存在新类型场景行时 000216 拒绝),因此整库回退只能到000214,发布说明写明该边界。验证期间只创建、删除本 Change 自己的 fixture(shop_code LIKE 'AUG26008%'、三张新表、13 个新增动作码审计与资源行),复核残留:新表与审计残留均为 0,tb_shop无空分销码且全局唯一;未重置整库。 - 4.2 受控验证本地状态机:以 Redis 预置验证码(DB 6)、
approval.Port.Prepare与受控TerminalDecisionEvent驱动业务消费者,验证分销码唯一与停用门禁、注册通过/驳回与重复回调、资格替换与作废、提现冻结/重提/通过/驳回/取消/删除/通过后撤销、本地终审拒绝与存量兼容、待审提现释放接缝;不调用企业微信、短信、对象存储或支付网络。验证:临时受控脚手架(Redis DB 6 显式覆盖,.env.local的 DB 7 不适用)驱动真实业务消费者,结果 227 项通过 / 0 项失败,分 18 组:分销码唯一/随机/不可修改/冲突重试与非事务句柄守卫;公开注册验证码无效与已消费、无效码、停用上级统一拒绝且不落库;注册通过建店+账号+钱包+层级+业务员快照且新码≠上级码并可续开下级,重复回调不重复建实体,驳回不建实体且同手机号可再注册;资格提交/替换失效/驳回不改写历史/超管作废/停用与删店联动失效;提现冻结/通过(状态保持 2 且写paid_at,不使用 4)/驳回/cancelled/deleted/重提单笔冻结/通过后撤销不回滚;释放接缝先释放后扣减、重复释放不重复入账;本地终审拒绝新申请与存量兼容;退款佣金回扣 × 在途企微提现(修复前复现 8 项失败);统一加锁序下 6 轮并发无死锁;负向场景拒绝审计与 14 个动作码审计真实落库、恰一个主要资源、失败/拒绝审计不再被吞(auditfailure日志 0 行);数据范围与脱敏投影。脚手架为一次性产物,按清理要求已删除,未在仓库留下测试入口(自动化测试按项目决策为 N/A)。 - 4.3 运行
gofmt -w、go build ./cmd/api ./cmd/worker、go run cmd/gendocs/main.go、openspec validate add-agent-distribution-withdrawal-qualification --strict、openspec doctor --json与./scripts/context-health.sh;自动化测试按项目决策为 N/A。验证:gofmt -l对全部变更 Go 文件输出为空;go build ./cmd/api ./cmd/worker无错误;go vet ./internal/... ./pkg/...无输出;go run cmd/gendocs/main.go重新生成docs/admin-openapi.yaml,与工作区文件逐字节一致,新增路由与 6 值业务类型枚举齐全,既有路由未被改写或删除;./scripts/context-health.sh输出「Context 健康检查通过」;openspec validate add-agent-distribution-withdrawal-qualification --strict输出Change 'add-agent-distribution-withdrawal-qualification' is valid;openspec doctor --json为"healthy": true。