Files
huang 409a68d60b
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m45s
feat: OpenAPI 契约对齐与框架优化
主要变更:
1. OpenAPI 文档契约对齐
   - 统一错误响应字段名为 msg(非 message)
   - 规范 envelope 响应结构(code, msg, data, timestamp)
   - 个人客户路由纳入文档体系(使用 Register 机制)
   - 新增 BuildDocHandlers() 统一管理 handler 构造
   - 确保文档生成的幂等性

2. Service 层错误处理统一
   - 全面替换 fmt.Errorf 为 errors.New/Wrap
   - 统一错误码使用规范
   - Handler 层参数校验不泄露底层细节
   - 新增错误码验证集成测试

3. 代码质量提升
   - 删除未使用的 Task handler 和路由
   - 新增代码规范检查脚本(check-service-errors.sh)
   - 新增注释路径一致性检查(check-comment-paths.sh)
   - 更新 API 文档生成指南

4. OpenSpec 归档
   - 归档 openapi-contract-alignment 变更(63 tasks)
   - 归档 service-error-unify-core 变更
   - 归档 service-error-unify-support 变更
   - 归档 code-cleanup-docs-update 变更
   - 归档 handler-validation-security 变更
   - 同步 delta specs 到主规范文件

影响范围:
- pkg/openapi: 新增 handlers.go,优化 generator.go
- internal/service/*: 48 个 service 文件错误处理统一
- internal/handler/admin: 优化参数校验错误提示
- internal/routes: 个人客户路由改造,删除 task 路由
- scripts: 新增 3 个代码检查脚本
- docs: 更新 OpenAPI 文档(15750+ 行)
- openspec/specs: 同步 3 个主规范文件

破坏性变更:无
向后兼容:是
2026-01-30 11:40:36 +08:00

317 lines
8.0 KiB
Markdown
Raw Permalink 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-01-29
**完成进度**9/58 任务15.5%
---
## ✅ 已完成部分
### 阶段 1限流覆盖真实 API 路由组3/3 完成)
**影响文件**
- `cmd/api/main.go`
- `docs/rate-limiting.md`
**变更内容**
1. 调整限流中间件挂载位置,从 `/api/v1` 改为真实业务路由组
2. 限流覆盖范围:`/api/admin``/api/h5``/api/c/v1`
3. 明确排除:`/api/callback`(回调)、`/health``/ready`(健康检查)
4. 更新文档说明限流生效范围
**测试建议**
```bash
# 启用限流配置
export JUNHONG_MIDDLEWARE_ENABLE_RATE_LIMITER=true
export JUNHONG_MIDDLEWARE_RATE_LIMITER_MAX=5
export JUNHONG_MIDDLEWARE_RATE_LIMITER_EXPIRATION=1m
# 测试限流生效
for i in {1..10}; do curl http://localhost:3000/api/admin/login; done
# 验证排除路径不受限流
for i in {1..10}; do curl http://localhost:3000/health; done
```
---
### 阶段 2短信验证码未配置不崩溃3/3 完成)
**影响文件**
- `internal/service/verification/service.go`
**变更内容**
1. `SendCode` 方法增加 smsClient 可用性检查
2. 未配置短信服务时返回 `errors.New(CodeServiceUnavailable)` (HTTP 503)
3. 统一验证码链路所有错误返回为结构化错误(`errors.New/Wrap`
**修复的错误点**
- 验证码发送频率限制错误:`CodeTooManyRequests`
- 验证码生成失败:`CodeInternalError`
- 短信发送失败:`CodeInternalError`
- Redis 存储失败:`CodeInternalError`
- 验证码不存在或过期:`CodeInvalidParam`
- 验证码错误:`CodeInvalidParam`
**测试场景**
- ✅ 短信服务未配置时调用发送验证码 → 返回 503
- ✅ 验证码发送过于频繁 → 返回 429
- ✅ 验证码错误 → 返回 400
- ✅ 验证码过期 → 返回 400
---
### 阶段 3Service 层错误语义统一部分完成4/27 文件)
**已完成文件**27 处错误修复):
1. `verification/service.go` - 10 处
2. `personal_customer/service.go` - 11 处
3. `auth/service.go` - 4 处
4. `device_import/service.go` - 2 处
**修复模式**
```go
// ❌ 修复前
return fmt.Errorf("创建用户失败: %w", err)
// ✅ 修复后(系统错误)
return errors.Wrap(errors.CodeInternalError, err, "创建用户失败")
// ✅ 修复后(业务错误)
return errors.New(errors.CodeInvalidParam, "验证码错误")
```
**待完成文件**24 个文件,约 224 处):
- `iot_card_import/service.go` (2)
- `commission_stats/service.go` (3)
- `shop_package_batch_pricing/service.go` (3)
- `commission_withdrawal_setting/service.go` (4)
- `sync/service.go` (4)
- `customer_account/service.go` (6)
- `email/service.go` (6)
- `shop_package_batch_allocation/service.go` (6)
- `commission_withdrawal/service.go` (7)
- `enterprise/service.go` (7)
- `shop_commission/service.go` (7)
- `shop/service.go` (8)
- `carrier/service.go` (9)
- `enterprise_card/service.go` (9)
- `my_commission/service.go` (9)
- `package_series/service.go` (9)
- `permission/service.go` (10)
- `shop_account/service.go` (11)
- `package/service.go` (14)
- `role/service.go` (15)
- `shop_package_allocation/service.go` (17)
- `enterprise_device/service.go` (20)
- `account/service.go` (24)
- `shop_series_allocation/service.go` (24)
---
## ⏸️ 待完成部分49/58 任务)
### 阶段 3 剩余Service 层错误语义统一
**工作量估算**:约 224 处 `fmt.Errorf` 需要逐一分析并替换
- 需要区分业务错误4xx和系统错误5xx
- 需要选择合适的错误码
- 需要补充回归测试
**建议执行方式**
- 按文件数量从少到多处理
- 优先处理核心业务模块order、package、commission
- 每完成 5-10 个文件运行一次测试
---
### 阶段 4参数校验错误不泄露内部细节
**影响范围**`internal/handler/**` 所有 Handler 文件(约 30-40 个)
**需要修复的模式**
```go
// ❌ 修复前
if err := c.BodyParser(&req); err != nil {
return response.Error(c, 400, errors.CodeInvalidParam, "参数解析失败: "+err.Error())
}
// ✅ 修复后
if err := c.BodyParser(&req); err != nil {
logger.GetAppLogger().Warn("参数解析失败", zap.Error(err))
return response.Error(c, 400, errors.CodeInvalidParam, "参数解析失败")
}
```
---
### 阶段 5OpenAPI 响应 envelope 对齐
**影响文件**
- `pkg/openapi/generator.go`
**需要修复**
- 错误响应字段名:`message``msg`
- 成功响应体现 envelope`{code, data, msg, timestamp}`
---
### 阶段 6OpenAPI handlers 清单完整
**影响文件**
- `cmd/api/docs.go`
- `cmd/gendocs/main.go`
- `internal/bootstrap/handlers.go`
**需要补齐的 handlers**
- PersonalCustomer
- ShopPackageBatchAllocation
- ShopPackageBatchPricing
---
### 阶段 7个人客户路由纳入文档体系
**影响文件**
- `internal/routes/personal.go`
- `internal/routes/routes.go`
---
### 阶段 8移除任务模块占位代码
**影响文件**
- `internal/routes/task.go`
- `internal/routes/routes.go`
- `internal/handler/admin/task.go`
---
### 阶段 9-11规范文档更新和回归验证
---
## 建议后续工作拆分
### 提案 AService 层错误语义统一(核心模块)
**范围**
- 已完成 4 个关键认证文件
- 继续完成 10 个核心业务模块order、package、commission、shop、enterprise
**文件数**:约 10 个60-80 处错误
---
### 提案 BService 层错误语义统一(非核心模块)
**范围**
- 剩余 14 个支持模块
**文件数**:约 14 个140-150 处错误
---
### 提案 CHandler 层参数校验安全加固
**范围**
- 所有 Handler 参数校验错误处理
- 统一为不泄露内部细节
---
### 提案 DOpenAPI 文档契约对齐
**范围**
- 响应 envelope 对齐
- handlers 清单完整
- 个人客户路由纳入文档
---
### 提案 E代码清理和规范文档更新
**范围**
- 移除任务模块占位
- 清理注释一致性
- 更新规范文档
- 回归验证
---
## 技术债务记录
### 已解决
- ✅ 限流不覆盖真实业务路由
- ✅ 短信服务未配置时崩溃
- ✅ 核心认证链路错误语义不一致
### 待解决
- ⏸️ 224 处 Service 层 `fmt.Errorf` 待替换
- ⏸️ Handler 层参数校验错误泄露内部细节
- ⏸️ OpenAPI 文档与真实响应不一致
- ⏸️ 任务模块占位代码存在鉴权风险
---
## 验证清单
### 已完成部分验证
**限流功能**
```bash
# 1. 检查限流配置
grep -A 10 "enable_rate_limiter" pkg/config/defaults/config.yaml
# 2. 验证限流生效
source .env.local && go run cmd/api/main.go &
for i in {1..10}; do curl http://localhost:3000/api/admin/login; done
# 3. 验证健康检查不受限流
for i in {1..10}; do curl http://localhost:3000/health; done
```
**验证码服务**
```bash
# 1. 未配置短信服务测试
unset JUNHONG_SMS_ENABLED
go test -v ./internal/service/verification/... -run TestSendCode
# 2. 验证错误码正确性
# 预期CodeServiceUnavailable (2004) → HTTP 503
```
**认证服务**
```bash
# 运行认证相关测试
source .env.local && go test -v ./internal/service/auth/...
source .env.local && go test -v ./internal/service/personal_customer/...
```
### 待验证部分
**编译检查**
```bash
go build -o /tmp/test_build ./cmd/api
go build -o /tmp/test_build ./cmd/worker
```
**全量测试**(待完成后执行):
```bash
source .env.local && go test ./...
```
---
## 归档原因
由于 Service 层错误语义统一工作量巨大224 处待处理),需要逐一分析业务语义并选择合适的错误码,继续在单一变更中完成会导致:
1. **变更风险过高**:单次变更影响 27 个 Service 文件
2. **测试覆盖不足**:无法为每个模块补充充分的回归测试
3. **Code Review 困难**:单次 PR 包含 200+ 处修改难以审查
因此决定将已完成的高优先级部分(限流 + 验证码 + 核心认证)归档,剩余工作拆分为独立提案逐步完成。