All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m26s
78 lines
16 KiB
Markdown
78 lines
16 KiB
Markdown
# 七月迭代已完成范围实施证据
|
||
|
||
> 核验日期:2026-07-25
|
||
> 范围:OpenSpec `deliver-july-iteration-confirmed-scope` 任务 0.1~7.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`;复用创建、详情、更新和套餐管理接口,1~100 项在单事务内校验和写入 | 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.1~3.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.1~4.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.2~6.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.1~7.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 生成器依赖树编译成功不能替代完整构建结论。
|