Files
junhong_cmp_fiber/openspec/changes/deliver-july-iteration-confirmed-scope/实施证据.md
break 73f5125d3d
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
七月迭代短暂完结,还有很多后端的关键东西没有弄,这是一版赶时间做的东西
2026-07-25 17:06:58 +08:00

78 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 七月迭代已完成范围实施证据
> 核验日期2026-07-25
> 范围OpenSpec `deliver-july-iteration-confirmed-scope` 任务 0.17.5。首个矩阵保留 0.1 对历史已完成范围的只读证据,后续章节记录本 Change 的生产代码、迁移、契约和静态收口证据。
## 需求证据矩阵
| 需求 | 已有实现与接口证据 | 迁移证据 | 自动化验证证据 | 结论与联调边界 |
| --- | --- | --- | --- | --- |
| #45 换货新旧资产展示与独立搜索 | `internal/service/exchange/asset_snapshot.go``internal/query/exchange/list.go``internal/handler/admin/exchange.go``GET /api/admin/exchanges` 支持 `old_asset_keyword``new_asset_keyword` | N/A不新增表或字段 | `internal/service/exchange/asset_snapshot_test.go``internal/query/exchange/list_test.go``internal/handler/admin/exchange_test.go` | 后端快照与搜索已交付;前端页面与浏览器人工验收属联调。 |
| #46 资产预计最终到期 | `internal/query/packageexpiry/query.go`后台解析、C 端资产信息和资产列表均返回预计到期投影 | `migrations/000164_add_package_expiry_query_indexes.*.sql` | `internal/query/packageexpiry/query_test.go``internal/routes/asset_exchange_trace_integration_test.go` | Query、HTTP 字段与索引已交付;页面展示为联调范围。 |
| #55 套餐分配生效条件 | `internal/domain/package/terms.go``internal/service/package/`;分配、系列授权和单条覆盖写入购买快照 | `migrations/000162_add_expiry_base_override_to_shop_package_allocation.*.sql``000163_add_package_usage_terms_snapshots.*.sql` | `internal/domain/package/terms_test.go``internal/store/postgres/package_terms_snapshot_integration_test.go``internal/service/package/activation_terms_integration_test.go``internal/handler/admin/shop_package_expiry_base_integration_test.go` | 快照写入、历史回退与异常拒绝已交付;前端选项联调待同窗验收。 |
| #60 店铺联系电话搜索 | `internal/service/shop/service.go``internal/query/shop/business_owner.go``GET /api/admin/shops?contact_phone=` 精确匹配 | `migrations/000160_add_shop_contact_phone_index.*.sql` | `internal/routes/shop_integration_test.go` 覆盖参数、分页、权限、精确匹配、店铺范围和索引 | 后端与索引已交付;筛选页面及四类账号人工验收为联调范围。 |
| #86 资产前代/后代换货标识 | `internal/query/asset/exchange_trace.go``internal/routes/asset.go`;资产解析返回 `exchange_trace` | `migrations/000161_add_exchange_trace_indexes.*.sql` | `internal/query/asset/exchange_trace_test.go``internal/routes/asset_exchange_trace_integration_test.go` | 单节点前/后代投影与可见性已交付;前端跳转和历史异常抽样为联调/发布验收。 |
| #38 代理主钱包信用额度 | `internal/domain/wallet/``internal/application/wallet/``internal/application/role/default_credit.go``internal/query/shop/fund_summary.go`;角色默认额度、店铺调额、资金概况和开放余额接口已装配 | `migrations/000171``000177` | 本次目标包编译通过;资金迁移异常查询、并发与真实 PostgreSQL/Redis/Asynq 验收在原总 Change 中明确延期 | 代码与接口已交付;真实资金并发和迁移数据门禁属测试环境验收。 |
| #94 状态同步与运营商回调 | `internal/application/cardobservation/``internal/infrastructure/cardobservation/``internal/handler/callback/{ctcc,cmcc,cucc}_realname.go`;公共 `ApplyCardObservation`、观测序列和四类回调已装配 | `migrations/000178``000181` | 本次目标包编译通过原总结明确真实运营商样例、Gateway、19/20 位命中和迁移重放延期 | 后端代码与测试环境装配已完成;不宣称生产验收完成,只剩真实外部环境联调门禁。 |
| #96 店铺业务员归属 | `internal/query/shop/business_owner.go``internal/infrastructure/shop/recipient_resolver.go`;店铺创建/更新、列表/详情/候选人与通知接收人解析已装配 | `migrations/000169_add_shop_business_owner.*.sql` | 本次目标包编译通过;原总结明确 HTTP/迁移与真实数据库验收延期 | 后端纵向切片已交付;真实数据库和前端人工验收为联调范围。 |
| #98 换货新资产继承旧店铺 | `internal/service/exchange/service.go` 在完成换货时拒绝其他店铺资产,并让平台库存新资产继承旧资产 `shop_id``internal/service/exchange/migration.go` 沿用新归属写租户标签 | N/A复用现有资产与换货表 | `go test ./internal/service/exchange` 通过;当前没有以 UR#98 命名的专项自动化用例 | 写侧实现已存在;平台库存、他店资产拒绝、完成换货和历史可见性需按 INT-02 联调验收。 |
| #43 系列套餐批量授权 | `internal/service/shop_series_grant/service.go``internal/routes/shop_series_grant.go`复用创建、详情、更新和套餐管理接口1100 项在单事务内校验和写入 | N/A复用现有授权模型 | `internal/handler/admin/shop_package_expiry_base_integration_test.go` 只覆盖系列授权写入的生效条件;`internal/service/shop_series_grant` 当前无专项测试 | 后端批量命令已交付;权限、价格、`remove`、原子性和真实并发验收仍是明确的发布验收缺口。 |
| #73 行业卡复机行为冻结 | `internal/service/iot_card/stop_resume_service.go` 明确保持 `card_category=industry` 无需实名即可进入复机判定;本 Change 不改写该规则 | N/A | `internal/service/iot_card/stop_resume_service_test.go` 当前只覆盖风险 Gateway 扩展判定,没有直接锁定行业卡复机的特征测试 | 代码行为已确认且本任务不修改;直接回归测试为已记录的后续风险。 |
## 2026-07-25 目标验证记录
- 执行:`go test ./internal/service/exchange ./internal/query/exchange ./internal/query/asset ./internal/query/packageexpiry ./internal/service/package ./internal/routes ./internal/handler/admin ./internal/domain/wallet ./internal/application/wallet ./internal/query/shop ./internal/infrastructure/shop ./internal/service/iot_card ./internal/application/cardobservation ./internal/handler/callback`
- 结果:全部退出码为 0有测试的包全部 PASS无测试文件的包完成编译检查。
- 诊断:对上表核心 Go 文件执行 `gopls check`,退出码为 0无诊断输出。首次沙箱内执行因 Go 缓存目录不可写而无法加载 workspace改为允许缓存写入后重跑成功。
## 未扩展的范围
- 本任务未修改换货、套餐、钱包、卡状态、店铺或授权业务代码。
- #45#46#55#60#86 具备完整自动化证据,可归为只剩联调/人工验收。
- #38#43#94#96 有后端实现与迁移,但专项自动化或真实环境验证明确延期;#98 有实现但无归属继承专项测试。这些不得误写为“自动化/生产验收已完成”。
## 2026-07-25 局部缺陷、字段与筛选实现记录
> 用户明确要求本 Change 不编写或补齐测试代码、不运行测试,只完成生产代码至可联调状态;实现优先修改和复用现有能力,确实无法承载时才做最小新增。以下记录生产代码证据,不宣称自动化验证通过。
| 任务 | 生产代码证据 | 当前结论 | 未执行验证 |
| --- | --- | --- | --- |
| 1.1 #189 | `internal/service/package/activation_service.go` 按退款订单与套餐使用记录定位权益,不再用旧资产 ID 缩小查询范围 | 换货迁移后仍可失效原订单对应权益,其他订单权益不受影响 | 退款/换货目标测试、LSP 诊断 |
| 1.2 #181 | `internal/service/client_order/service.go` 写入既有 `purchase_role=self_purchase`;卡快照写 ICCID设备按 VirtualNo→IMEI`internal/service/order/service.go` 同步按 ID 下单设备快照顺序 | 未新增渠道字段,不读取兼容或回填历史空值,只保证新订单正确 | 订单/退款 HTTP 与 DB 测试、LSP 诊断 |
| 1.3 #182/#44 | 退款与换货以 `creator`、充值以 `user_id` 投影统一的 `submitter_id/submitter_name``GetDisplayAccountsByIDs` 批量读取账号展示名并支持软删除历史账号 | 列表无 N+1保留既有 `creator` 字段 | 三类列表/详情权限与响应测试、LSP 诊断 |
| 1.4 #53 | 卡列表直接过滤 `tb_iot_card.real_name_status`;设备列表用有效绑定关系与卡实名状态的实时 `EXISTS/NOT EXISTS` | 无投影、Worker、事件消费者 | 分页、权限、多卡场景测试、LSP 诊断 |
| 1.5 #57 | `RefundStore.HasUnfinishedByAsset` 拦截待审批、已退回、已通过但资产处理未完成的退款;换货创建前失败关闭;新增错误码 1207 | 已拒绝或 `asset_reset=true` 的已完成退款放行,错误消息为“该资产存在退款申请” | 换货创建 HTTP/DB 测试、LSP 诊断 |
| 1.6 API 契约 | 更新订单/退款资产标识说明、实名筛选 DTO、提交人 DTO 和中文错误码;未新增 Handler | 相关 DTO 已进入生成后的 OpenAPI无需新增 Handler 装配 | 契约测试、LSP 诊断 |
## 2026-07-25 完整交付矩阵
| 任务 | 主要代码、迁移与文档证据 | 当前结论 | 后续验证边界 |
| --- | --- | --- | --- |
| 2.1 店铺登录限制 | `migrations/000182_*``internal/application/shop/update.go``internal/service/client_auth/service.go`、店铺 DTO | 店铺配置默认允许登录;开启后仅阻止新资产登录,不吊销已有 Token测试库结构已落库 | 四类账号权限和 C 端登录联调 |
| 2.2 实名策略 | `internal/service/iot_card/realname_policy_batch.go``internal/service/device/realname_policy_batch.go`、C 端资产 DTO | 三种策略、单资产与最多 500 条批量全成全败、设备策略优先生效均已接线 | HTTP/DB 事务和设备多卡场景联调 |
| 2.3 下架套餐续费 | `internal/service/purchase_validation/service.go``internal/service/client_order/service.go`、订单 DTO | 普通列表排除下架套餐;当前使用者可用现有下单入口创建新续费订单,历史订单不修改 | 当前使用者、代理代购、新客户与待支付订单联调 |
| 2.4 支付方式配置 | `internal/bootstrap/payment_method_config.go``internal/service/paymentmethod/`、系统配置和 C 端订单/充值接线 | 卡、设备分别维护非空 `wallet/wechat/alipay` 集合;强充过滤钱包且后端复核 | 配置更新、缓存失败关闭、三种支付渠道真实联调 |
| 3.13.3 站内通知 | `internal/application/exchange/``internal/infrastructure/exchange/``internal/infrastructure/wallet/debit_consumer.go``internal/application/packageexpiry/``migrations/000183_*` | 换货提醒、主钱包首次跌破 100 元提醒、套餐 15/7/3 天提醒均复用现有通知和可靠事件 | Scheduler、重复消费、接收人和 C 端弹窗联调 |
| 4.14.6 企微 Adapter | `migrations/000184_*``000189_*``internal/application/wecom/``internal/infrastructure/wecom/`、企微 Handler/Route/Worker、`docs/wecom-application-connection/功能总结.md` | 应用连接、可见成员、账号绑定、模板映射、默认发起人、提交、加密回调、详情同步和主动恢复已装配 | 可信 IP、真实模板、回调公网、附件、结果未知和轮询闭环 |
| 5.1 员工线下代充值 | `migrations/000190_*``internal/application/agentrecharge/`、充值 Service/DTO | 真实提交人、明文业务快照、通用审批实例和提交 Outbox 同事务创建approved 幂等入主钱包 | 真实企微终态、钱包流水和重复决策联调 |
| 5.2 退款企微审批 | `migrations/000191_*``internal/application/refundapproval/``internal/service/refund/approval_decision.go` | 唯一通用实例和企微标准终态驱动既有退款处理,钱包、佣金、套餐和换货迁移副作用保持幂等 | 全退款/部分退款、换货后退款和重复终态联调 |
| 5.3 旧入口切换 | `pkg/config/config.go``docs/wecom-application-connection/存量审批切换清单.md` | 旧入口默认开启;新企微记录禁止旧入口绕过,关闭后前端只读审批状态 | 存量 provider 清单和生产切换审批 |
| 6.1 批量订购 | `migrations/000192_*``internal/service/asset_package_batch_order/`、Handler/Route/Worker、`docs/asset-package-batch-order/功能总结.md` | 单列 CSV、统一套餐和支付方式、逐行复用订单/钱包幂等规则 | 对象存储、Worker、部分成功、钱包扣款和线下凭证联调 |
| 6.26.4 六类导出 | `internal/exporter/{iot_card,package,agent_wallet_transaction,agent_recharge,refund,exchange}_scene.go``docs/business-data-export/功能总结.md` | 六个 datasource 已注册,复用现有导出任务、筛选和数据权限 | 大数据量、文件下载、金额格式和各账号权限联调 |
| 6.5 卡固定档位限速 | `internal/service/iot_card/speed_tier.go`、Gateway flow-card、卡 Handler/Route、`docs/iot-card-speed-tier/功能总结.md` | 仅卡 ICCID 支持 `-1..8` 固定档位;无设备入口;超时记 unknown 且不盲目重试 | Gateway 全档位、明确失败、超时和人工核对 |
| 6.6 设备 CSV 批量分配 | `migrations/000193_*``internal/task/device_batch_allocation.go`、设备导入任务扩展、`docs/device-batch-allocation/功能总结.md` | 只复用导入任务外壳;`assign_shop/assign_series` 独立分支复用现有权限和业务方法 | CSV、对象存储、Worker 中断恢复和重复消费联调 |
| 7.1 API 契约 | DTO description/enum/status_name、路由注释、两个文档生成器和 `docs/admin-openapi.yaml` | 生成器执行成功;新接口和 DTO 存在,旧设备限速契约不存在 | 前端契约联调 |
| 7.2 审计基线 | `.scratch/tech-global-audit/审计覆盖基线.md` | 0.17.5 均有 Audit Event、Domain Ledger、Integration Log、Outbox 决定或 N/A 理由 | 后续生产治理评审 |
| 7.3 静态收口 | 本文“静态收口记录” | `gofmt``git diff --check` 通过;禁用模式未发现新增违规;测试库迁移已验证至 `000194` | 测试、完整构建和 LSP 未执行 |
| 7.4 联调交付 | `docs/7月迭代/七月迭代联调交付说明.md``docs/environment-variables.md` | 配置、接口、限制和回滚步骤齐备 | 真实环境闭环由后续流程执行 |
## 2026-07-25 静态收口记录
- 对当前工作树 169 个新增或修改的非测试 Go 文件执行 `gofmt -w`,随后 `gofmt -d` 无差异。
- 执行 `git diff --check`,退出码为 0。
- 对新增行检查 `fmt.Errorf`、裸 `go func``database/sql`:仅 Worker 定时任务注册的启动期错误使用 `fmt.Errorf`;没有新增裸 goroutine也没有新增 `database/sql` 依赖。模型中的 `database/sql/driver` 是既有 `driver.Valuer` 实现,不是直接数据库访问。
- 检查生产路由、Handler、Service、Gateway、常量及生成后的 OpenAPI仅保留 `PUT /api/admin/iot-cards/{iccid}/speed-tier` 卡 ICCID 限速不存在设备限速路由、DTO 或通过设备绑定卡间接限速的入口。
- 根据用户后续明确要求,已执行 `env GOCACHE=/private/tmp/junhong-go-build-cache go run cmd/gendocs/main.go`,生成成功;已确认卡限速与设备批量分配路径和 DTO 存在,旧设备限速契约不存在。因此“未执行 OpenAPI 生成”不再是验证缺口。
- 根据用户后续明确要求,已校准测试库迁移元数据并执行 `000187``000194`MCP 复核确认目标表列数、表注释、字段注释、增量字段、索引和约束均无缺口,最终迁移版本为干净的 `194`
- 本 Change 仍未执行单元/集成/验收测试、`go test`、完整 `go build`、LSP 诊断和真实企业微信/Gateway 联调。OpenAPI 生成器依赖树编译成功不能替代完整构建结论。