# ACL 权限模型

## 功能权限 (RBAC)

| 权限代码 | 说明 | 角色 |
|:---|:---|:---|
| `project:create` | 创建项目 | SuperAdmin |
| `project:delete` | 删除/归档项目 | SuperAdmin |
| `project:edit` | 直接编辑项目 | SuperAdmin |
| `project:edit_workflow` | 通过工单编辑项目 | User (有ACL权限) |
| `project:auth_manage` | 一级/二级授权管理 | SuperAdmin |
| `project:permission_manage` | 项目权限分配 | SuperAdmin |

## 数据权限 (ACL) - 模块级别

### 模块定义

| 模块代码 | 模块名称 | 说明 |
|:---|:---|:---|
| `basic_info` | 基本信息模块 | 项目名称、命名空间、省份城市等 |
| `business_info` | 部署业务模块 | 部署人、部署时间、系统版本等 |
| `environment_info` | 部署环境模块 | 主机信息、网络环境、域名等 |
| `middleware_info` | 部署中间件模块 | MySQL、Redis、EMQX等配置 |
| `authorization_info` | 项目授权模块 | TOTP授权信息（仅SuperAdmin） |

### 权限类型

| 权限类型 | 说明 |
|:---|:---|
| `view` | 查看权限（可查看项目信息，可发起修改工单） |
| `export` | 导出权限（可导出项目信息） |

> **说明**：编辑权限通过工单系统实现，拥有 `view` 权限的用户可以发起修改工单，由 SuperAdmin 审批后生效。

## 权限规则

1. **SuperAdmin**: 拥有所有项目的所有模块的全部权限，可直接修改
2. **Admin**: 可以访问自己被授权的项目模块，可以向普通用户转授权限
3. **Normal User**: 只能访问被授权的项目模块，修改需通过工单
4. **项目填写人**: 自动获得该项目的查看权限
5. **授权模块**: 仅 SuperAdmin 可见

## ACL 表结构（位于 rmdc-user-auth）

```go
// ProjectACL 项目权限表 (模块级别)
type ProjectACL struct {
    ID         int64     `gorm:"primaryKey;autoIncrement" json:"id"`
    ProjectID  string    `gorm:"type:varchar(64);index;not null" json:"project_id"`
    UserID     int64     `gorm:"index;not null" json:"user_id"`

    // 模块代码: basic_info/business_info/environment_info/middleware_info/authorization_info
    ModuleCode string    `gorm:"type:varchar(32);not null" json:"module_code"`

    // 权限类型
    CanView    bool      `gorm:"default:false" json:"can_view"`
    CanExport  bool      `gorm:"default:false" json:"can_export"`

    // 授权信息
    GrantedBy  int64     `json:"granted_by"`
    GrantedAt  time.Time `json:"granted_at"`

    UpdatedAt  time.Time `json:"updated_at"`
}
```

## 权限检查流程

```go
// CheckProjectModulePermission 检查用户对项目模块的权限
func (s *ACLService) CheckProjectModulePermission(
    ctx context.Context,
    userID int64,
    projectID string,
    moduleCode string,
    permType string, // "view" or "export"
) (bool, error) {
    // 1. 检查是否为 SuperAdmin
    if s.IsSuperAdmin(ctx, userID) {
        return true, nil
    }

    // 2. 授权模块仅 SuperAdmin 可访问
    if moduleCode == "authorization_info" {
        return false, nil
    }

    // 3. 查询 ACL 表
    var acl ProjectACL
    err := s.db.Where("project_id = ? AND user_id = ? AND module_code = ?",
        projectID, userID, moduleCode).First(&acl).Error
    if err != nil {
        return false, nil
    }

    // 4. 检查权限类型
    switch permType {
    case "view":
        return acl.CanView, nil
    case "export":
        return acl.CanExport, nil
    default:
        return false, nil
    }
}
```

## 权限分配接口

### 授予权限

```json
// POST /api/project/permission/grant
{
  "project_id": "proj_001",
  "user_id": 123,
  "modules": [
    {
      "module_code": "basic_info",
      "can_view": true,
      "can_export": false
    },
    {
      "module_code": "business_info",
      "can_view": true,
      "can_export": true
    }
  ]
}
```

### 批量设置权限

```json
// POST /api/project/permission/batch
{
  "project_id": "proj_001",
  "permissions": [
    {
      "user_id": 123,
      "modules": ["basic_info", "business_info"]
    },
    {
      "user_id": 456,
      "modules": ["basic_info"]
    }
  ]
}
```

## 权限继承规则

| 场景 | 规则 |
|:---|:---|
| 项目创建 | 填写人自动获得所有模块的 view 权限 |
| 权限转授 | Admin 只能转授自己拥有的权限 |
| 权限撤销 | 不影响已创建的草稿/工单 |
| 项目归档 | 保留权限记录，但无法访问 |
