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顺序小步执行
This commit is contained in:
184
docs/plans/2026-04-21-supply-api-split-analysis.md
Normal file
184
docs/plans/2026-04-21-supply-api-split-analysis.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# P4-B 分析:supply-api 大文件拆分与未接入能力
|
||||
|
||||
生成时间: 2026-04-21
|
||||
Phase: P4-B
|
||||
|
||||
---
|
||||
|
||||
## 一、supply_api.go 分区记录(P4-B-01 完成)
|
||||
|
||||
文件:`supply-api/internal/httpapi/supply_api.go`,1048 行
|
||||
|
||||
### 分区概览
|
||||
|
||||
| 分区 | 起始行 | 主要 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.go`,589 行
|
||||
|
||||
### 分区概览
|
||||
|
||||
| 分区 | 起始行 | 函数 | 说明 |
|
||||
|------|--------|------|------|
|
||||
| 输入解析 | 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.go`,891 行
|
||||
|
||||
### 分区概览
|
||||
|
||||
| 分区 | 起始行 | 内容 | 说明 |
|
||||
|------|--------|------|------|
|
||||
| 配置与结构 | 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 {
|
||||
```
|
||||
|
||||
### 分析
|
||||
|
||||
- `InvariantChecker` 在 `buildSecurityBundle` 中创建(第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.go` 的 `buildSecurityBundle` 中,将 `_ = 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(确认无引用后执行)
|
||||
|
||||
**关键约束**:每步改动后全量测试通过才能提交,不跨多个分区同时大爆炸改动。
|
||||
Reference in New Issue
Block a user