Files
junhong_cmp_fiber/.claude/skills/api-routing/SKILL.md
huang a924e63e68
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 4m42s
feat: 实现物联网卡独立管理和批量导入功能
新增物联网卡独立管理模块,支持单卡查询、批量导入和状态管理。主要变更包括:

功能特性:
- 新增物联网卡 CRUD 接口(查询、分页列表、删除)
- 支持 CSV/Excel 批量导入物联网卡
- 实现异步导入任务处理和进度跟踪
- 新增 ICCID 号码格式校验器(支持 Luhn 算法)
- 新增 CSV 文件解析工具(支持编码检测和错误处理)

数据库变更:
- 移除 iot_card 和 device 表的 owner_id/owner_type 字段
- 新增 iot_card_import_task 导入任务表
- 为导入任务添加运营商类型字段

测试覆盖:
- 新增 IoT 卡 Store 层单元测试
- 新增 IoT 卡导入任务单元测试
- 新增 IoT 卡集成测试(包含导入流程测试)
- 新增 CSV 工具和 ICCID 校验器测试

文档更新:
- 更新 OpenAPI 文档(新增 7 个 IoT 卡接口)
- 归档 OpenSpec 变更提案
- 更新 API 文档规范和生成器指南

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-24 11:03:43 +08:00

4.6 KiB
Raw Blame History

name, description
name description
api-routing API 路由注册规范。注册新 API 路由、添加新 Handler 时使用。包含 Register() 函数用法、RouteSpec 必填项、文档生成器更新等规范。

API 路由注册规范

所有 HTTP 接口必须使用统一的 Register() 函数注册,以自动加入 OpenAPI 文档生成。

触发条件

在以下情况下必须遵守本规范:

  • 注册新的 API 路由
  • 修改现有路由配置
  • 添加新的 Handler必须同步更新文档生成器

新增 Handler 检查清单(⚠️ 最容易遗漏)

新增 Handler 时,必须完成以下 4 个步骤,否则接口不会出现在 OpenAPI 文档中:

步骤 文件 操作
1 internal/bootstrap/types.go 添加 Handler 字段
2 internal/bootstrap/handlers.go 实例化 Handler
3 internal/routes/admin.go 调用路由注册函数
4 cmd/api/docs.go + cmd/gendocs/main.go 添加到文档生成器

步骤 4 详解(最常遗漏!)

// cmd/api/docs.go 和 cmd/gendocs/main.go 都要改!
handlers := &bootstrap.Handlers{
    // ... 现有 Handler
    IotCard:       admin.NewIotCardHandler(nil),       // 添加
    IotCardImport: admin.NewIotCardImportHandler(nil), // 添加
}

核心规则

必须使用 Register() 函数

// ✅ 正确
Register(router, doc, basePath, "POST", "/shops", handler.Create, RouteSpec{
    Summary: "创建店铺",
    Tags:    []string{"店铺管理"},
    Input:   new(model.CreateShopRequest),
    Output:  new(model.ShopResponse),
    Auth:    true,
})

// ❌ 错误:直接注册不会生成文档
router.Post("/shops", handler.Create)

RouteSpec 必填项

字段 类型 说明 示例
Summary string 操作说明(中文,简短) "创建店铺"
Tags []string 分类标签(用于文档分组) []string{"店铺管理"}
Input interface{} 请求 DTOnil 表示无参数) new(model.CreateShopRequest)
Output interface{} 响应 DTOnil 表示无返回) new(model.ShopResponse)
Auth bool 是否需要认证 true

常见路由模式

CRUD 路由组

// 列表查询
Register(router, doc, basePath, "GET", "/shops", handler.List, RouteSpec{
    Summary: "获取店铺列表",
    Tags:    []string{"店铺管理"},
    Input:   new(model.ListShopRequest),
    Output:  new(model.ShopListResponse),
    Auth:    true,
})

// 详情查询
Register(router, doc, basePath, "GET", "/shops/:id", handler.Get, RouteSpec{
    Summary: "获取店铺详情",
    Tags:    []string{"店铺管理"},
    Input:   new(model.IDReq),
    Output:  new(model.ShopResponse),
    Auth:    true,
})

// 创建
Register(router, doc, basePath, "POST", "/shops", handler.Create, RouteSpec{
    Summary: "创建店铺",
    Tags:    []string{"店铺管理"},
    Input:   new(model.CreateShopRequest),
    Output:  new(model.ShopResponse),
    Auth:    true,
})

// 更新
Register(router, doc, basePath, "PUT", "/shops/:id", handler.Update, RouteSpec{
    Summary: "更新店铺",
    Tags:    []string{"店铺管理"},
    Input:   new(model.UpdateShopRequest),
    Output:  new(model.ShopResponse),
    Auth:    true,
})

// 删除
Register(router, doc, basePath, "DELETE", "/shops/:id", handler.Delete, RouteSpec{
    Summary: "删除店铺",
    Tags:    []string{"店铺管理"},
    Input:   new(model.IDReq),
    Output:  nil,
    Auth:    true,
})

无认证路由

// 公开接口(如健康检查)
Register(router, doc, basePath, "GET", "/health", handler.Health, RouteSpec{
    Summary: "健康检查",
    Tags:    []string{"系统"},
    Input:   nil,
    Output:  new(model.HealthResponse),
    Auth:    false,
})

AI 助手检查清单

注册路由时

  1. 是否使用 Register() 函数而非直接注册
  2. Summary 是否使用中文简短描述
  3. Tags 是否正确分组
  4. InputOutput 是否指向正确的 DTO
  5. Auth 是否根据业务需求正确设置

新增 Handler 时(⚠️ 必查)

  1. internal/bootstrap/types.go 添加了 Handler 字段
  2. internal/bootstrap/handlers.go 实例化了 Handler
  3. internal/routes/admin.go 调用了路由注册函数
  4. cmd/api/docs.go 添加了 Handler
  5. cmd/gendocs/main.go 添加了 Handler
  6. 运行 go run cmd/gendocs/main.go 验证文档生成
  7. 运行 grep "接口路径" docs/admin-openapi.yaml 确认接口存在

完整指南: 参见 docs/api-documentation-guide.md