- 合并 customer_account 和 shop_account 路由到统一的 account 接口 - 新增统一认证接口 (auth handler) - 实现越权防护中间件和权限检查工具函数 - 新增操作审计日志模型和服务 - 更新数据库迁移 (版本 39: account_operation_log 表) - 补充集成测试覆盖权限检查和审计日志场景
13 KiB
新增 Gateway 后台管理接口
TL;DR
Quick Summary: 将 Gateway 层已封装的 14 个第三方能力(卡状态查询、流量查询、停复机、设备控制等)暴露为后台管理 API,供平台用户和代理商使用。
Deliverables:
- 6 个卡相关 Gateway 接口
- 7 个设备相关 Gateway 接口
- 对应的路由注册和 OpenAPI 文档
Estimated Effort: Medium Parallel Execution: YES - 2 waves Critical Path: 依赖注入 → 卡接口 → 设备接口
Context
Original Request
为 Gateway 层已封装的第三方能力提供后台管理接口,让前端可以对接卡和设备的实时查询、操作功能。
Interview Summary
Key Discussions:
- 接口归属:集成到现有 iot-cards 和 devices 路径下
- 业务逻辑:简单透传,仅做权限校验
- 权限控制:平台 + 代理商(自动数据权限过滤)
- ICCID = CardNo,IMEI = DeviceID,直接透传
Research Findings:
- Gateway Client 已完整实现(
internal/gateway/flow_card.go,internal/gateway/device.go) - 现有 Handler 结构清晰,可直接扩展
- 路由注册使用
Register()函数,自动生成 OpenAPI 文档
Work Objectives
Core Objective
将 Gateway 层封装的 13 个第三方能力暴露为后台管理 RESTful API。
Concrete Deliverables
internal/handler/admin/iot_card.go扩展 6 个方法internal/handler/admin/device.go扩展 7 个方法internal/routes/iot_card.go注册 6 个路由internal/routes/device.go注册 7 个路由internal/bootstrap/handlers.go注入 Gateway Client 依赖- 13 个接口的集成测试
Definition of Done
- 所有 13 个接口可通过 HTTP 调用
- 代理商只能操作自己店铺的卡/设备(权限校验生效)
- OpenAPI 文档自动生成
- 集成测试覆盖所有接口
Must Have
- 卡状态查询、流量查询、实名查询、停机、复机接口
- 设备信息查询、卡槽查询、限速设置、WiFi 设置、切卡、重启、恢复出厂接口
- 权限校验(先查数据库确认归属)
Must NOT Have (Guardrails)
- 不添加额外业务逻辑(简单透传)
- 不修改 Gateway 层代码
- 不添加异步任务处理(同步调用)
- 不添加缓存层
Verification Strategy
Test Decision
- Infrastructure exists: YES (go test)
- User wants tests: YES (集成测试)
- Framework: go test + testutils
Automated Verification
# 运行集成测试
source .env.local && go test -v ./tests/integration/... -run TestGateway
# 检查 OpenAPI 文档生成
go run cmd/gendocs/main.go && cat docs/openapi.yaml | grep gateway
Execution Strategy
Parallel Execution Waves
Wave 1 (Start Immediately):
├── Task 1: 修改 Bootstrap 注入 Gateway Client
└── Task 2: 创建 OpenSpec proposal.md(可选,文档记录)
Wave 2 (After Wave 1):
├── Task 3: 扩展 IotCardHandler(6个接口)
├── Task 4: 扩展 DeviceHandler(7个接口)
└── Task 5: 注册路由
Wave 3 (After Wave 2):
└── Task 6: 添加集成测试
Critical Path: Task 1 → Task 3/4 → Task 6
TODOs
-
1. 修改 Bootstrap 注入 Gateway Client 依赖
What to do:
- 修改
internal/bootstrap/handlers.go,为IotCardHandler和DeviceHandler注入gateway.Client - 修改 Handler 构造函数签名,接收
gateway.Client参数 - 同时注入
IotCardStore和DeviceStore用于权限校验
Must NOT do:
- 不修改 Gateway Client 本身
- 不修改其他不相关的 Handler
Recommended Agent Profile:
- Category:
quick - Skills: [
api-routing]
Parallelization:
- Can Run In Parallel: NO
- Blocks: Task 3, Task 4
- Blocked By: None
References:
internal/bootstrap/handlers.go- 现有 Handler 初始化模式internal/bootstrap/types.go- Handlers 结构体定义internal/gateway/client.go- Gateway Client 定义internal/handler/admin/iot_card.go- 现有 Handler 结构
Acceptance Criteria:
IotCardHandler构造函数接收gatewayClient *gateway.Client参数DeviceHandler构造函数接收gatewayClient *gateway.Client参数go build ./cmd/api编译通过
Commit: YES
- Message:
feat(bootstrap): 为 IotCardHandler 和 DeviceHandler 注入 Gateway Client - Files:
internal/bootstrap/handlers.go,internal/handler/admin/iot_card.go,internal/handler/admin/device.go
- 修改
-
2. 扩展 IotCardHandler 添加 6 个 Gateway 接口方法
What to do:
- 在
internal/handler/admin/iot_card.go中添加以下方法:GetGatewayStatus(c *fiber.Ctx) error- 查询卡实时状态GetGatewayFlow(c *fiber.Ctx) error- 查询流量使用GetGatewayRealname(c *fiber.Ctx) error- 查询实名状态GetRealnameLink(c *fiber.Ctx) error- 获取实名链接StopCard(c *fiber.Ctx) error- 停机StartCard(c *fiber.Ctx) error- 复机
- 每个方法先查数据库校验权限,再调用 Gateway
Must NOT do:
- 不添加额外业务逻辑
- 不修改现有方法
Recommended Agent Profile:
- Category:
quick - Skills: [
api-routing]
Parallelization:
- Can Run In Parallel: YES (with Task 3)
- Parallel Group: Wave 2
- Blocks: Task 5
- Blocked By: Task 1
References:
internal/handler/admin/iot_card.go- 现有 Handler 结构和模式internal/gateway/flow_card.go- Gateway 方法定义internal/gateway/models.go:CardStatusReq- 请求结构internal/store/postgres/iot_card_store.go:GetByICCID- 权限校验方法
Acceptance Criteria:
- 6 个新方法已添加
- 每个方法包含权限校验(调用
GetByICCID) - 使用
errors.New(errors.CodeNotFound, "卡不存在或无权限访问")处理权限错误 go build ./cmd/api编译通过
Commit: YES
- Message:
feat(handler): IotCardHandler 新增 6 个 Gateway 接口方法 - Files:
internal/handler/admin/iot_card.go
- 在
-
3. 扩展 DeviceHandler 添加 7 个 Gateway 接口方法
What to do:
- 在
internal/handler/admin/device.go中添加以下方法:GetGatewayInfo(c *fiber.Ctx) error- 查询设备信息GetGatewaySlots(c *fiber.Ctx) error- 查询卡槽信息SetSpeedLimit(c *fiber.Ctx) error- 设置限速SetWiFi(c *fiber.Ctx) error- 设置 WiFiSwitchCard(c *fiber.Ctx) error- 切换卡RebootDevice(c *fiber.Ctx) error- 重启设备ResetDevice(c *fiber.Ctx) error- 恢复出厂
- 每个方法先查数据库校验权限,再调用 Gateway
- 使用
c.Params("imei")获取 IMEI 参数
Must NOT do:
- 不添加额外业务逻辑
- 不修改现有方法
Recommended Agent Profile:
- Category:
quick - Skills: [
api-routing]
Parallelization:
- Can Run In Parallel: YES (with Task 2)
- Parallel Group: Wave 2
- Blocks: Task 5
- Blocked By: Task 1
References:
internal/handler/admin/device.go- 现有 Handler 结构和模式internal/gateway/device.go- Gateway 方法定义internal/gateway/models.go- 请求/响应结构(DeviceInfoReq, SpeedLimitReq, WiFiReq 等)internal/store/postgres/device_store.go:GetByDeviceNo- 权限校验方法
Acceptance Criteria:
- 7 个新方法已添加
- 每个方法包含权限校验(调用
GetByDeviceNo) go build ./cmd/api编译通过
Commit: YES
- Message:
feat(handler): DeviceHandler 新增 7 个 Gateway 接口方法 - Files:
internal/handler/admin/device.go
- 在
-
4. 注册卡 Gateway 路由(6个)
What to do:
- 在
internal/routes/iot_card.go的registerIotCardRoutes函数中添加:Register(cards, doc, groupPath, "GET", "/:iccid/gateway-status", h.GetGatewayStatus, RouteSpec{...}) Register(cards, doc, groupPath, "GET", "/:iccid/gateway-flow", h.GetGatewayFlow, RouteSpec{...}) Register(cards, doc, groupPath, "GET", "/:iccid/gateway-realname", h.GetGatewayRealname, RouteSpec{...}) Register(cards, doc, groupPath, "GET", "/:iccid/realname-link", h.GetRealnameLink, RouteSpec{...}) Register(cards, doc, groupPath, "POST", "/:iccid/stop", h.StopCard, RouteSpec{...}) Register(cards, doc, groupPath, "POST", "/:iccid/start", h.StartCard, RouteSpec{...}) - 使用
gateway.CardStatusResp等作为 Output 类型 - Tags 使用
["IoT卡管理"]
Must NOT do:
- 不修改现有路由
Recommended Agent Profile:
- Category:
quick - Skills: [
api-routing]
Parallelization:
- Can Run In Parallel: YES (with Task 5)
- Parallel Group: Wave 2 (after handlers)
- Blocks: Task 6
- Blocked By: Task 2
References:
internal/routes/iot_card.go- 现有路由注册模式internal/routes/registry.go:RouteSpec- 路由规格结构internal/gateway/models.go- 响应结构定义
Acceptance Criteria:
- 6 个新路由已注册
- RouteSpec 包含 Summary、Tags、Input、Output、Auth
go build ./cmd/api编译通过go run cmd/gendocs/main.go生成文档成功
Commit: YES
- Message:
feat(routes): 注册 6 个卡 Gateway 路由 - Files:
internal/routes/iot_card.go
- 在
-
5. 注册设备 Gateway 路由(7个)
What to do:
- 在
internal/routes/device.go的registerDeviceRoutes函数中添加:Register(devices, doc, groupPath, "GET", "/by-imei/:imei/gateway-info", h.GetGatewayInfo, RouteSpec{...}) Register(devices, doc, groupPath, "GET", "/by-imei/:imei/gateway-slots", h.GetGatewaySlots, RouteSpec{...}) Register(devices, doc, groupPath, "PUT", "/by-imei/:imei/speed-limit", h.SetSpeedLimit, RouteSpec{...}) Register(devices, doc, groupPath, "PUT", "/by-imei/:imei/wifi", h.SetWiFi, RouteSpec{...}) Register(devices, doc, groupPath, "POST", "/by-imei/:imei/switch-card", h.SwitchCard, RouteSpec{...}) Register(devices, doc, groupPath, "POST", "/by-imei/:imei/reboot", h.RebootDevice, RouteSpec{...}) Register(devices, doc, groupPath, "POST", "/by-imei/:imei/reset", h.ResetDevice, RouteSpec{...}) - Tags 使用
["设备管理"]
Must NOT do:
- 不修改现有路由
Recommended Agent Profile:
- Category:
quick - Skills: [
api-routing]
Parallelization:
- Can Run In Parallel: YES (with Task 4)
- Parallel Group: Wave 2 (after handlers)
- Blocks: Task 6
- Blocked By: Task 3
References:
internal/routes/device.go- 现有路由注册模式internal/routes/registry.go:RouteSpec- 路由规格结构internal/gateway/models.go- 请求/响应结构定义
Acceptance Criteria:
- 7 个新路由已注册
- RouteSpec 包含 Summary、Tags、Input、Output、Auth
go build ./cmd/api编译通过go run cmd/gendocs/main.go生成文档成功
Commit: YES
- Message:
feat(routes): 注册 7 个设备 Gateway 路由 - Files:
internal/routes/device.go
- 在
-
6. 添加集成测试
What to do:
- 创建或扩展
tests/integration/iot_card_gateway_test.go:- 测试 6 个卡 Gateway 接口
- 测试权限校验(代理商不能操作其他店铺的卡)
- Mock Gateway 响应
- 创建或扩展
tests/integration/device_gateway_test.go:- 测试 7 个设备 Gateway 接口
- 测试权限校验
- Mock Gateway 响应
Must NOT do:
- 不调用真实第三方服务
Recommended Agent Profile:
- Category:
unspecified-low - Skills: []
Parallelization:
- Can Run In Parallel: NO
- Parallel Group: Wave 3 (final)
- Blocks: None
- Blocked By: Task 4, Task 5
References:
tests/integration/iot_card_test.go- 现有集成测试模式tests/integration/device_test.go- 现有设备测试模式internal/testutils/- 测试工具函数
Acceptance Criteria:
- 卡 Gateway 接口测试覆盖 6 个端点
- 设备 Gateway 接口测试覆盖 7 个端点
- 权限校验测试通过
source .env.local && go test -v ./tests/integration/... -run TestGateway通过
Commit: YES
- Message:
test(integration): 添加 Gateway 接口集成测试 - Files:
tests/integration/iot_card_gateway_test.go,tests/integration/device_gateway_test.go
- 创建或扩展
Commit Strategy
| After Task | Message | Files |
|---|---|---|
| 1 | feat(bootstrap): 为 IotCardHandler 和 DeviceHandler 注入 Gateway Client |
handlers.go, iot_card.go, device.go |
| 2 | feat(handler): IotCardHandler 新增 6 个 Gateway 接口方法 |
iot_card.go |
| 3 | feat(handler): DeviceHandler 新增 7 个 Gateway 接口方法 |
device.go |
| 4 | feat(routes): 注册 6 个卡 Gateway 路由 |
iot_card.go |
| 5 | feat(routes): 注册 7 个设备 Gateway 路由 |
device.go |
| 6 | test(integration): 添加 Gateway 接口集成测试 |
*_gateway_test.go |
Success Criteria
Verification Commands
# 编译检查
go build ./cmd/api
# 生成 OpenAPI 文档
go run cmd/gendocs/main.go
# 运行集成测试
source .env.local && go test -v ./tests/integration/... -run TestGateway
Final Checklist
- 所有 13 个接口可访问
- 权限校验生效
- OpenAPI 文档包含新接口
- 集成测试通过