Files
junhong_cmp_fiber/specs/004-rbac-data-permission/contracts/README.md
huang eaa70ac255 feat: 实现 RBAC 权限系统和数据权限控制 (004-rbac-data-permission)
主要功能:
- 实现完整的 RBAC 权限系统(账号、角色、权限的多对多关联)
- 基于 owner_id + shop_id 的自动数据权限过滤
- 使用 PostgreSQL WITH RECURSIVE 查询下级账号
- Redis 缓存优化下级账号查询性能(30分钟过期)
- 支持多租户数据隔离和层级权限管理

技术实现:
- 新增 Account、Role、Permission 模型及关联关系表
- 实现 GORM Scopes 自动应用数据权限过滤
- 添加数据库迁移脚本(000002_rbac_data_permission、000003_add_owner_id_shop_id)
- 完善错误码定义(1010-1027 为 RBAC 相关错误)
- 重构 main.go 采用函数拆分提高可读性

测试覆盖:
- 添加 Account、Role、Permission 的集成测试
- 添加数据权限过滤的单元测试和集成测试
- 添加下级账号查询和缓存的单元测试
- 添加 API 回归测试确保向后兼容

文档更新:
- 更新 README.md 添加 RBAC 功能说明
- 更新 CLAUDE.md 添加技术栈和开发原则
- 添加 docs/004-rbac-data-permission/ 功能总结和使用指南

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 16:44:06 +08:00

264 lines
7.5 KiB
Markdown
Raw 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.
# API Contracts: RBAC 表结构与 GORM 数据权限过滤
**Feature**: 004-rbac-data-permission
**Date**: 2025-11-18
**Format**: OpenAPI 3.0.3
## 概述
本目录包含 RBAC 权限系统的完整 API 接口规范,使用 OpenAPI 3.0.3 标准定义。所有 API 遵循 RESTful 设计原则,支持统一的认证、错误处理和响应格式。
## 文件结构
```
contracts/
├── README.md # 本文件
├── account-api.yaml # 账号管理接口
├── role-api.yaml # 角色管理接口
└── permission-api.yaml # 权限管理接口
```
## API 模块
### 1. Account Management API (`account-api.yaml`)
**基础路径**: `/api/v1/accounts`
**核心功能**:
- 账号 CRUD创建、查询、更新、删除账号
- 账号-角色关联:为账号分配角色、查询账号的角色、移除角色
**关键端点**:
- `POST /accounts` - 创建账号(非 root 必须提供 parent_id
- `GET /accounts` - 查询账号列表(自动应用数据权限过滤)
- `GET /accounts/{id}` - 查询账号详情
- `PUT /accounts/{id}` - 更新账号(禁止修改 parent_id 和 user_type
- `DELETE /accounts/{id}` - 软删除账号
- `POST /accounts/{id}/roles` - 为账号分配角色
- `GET /accounts/{id}/roles` - 查询账号的所有角色
- `DELETE /accounts/{account_id}/roles/{role_id}` - 移除账号的角色
**数据权限过滤**:
- 查询账号列表和详情时,自动应用 `WHERE owner_id IN (当前用户及所有下级的ID列表) AND shop_id = 当前用户的shop_id`
- root 用户user_type=1跳过数据权限过滤
**业务规则**:
- username 和 phone 必须唯一(软删除后可重用)
- 密码使用 bcrypt 哈希(建议替代 MD5
- parent_id 创建后不可修改
- 账号类型1=root, 2=平台, 3=代理, 4=企业
### 2. Role Management API (`role-api.yaml`)
**基础路径**: `/api/v1/roles`
**核心功能**:
- 角色 CRUD创建、查询、更新、删除角色
- 角色-权限关联:为角色分配权限、查询角色的权限、移除权限
**关键端点**:
- `POST /roles` - 创建角色
- `GET /roles` - 查询角色列表(支持按类型和状态过滤)
- `GET /roles/{id}` - 查询角色详情
- `PUT /roles/{id}` - 更新角色
- `DELETE /roles/{id}` - 软删除角色
- `POST /roles/{id}/permissions` - 为角色分配权限
- `GET /roles/{id}/permissions` - 查询角色的所有权限
- `DELETE /roles/{role_id}/permissions/{perm_id}` - 移除角色的权限
**角色类型**:
- 1=超级角色
- 2=代理角色
- 3=企业角色
### 3. Permission Management API (`permission-api.yaml`)
**基础路径**: `/api/v1/permissions`
**核心功能**:
- 权限 CRUD创建、查询、更新、删除权限
- 层级支持支持权限的层级关系parent_id
- 树形查询:查询完整的权限树结构
**关键端点**:
- `POST /permissions` - 创建权限(支持层级关系)
- `GET /permissions` - 查询权限列表(支持按类型、父权限、状态过滤)
- `GET /permissions/{id}` - 查询权限详情
- `PUT /permissions/{id}` - 更新权限
- `DELETE /permissions/{id}` - 软删除权限
- `GET /permissions/tree` - 查询权限树(完整层级结构)
**权限类型**:
- 1=菜单权限
- 2=按钮权限
**权限编码规范**:
- 格式:`module:action`(如 `user:create``order:delete`
- 必须唯一
- 使用小写字母和冒号
## 统一规范
### 认证方式
所有 API 使用 **Bearer Token** 认证JWT:
```http
Authorization: Bearer <token>
```
### 统一响应格式
所有 API 响应使用统一的 JSON 格式:
```json
{
"code": 0,
"message": "success",
"data": { ... },
"timestamp": "2025-11-18T15:30:00Z"
}
```
**字段说明**:
- `code`: 错误码0 表示成功1xxx 表示客户端错误2xxx 表示服务端错误)
- `message`: 响应消息(中英文双语)
- `data`: 响应数据(具体内容根据接口而定)
- `timestamp`: 响应时间戳ISO 8601 格式)
### 分页参数
所有列表查询接口统一使用以下分页参数:
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| page | integer | 1 | 页码(从 1 开始) |
| page_size | integer | 20 | 每页大小(最大 100 |
分页响应格式:
```json
{
"items": [ ... ],
"total": 100,
"page": 1,
"page_size": 20
}
```
### 时间格式
所有时间字段使用 **ISO 8601 格式**RFC3339
```
2025-11-18T15:30:00Z
```
### HTTP 状态码
| 状态码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 400 | 请求参数错误 |
| 401 | 未认证 |
| 403 | 无权限访问 |
| 404 | 资源不存在 |
| 500 | 服务器错误 |
### 错误响应示例
**客户端错误400**:
```json
{
"code": 1001,
"message": "用户名已存在",
"data": null,
"timestamp": "2025-11-18T15:30:00Z"
}
```
**服务器错误500**:
```json
{
"code": 2001,
"message": "服务器内部错误,请稍后重试",
"data": null,
"timestamp": "2025-11-18T15:30:00Z"
}
```
## 数据权限过滤
### 过滤机制
所有业务数据查询(账号、用户、订单等)自动应用数据权限过滤:
```sql
WHERE owner_id IN (ID列表) AND shop_id = shop_id
```
### 特殊情况
1. **root 用户user_type=1**: 跳过数据权限过滤,返回所有数据
2. **C 端业务用户**: 使用 `WithoutDataFilter` 选项,改为基于业务字段(如 iccid/device_id过滤
3. **系统任务**: Context 中无用户信息时,不应用过滤
### 缓存策略
用户的所有下级 ID 列表缓存到 Redis
- **Key**: `account:subordinates:{账号ID}`
- **Value**: 下级 ID 列表JSON 数组)
- **过期时间**: 30 分钟
- **清除时机**: 账号创建、删除时主动清除相关缓存
## 使用工具
### 在线查看
可以使用以下工具在线查看和测试 API
- **Swagger Editor**: https://editor.swagger.io/
- **Swagger UI**: https://petstore.swagger.io/
- **Postman**: 导入 OpenAPI 文件自动生成 API 集合
### 代码生成
使用 OpenAPI Generator 可以生成客户端 SDK 和服务端代码骨架:
```bash
# 安装 OpenAPI Generator
npm install -g @openapitools/openapi-generator-cli
# 生成 Go 服务端代码Fiber
openapi-generator-cli generate -i account-api.yaml -g go-server -o ./generated/account
# 生成 TypeScript 客户端代码
openapi-generator-cli generate -i account-api.yaml -g typescript-axios -o ./generated/client
```
## 下一步
1. **实现 Handler 层**: 根据 API 规范实现 Fiber Handler
2. **实现 Service 层**: 实现业务逻辑和数据权限过滤
3. **实现 Store 层**: 实现数据库访问和 GORM Scopes
4. **集成测试**: 编写 API 集成测试,验证接口行为
5. **文档部署**: 部署 Swagger UI 提供在线 API 文档
## 注意事项
1. **密码字段安全**: 账号的 `password` 字段在查询时不返回(使用 GORM 标签 `json:"-"`
2. **软删除支持**: 所有表支持软删除,删除操作只设置 `deleted_at` 字段
3. **唯一性约束**: username、phone、perm_code 使用软删除感知的唯一索引(`WHERE deleted_at IS NULL`
4. **关联表**: account_roles 和 role_permissions 使用联合唯一索引防止重复分配
5. **层级关系**: parent_id 创建后不可修改权限支持多层级parent_id
## 参考资料
- [OpenAPI 3.0.3 规范](https://spec.openapis.org/oas/v3.0.3)
- [RESTful API 设计指南](https://restfulapi.net/)
- [Fiber 框架文档](https://docs.gofiber.io/)
- [GORM 文档](https://gorm.io/docs/)