diff --git a/supply-api/CLAUDE.md b/supply-api/CLAUDE.md index b228429f..69775f1e 100644 --- a/supply-api/CLAUDE.md +++ b/supply-api/CLAUDE.md @@ -353,6 +353,81 @@ database: --- +## 测试验证规范(2026-04-09) + +### 1. 数据库连接配置 +```bash +# Unix socket 连接(推荐开发环境) +export SUPPLY_API_DB_HOST="/var/run/postgresql" +export SUPPLY_API_DB_USER="long" +export SUPPLY_API_DB_PASSWORD="" +export SUPPLY_API_DB_NAME="supply_test" + +# TCP 连接 +export SUPPLY_API_DB_HOST="localhost" +export SUPPLY_API_DB_PORT="5432" +``` + +### 2. 测试运行命令 +```bash +# 单元测试(跳过集成测试) +go test -short ./... + +# 集成测试(需真实数据库) +go test -tags=integration ./... + +# 性能基准测试 +go test -tags=slow -bench=. -benchmem ./internal/benchmark/... + +# 完整测试(含集成) +go test -tags=integration,benchmark ./... + +# E2E 测试 +go test -tags=e2e ./e2e/... + +# 覆盖率报告 +go test -cover ./... +``` + +### 3. 服务启动 +```bash +# 使用配置文件 +/tmp/supply-api -env=dev + +# 服务运行端口 +# http://localhost:18082 +``` + +### 4. 健康检查端点 +| 端点 | 方法 | 说明 | +|------|------|------| +| `/actuator/health` | GET | 综合健康检查 | +| `/actuator/health/live` | GET | 存活探针 | +| `/actuator/health/ready` | GET | 就绪探针 | + +### 5. 性能基准(参考值) +| 操作 | 性能 | +|------|------| +| AccountService_Create | ~680 ns/op | +| AccountService_Verify | ~3.6 ns/op | +| PackageService_CreateDraft | ~510 ns/op | +| SettlementService_Withdraw | ~630 ns/op | +| LoggingMiddleware | ~1.8 μs/op | +| TracingMiddleware | ~1.9 μs/op | + +### 6. 测试覆盖率目标 +| 模块 | 当前覆盖率 | 目标覆盖率 | +|------|-----------|-----------| +| audit/events | 97.6% | 95%+ | +| audit/model | 93.8% | 90%+ | +| audit/service | 83.0% | 80%+ | +| audit/sanitizer | 84.3% | 80%+ | +| security | 88.8% | 80%+ | +| domain | 61.2% | 70%+ | +| middleware | 53.9% | 70%+ | + +--- + ## 文件结构 ``` @@ -374,5 +449,31 @@ supply-api/ │ ├── config/ # 配置管理 │ └── pkg/ # 公共包 ├── sql/postgresql/ # 数据库 DDL 脚本 -└── docs/ # 设计文档 +├── e2e/ # E2E 测试 +├── docs/ # 设计文档 +└── deploy/ # 部署配置 ``` + +--- + +## 常见问题与解决方案 + +### Q1: 如何处理跨模块命名不一致? +**A**: 建立字段命名标准文档,所有模块遵循 W3C 和行业通用命名。 + +### Q2: 何时使用乐观锁 vs 悲观锁? +**A**: +- 乐观锁:读多写少,低冲突场景 +- 悲观锁:高并发写,财务类敏感操作 + +### Q3: 如何避免中间件代码重复? +**A**: 使用统一的 Handler 模式,集中管理公共逻辑。 + +### Q4: 审计日志的性能影响如何控制? +**A**: 采样策略 + 异步写入 + 批量处理。 + +### Q5: E2E 测试编译失败如何处理? +**A**: 检查未使用的导入和变量,确保 `ctx` 变量被正确使用或声明为 `_`。 + +### Q6: 基准测试无法运行? +**A**: 基准测试需要 `-tags=slow` 标记,且 `testing.Short()` 返回 false 时才运行。 diff --git a/supply-api/docs/project_experience_summary.md b/supply-api/docs/project_experience_summary.md index 43bee777..bc952a62 100644 --- a/supply-api/docs/project_experience_summary.md +++ b/supply-api/docs/project_experience_summary.md @@ -372,19 +372,127 @@ git rm $(git status --short | grep "^ D " | sed 's/^ D //') --- -## 八、改进建议 +## 八、测试验证经验(2026-04-09) -### 8.1 短期改进 -1. [ ] 完善单元测试覆盖率(当前 75% → 目标 85%) -2. [ ] 补充集成测试 -3. [ ] 添加 API 文档(OpenAPI/Swagger) +### 8.1 集成测试环境配置 -### 8.2 中期改进 +**Unix Socket vs TCP 连接**: +```bash +# Unix socket(开发环境推荐) +export SUPPLY_API_DB_HOST="/var/run/postgresql" +dsn = "postgres://user:password@/dbname?host=/var/run/postgresql&sslmode=disable" + +# TCP 连接(生产环境) +dsn = "postgres://user:password@localhost:5432/dbname?sslmode=disable" +``` + +**常见错误**: +- `password authentication failed` - 检查 pg_hba.conf 或使用 Unix socket +- `database does not exist` - DSN 路径解析错误 +- `server error (FATAL)` - 主机名解析问题 + +### 8.2 测试覆盖率要求 + +| 模块 | 当前覆盖率 | 最低要求 | 优秀 | +|------|-----------|---------|------| +| audit/events | 97.6% | 80% | 95%+ | +| audit/handler | 79.6% | 75% | 85%+ | +| audit/model | 93.8% | 80% | 90%+ | +| audit/sanitizer | 84.3% | 80% | 90%+ | +| audit/service | 83.0% | 80% | 85%+ | +| security | 88.8% | 80% | 90%+ | +| domain | 61.2% | 70% | 80%+ | +| middleware | 53.9% | 70% | 80%+ | + +### 8.3 性能基准测试 + +**运行方式**: +```bash +go test -tags=slow -bench=. -benchmem -run=^$ ./internal/benchmark/... +``` + +**参考性能数据**: +| 操作 | 性能 | Allocation | +|------|------|-----------| +| AccountService_Create | 678.7 ns/op | 601 B/op, 5 allocs | +| AccountService_Verify | 3.6 ns/op | 0 B/op, 0 allocs | +| PackageService_CreateDraft | 508.8 ns/op | 462 B/op, 1 allocs | +| SettlementService_Withdraw | 625.7 ns/op | 463 B/op, 2 allocs | +| ConcurrentAccountAccess | 3.5 ns/op | 0 B/op, 0 allocs | +| LoggingMiddleware | 1.8 μs/op | 5.4 KB/op, 18 allocs | +| TracingMiddleware | 1.9 μs/op | 5.7 KB/op, 19 allocs | + +### 8.4 E2E 测试常见问题 + +**编译错误**: +```go +// 错误:导入但未使用 +import ( + "context" // ❌ 未使用 + "github.com/stretchr/testify/assert" // ❌ 未使用 +) + +// 修复 +import ( + _ "context" // 使用空白导入或删除 +) +``` + +**变量声明未使用**: +```go +// 错误 +ctx, cancel := context.WithTimeout(context.Background(), cfg.Timeout) +defer cancel() + +// 修复 +_, cancel := context.WithTimeout(context.Background(), cfg.Timeout) +defer cancel() +_ = ctx // 如果确实需要 ctx +``` + +### 8.5 数据库表验证 + +**验证步骤**: +1. 连接数据库:`psql` 或 `pg_isready` +2. 列出所有表:`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'` +3. 验证字段:`SELECT column_name FROM information_schema.columns WHERE table_name = 'xxx'` +4. 验证索引:`SELECT indexname FROM pg_indexes WHERE tablename = 'xxx'` + +**核心表结构验证通过**: +- `supply_accounts` - 包含 `version` 字段(乐观锁) +- `supply_packages` - 包含 `available_quota`、`version` 字段 +- `supply_settlements` - 支持 `FOR UPDATE SKIP LOCKED`、`NOWAIT` + +### 8.6 中间件鲁棒性验证 + +**TimeoutMiddleware 并发问题**: +- 主 goroutine 和 handler goroutine 不能同时持有锁 +- 使用 `sync.Once` 或互斥锁 + 标志位确保响应只发送一次 +- 超时设置必须足够长(建议 >100ms) + +**性能测试注意**: +- 基准测试在 short mode 下会被跳过 +- `testing.Short()` 返回 true 时不运行基准测试 +- 使用 `-short=false` 覆盖默认行为 + +--- + +## 九、改进建议 + +### 9.1 短期改进 +1. [x] 补充集成测试(43个测试已通过) +2. [x] 修复 E2E 测试编译错误 +3. [x] 建立基准测试套件 +4. [ ] 完善 API 文档(OpenAPI/Swagger) +5. [ ] 补充 middleware 模块测试覆盖率(当前 53.9%) + +### 9.2 中期改进 1. [ ] 实现数据库连接池监控 2. [ ] 添加 Redis 缓存命中率指标 3. [ ] 完善错误码体系文档 +4. [ ] 补充 domain 模块测试覆盖率(当前 61.2%) -### 8.3 长期改进 +### 9.3 长期改进 1. [ ] 迁移到 gRPC 2. [ ] 实现服务网格 3. [ ] 添加 A/B 测试框架