Files
junhong_cmp_fiber/openspec/changes/archive/2026-01-29-add-role-handler-validation/design.md
huang b02175271a
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m39s
feat: 实现企业设备授权功能并归档 OpenSpec 变更
- 新增企业设备授权模块(Model、DTO、Service、Handler、Store)
- 实现设备授权的创建、查询、更新、删除等完整业务逻辑
- 添加企业卡授权与设备授权的关联关系
- 新增 2 个数据库迁移脚本
- 同步 OpenSpec delta specs 到 main specs
- 归档 add-enterprise-device-authorization 变更
- 更新 API 文档和路由配置
- 新增完整的集成测试和单元测试覆盖
2026-01-29 13:18:49 +08:00

2.8 KiB
Raw Blame History

设计RoleHandler 请求验证

上下文

项目中已有标准的请求验证模式:

  • 使用 github.com/go-playground/validator/v10
  • 在 bootstrap 层创建全局 validator 实例
  • Handler 构造函数接收 validator
  • 请求解析后立即调用 validator.Struct() 验证

AuthHandler 已正确实现此模式(参考 internal/handler/admin/auth.go:34RoleHandler 需要遵循相同模式。

目标 / 非目标

目标:

  • RoleHandler 遵循项目验证标准模式
  • 所有请求在到达 Service 层前完成验证
  • 取消被跳过的集成测试

非目标:

  • 不修改 DTO 的 validate 标签(已正确定义)
  • 不改变错误响应格式(使用现有 CodeInvalidParam
  • 不引入新的验证库或模式

决策

决策 1遵循 AuthHandler 模式

方法: 完全复制 AuthHandler 的验证模式到 RoleHandler

理由:

  • 保持代码库一致性
  • AuthHandler 模式已验证有效
  • 无需重新设计验证流程

实现细节:

// 1. RoleHandler 结构体添加 validator 字段
type RoleHandler struct {
    service   *roleService.Service
    validator *validator.Validate  // 新增
}

// 2. 构造函数接收 validator
func NewRoleHandler(service *roleService.Service, validator *validator.Validate) *RoleHandler {
    return &RoleHandler{
        service:   service,
        validator: validator,
    }
}

// 3. Create 方法中验证
func (h *RoleHandler) Create(c *fiber.Ctx) error {
    var req dto.CreateRoleRequest
    if err := c.BodyParser(&req); err != nil {
        return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
    }
    
    // 新增验证逻辑
    if err := h.validator.Struct(&req); err != nil {
        return errors.New(errors.CodeInvalidParam, "参数验证失败: "+err.Error())
    }
    
    // ... 现有逻辑
}

决策 2验证所有接受 body 的方法

需要验证的方法:

  • Create() - CreateRoleRequest
  • Update() - UpdateRoleRequest
  • AssignPermissions() - AssignPermissionsRequest
  • UpdateStatus() - UpdateRoleStatusRequest

不需要验证的方法:

  • Get() - 只有路径参数,已有 ParseUint 检查
  • List() - Query 参数,已有 QueryParser
  • GetPermissions() - 只有路径参数
  • RemovePermission() - 只有路径参数
  • Delete() - 只有路径参数

决策 3错误消息格式

使用现有格式:

errors.New(errors.CodeInvalidParam, "参数验证失败: "+err.Error())

理由:

  • 与 AuthHandler 保持一致
  • validator 库的错误消息已足够清晰
  • 前端可以解析错误码和消息

测试策略

  • 取消 tests/integration/role_test.go:51 的 TODO 跳过
  • 运行现有测试验证"缺少必填字段返回错误"场景
  • 无需添加新测试(现有被跳过的测试已覆盖验证逻辑)