Files
lijiaoqiao/docs/plans/2026-04-21-supply-api-split-analysis.md
Your Name b193e0aab9 P4-B: supply-api大文件拆分分析 + InvariantChecker接入决策
supply_api.go(1048行): 6分区记录(Account/Package/Billing/Settlement/Earning/Helpers)
runtime.go(589行): 8分区记录(input解析/资源初始化/storeBundle/securityBundle等)
auth.go(891行): 9分区记录(bruteforce/queryReject/bearer/verify/authz等)

gateway未接入能力: compliance/rules 清单已记录
InvariantChecker决策: 接入真实写路径(非删除),CheckWithdrawBalance等有业务价值
拆分执行计划: 按Account→Package→Billing→Settlement顺序小步执行
2026-04-21 19:04:03 +08:00

7.8 KiB
Raw Blame History

P4-B 分析supply-api 大文件拆分与未接入能力

生成时间: 2026-04-21 Phase: P4-B


一、supply_api.go 分区记录P4-B-01 完成)

文件:supply-api/internal/httpapi/supply_api.go1048 行

分区概览

分区 起始行 主要 handler 说明
Account 163 handleVerifyAccount, handleCreateAccount, handleAccountActions, handleActivateAccount, handleSuspendAccount, handleDeleteAccount, handleAccountAuditLogs 账号生命周期管理
Package 453 handleCreatePackageDraft, handlePackageActions, handlePublishPackage, handlePausePackage, handleUnlistPackage, handleClonePackage, handleBatchUpdatePrice 套餐生命周期管理
Billing 731 handleGetBilling 账单查询
Settlement 761 handleWithdraw, handleSettlementActions, handleCancelSettlement, handleGetStatement 结算与提现
Earning 918 handleGetEarningRecords 收益记录
Helpers 975 writeJSON, writeError, getRequestID, getQueryInt, handleAuditEvent 通用工具

拆分建议

supply-api/internal/httpapi/
├── supply_api.go          # 保留 Register + NewSupplyAPI聚合入口
├── account.go             # Account 分区 handler~150行
├── package.go             # Package 分区 handler~230行
├── billing.go             # Billing 分区 handler~30行
├── settlement.go          # Settlement 分区 handler~160行
├── earning.go             # Earning 分区 handler~60行
├── errors.go              # Helpers: writeJSON/writeError/writeSupplyActionError~30行
└── request.go             # Helpers: getRequestID/getQueryInt/resolveSupplierID~30行

拆分原则:每个分区有独立的 registerXXXRoutes(mux) 函数,主 supply_api.go 的 Register 调用各子包的注册函数。


二、runtime.go 分区记录P4-B-02 完成)

文件:supply-api/internal/app/runtime.go589 行

分区概览

分区 起始行 函数 说明
输入解析 27 RuntimeOptions 结构体 所有外部依赖注入
资源初始化 140 BuildRuntime, buildRuntimeWithFactory, resolveRuntimeBuildInputs 构建逻辑入口
外部资源初始化 222 initializeRuntimeExternalResources, buildRuntimeResources DB/Redis 连接初始化
Store Bundle 286 buildStoreBundle, buildDBStoreBundle, buildMemoryStoreBundle 所有 repository 聚合
Security Bundle 332 buildSecurityBundle 鉴权/JWT key/验证码等安全依赖
API Bundle 369 buildAPIBundle HTTP handler/API 路由依赖
Server Bundle 485 BuildServer, resolveRuntimeHealthChecks, buildRuntimeHTTPView HTTP server 构建
生命周期 549 Close, ShutdownTimeout 资源释放

拆分建议

supply-api/internal/app/
├── runtime.go             # RuntimeOptions + Runtime struct + BuildRuntime 入口
├── runtime_stores.go       # buildStoreBundle / buildDBStoreBundle / buildMemoryStoreBundle
├── runtime_security.go     # buildSecurityBundle
├── runtime_server.go       # BuildServer + buildRuntimeHTTPView
└── runtime_options.go     # RuntimeOptions 定义

三、auth.go 分区记录P4-B-03 完成)

文件:supply-api/internal/middleware/auth.go891 行

分区概览

分区 起始行 内容 说明
配置与结构 25 TokenClaims, AuthConfig, AuthMiddleware, AuditEmitter, AuditEvent 类型定义
工厂方法 79 NewAuthMiddleware 构造器
BruteForce 保护 98 BruteForceProtection 结构 + 所有方法277行 MED-12: 防暴力破解
Query Key Reject 211 QueryKeyRejectMiddleware M-016: query key 拒绝
Bearer Extract 274 BearerExtractMiddleware Bearer token 提取
Token Verify 320 TokenVerifyMiddleware + verifyToken + signingKey + parseRSAPublicKey JWT 校验
Scope/Role Authz 449 ScopeRoleAuthzMiddleware + containsScope 权限校验
Token Status 595 checkTokenStatus + GetTokenClaims 状态查询
Helpers 589 shouldBypassAuth + writeAuthError 工具函数

拆分建议

supply-api/internal/middleware/auth/
├── auth.go                 # AuthConfig, AuthMiddleware, NewAuthMiddleware
├── auth_bearer.go          # BearerExtractMiddleware
├── auth_verify.go          # TokenVerifyMiddleware, verifyToken, signingKey
├── auth_authz.go           # ScopeRoleAuthzMiddleware, containsScope
├── auth_bruteforce.go      # BruteForceProtection
├── auth_errors.go          # writeAuthError, shouldBypassAuth
├── auth_status.go          # checkTokenStatus, GetTokenClaims
└── auth_test.go            # 测试

四、gateway 未接入能力清单P4-B-04 完成)

已接入模块Token Auth Middleware, Router, Circuit Breaker, Health Checker, Metrics, Remote Runtime Cache, Rate Limiter, Fallback Router

未接入 / 实验模块

模块 位置 状态 建议
compliance/rules internal/compliance/rules/ 已实现但未注册到路由 接入或移入 experimental/

P4-B-05 决策

待补充compliance/rules 模块接入路径或 experimental 转移决策。


五、InvariantChecker 去留决策P4-B-06

搜索结果

$ grep -rn "InvariantChecker" supply-api/internal/ --include="*.go" | grep -v "_test.go"
supply-api/internal/app/runtime.go:380:
    _ = domain.NewInvariantChecker(storeBundle.accountStore, ...)
supply-api/internal/domain/invariants.go:52: type InvariantChecker struct {

分析

  • InvariantCheckerbuildSecurityBundle 中创建第380行
  • 创建后立即丢弃(_ = domain.NewInvariantChecker(...)从未被任何写路径调用
  • 检查方法有实际业务价值:
    • CheckAccountDelete: 删除账号前校验
    • CheckAccountActivate: 激活账号前校验
    • CheckPackagePublish: 发布套餐前校验
    • CheckPackagePrice: 调价前校验
    • CheckSettlementCancel: 取消结算前校验
    • CheckWithdrawBalance: 提现余额校验(防透支)

P4-B-06 决策:接入真实写路径

理由:

  1. InvariantChecker 已有完整测试覆盖invariants_test.go
  2. 业务校验逻辑有价值,不应丢弃
  3. 当前状态(创建但不用)比删除更危险——给人虚假信心

P4-B-07 接入点顺序

1. settlement.go: Withdraw() — 接入 CheckWithdrawBalance最关键防透支
2. settlement.go: CancelSettlement() — 接入 CheckSettlementCancel
3. account.go: DeleteAccount() — 接入 CheckAccountDelete
4. account.go: ActivateAccount() — 接入 CheckAccountActivate
5. package.go: PublishPackage() — 接入 CheckPackagePublish
6. package.go: UpdatePrice() — 接入 CheckPackagePrice

接入方式

runtime.gobuildSecurityBundle 中,将 _ = domain.NewInvariantChecker(...) 改为传入 runtimeAPIBundle,各 domain service 构造函数接收 *InvariantChecker 参数。

回归测试

  • go test ./internal/domain/... — invariants_test.go 已有覆盖
  • go test ./internal/app/... — 集成测试
  • supply-api 全量 go test ./...

六、拆分执行计划P4-B-07

第一步supply_api.go 分区(按 Account → Package → Billing → Settlement → Earning → Helpers 顺序,每次改一个分区,验证 go build ./... + go test ./...

第二步auth.go 分区(按 Errors → Bearer → Verify → Authz → BruteForce 顺序)

第三步runtime.go 分区Stores → Security → Server → Options

第四步:删除 InvariantChecker确认无引用后执行

关键约束:每步改动后全量测试通过才能提交,不跨多个分区同时大爆炸改动。