All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m39s
- 新增企业设备授权模块(Model、DTO、Service、Handler、Store) - 实现设备授权的创建、查询、更新、删除等完整业务逻辑 - 添加企业卡授权与设备授权的关联关系 - 新增 2 个数据库迁移脚本 - 同步 OpenSpec delta specs 到 main specs - 归档 add-enterprise-device-authorization 变更 - 更新 API 文档和路由配置 - 新增完整的集成测试和单元测试覆盖
100 lines
2.8 KiB
Markdown
100 lines
2.8 KiB
Markdown
# 设计:RoleHandler 请求验证
|
||
|
||
## 上下文
|
||
|
||
项目中已有标准的请求验证模式:
|
||
- 使用 `github.com/go-playground/validator/v10` 库
|
||
- 在 bootstrap 层创建全局 validator 实例
|
||
- Handler 构造函数接收 validator
|
||
- 请求解析后立即调用 `validator.Struct()` 验证
|
||
|
||
AuthHandler 已正确实现此模式(参考 `internal/handler/admin/auth.go:34`),RoleHandler 需要遵循相同模式。
|
||
|
||
## 目标 / 非目标
|
||
|
||
**目标:**
|
||
- RoleHandler 遵循项目验证标准模式
|
||
- 所有请求在到达 Service 层前完成验证
|
||
- 取消被跳过的集成测试
|
||
|
||
**非目标:**
|
||
- 不修改 DTO 的 validate 标签(已正确定义)
|
||
- 不改变错误响应格式(使用现有 CodeInvalidParam)
|
||
- 不引入新的验证库或模式
|
||
|
||
## 决策
|
||
|
||
### 决策 1:遵循 AuthHandler 模式
|
||
|
||
**方法:** 完全复制 AuthHandler 的验证模式到 RoleHandler
|
||
|
||
**理由:**
|
||
- 保持代码库一致性
|
||
- AuthHandler 模式已验证有效
|
||
- 无需重新设计验证流程
|
||
|
||
**实现细节:**
|
||
```go
|
||
// 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:错误消息格式
|
||
|
||
**使用现有格式:**
|
||
```go
|
||
errors.New(errors.CodeInvalidParam, "参数验证失败: "+err.Error())
|
||
```
|
||
|
||
**理由:**
|
||
- 与 AuthHandler 保持一致
|
||
- validator 库的错误消息已足够清晰
|
||
- 前端可以解析错误码和消息
|
||
|
||
## 测试策略
|
||
|
||
- 取消 `tests/integration/role_test.go:51` 的 TODO 跳过
|
||
- 运行现有测试验证"缺少必填字段返回错误"场景
|
||
- 无需添加新测试(现有被跳过的测试已覆盖验证逻辑)
|