feat: 平台治理与权限体系完善,存储进度/GPU预留/审批中心与日志整合
- 平台治理: 租户用户权限层次、资源ACL、审批中心与审批模板、访问申请 - 存储: MinIO 存储进度迁移、对象存储安全加固与测试 - 计算: GPU 资源预留、compute 轮询与同步增强 - 权限: permission v2 迁移、权限安全验收测试 - 日志: 后端运行日志中文说明、操作日志整合 - 数据处理/评测: 数据转换与模型评测优化 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
38
docs/20260812/database-migration.md
Normal file
38
docs/20260812/database-migration.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 数据库迁移说明
|
||||
|
||||
## 当前迁移文件
|
||||
|
||||
- 新库初始化:`backend/app/db/sql/000_full_init.sql`
|
||||
- 已有数据库增量迁移:`backend/app/db/sql/005_storage_progress_migration.sql`
|
||||
- GPU 预留迁移:`backend/app/db/sql/006_gpu_reservations.sql`
|
||||
- 平台闭环迁移:`backend/app/db/sql/007_platform_completion.sql`
|
||||
- 离线部署使用:`docker/offline/src/backend/app/db/sql/000_full_init.sql`
|
||||
|
||||
## 执行方式
|
||||
|
||||
```bash
|
||||
for migration in 005_storage_progress_migration.sql 006_gpu_reservations.sql 007_platform_completion.sql; do
|
||||
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f "backend/app/db/sql/$migration"
|
||||
done
|
||||
```
|
||||
|
||||
迁移前应完成数据库备份,并保存以下结构快照:
|
||||
|
||||
```sql
|
||||
SELECT table_name, column_name, data_type
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
ORDER BY table_name, ordinal_position;
|
||||
```
|
||||
|
||||
## 本次迁移内容
|
||||
|
||||
- 为算力节点资源副本增加 `version_id` 和 `storage_object_id`,用于记录 MinIO 版本与本地缓存对应关系。
|
||||
- 补齐 `storage_objects.metadata`、模型产物、数据集文件和数据转换任务的 MinIO 字段。
|
||||
- 补齐评测任务软删除、创建者、租户和报告对象字段。
|
||||
- 增加活动评测任务、资源副本和 MinIO 对象索引。
|
||||
- 增加 GPU 预留表,统一训练、推理、评测的卡级占用约束。
|
||||
- 增加模型导出创建者/租户/归档状态字段。
|
||||
- 增加 MinIO 对象软删除清理、缓存版本校验和访问保护字段及清理任务表。
|
||||
|
||||
`000_full_init.sql` 已包含相同的幂等变更,新增数据库直接执行初始化脚本即可;已有数据库不要依赖容器重启自动完成迁移。
|
||||
383
docs/20260812/当前项目开发进度.md
Normal file
383
docs/20260812/当前项目开发进度.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# 当前项目开发进度
|
||||
|
||||
> 评估基线:2026-08-19 当前工作区代码、数据库初始化脚本、Docker 部署文件、前端页面和现有设计文档。
|
||||
>
|
||||
> 本文以代码实际情况为准。设计文档中已经提出但代码没有形成完整闭环的内容,统一标记为“部分完成”或“未完成”。
|
||||
|
||||
## 一、项目定位与总体结论
|
||||
|
||||
当前项目是一个面向多用户、多算力节点的模型训练与推理平台,主要链路为:
|
||||
|
||||
```text
|
||||
Vue 前端
|
||||
|
|
||||
FastAPI Backend API
|
||||
|-- PostgreSQL:业务元数据、权限、任务状态、小型内容和预览数据
|
||||
|-- Redis:会话、限流、短期缓存和任务辅助状态
|
||||
|-- MinIO:模型、数据集、报告和大文件的统一对象存储
|
||||
|-- Compute API / Agent:训练、推理、评测、模型合并和 GPU 执行
|
||||
|
|
||||
多台算力节点
|
||||
```
|
||||
|
||||
整体判断:
|
||||
|
||||
| 范围 | 当前状态 | 结论 |
|
||||
|---|---|---|
|
||||
| 平台基础架构 | 基本完成 | 前后端、数据库、Redis、MinIO、Compute Agent 和 Docker 部署均已具备 |
|
||||
| 核心业务闭环 | 基本可用 | 数据集、数据处理、数据转换、训练、模型、推理、评测均有页面和接口 |
|
||||
| 多算力节点 | 部分完成 | 节点选择、GPU 分配和缓存准备已经接入,跨节点一致性和失败恢复仍需加强 |
|
||||
| 权限治理 | 部分完成 | 登录、角色、权限码、ACL、审批、审计已实现,但完整的租户/项目隔离尚未闭环 |
|
||||
| MinIO 统一存储 | 部分完成 | 大文件和模型已接入,仍存在兼容性的本地路径和部分数据双写/回退路径 |
|
||||
| 生产可靠性 | 未完成 | 缓存容量治理、对象清理、流式上传、归档重试、备份和高可用尚未完成 |
|
||||
| 前端体验 | 基本可用,需优化 | 构建问题已持续修复,但页面响应等待、首屏体积和部分错误提示仍需优化 |
|
||||
|
||||
## 二、已完成的功能
|
||||
|
||||
### 2.1 平台基础与部署
|
||||
|
||||
- 已建立 Vue 3 + TypeScript + Vite 前端工程。
|
||||
- 已建立 FastAPI 后端服务,提供登录、平台管理和模型业务接口。
|
||||
- 已建立 Compute API / Agent,用于连接算力节点并执行训练、推理、评测和模型处理任务。
|
||||
- 已使用 PostgreSQL 保存核心业务数据,Redis 提供会话、限流和缓存能力。
|
||||
- 已增加 MinIO 服务及 Backend 的 MinIO 配置,支持和 Compute Agent 分离部署。
|
||||
- 已提供 `docker/app`、`docker/compute`、`docker/minio` 和 `docker/offline` 部署目录。
|
||||
- 已考虑后端、算力服务、MinIO 分布在不同服务器时使用独立网络;Compute 节点访问 MinIO 需要配置所有节点都能访问的固定 IP 或 DNS。
|
||||
- 离线部署目录已经同步后端、算力相关源码和初始化 SQL 的主要改造内容。
|
||||
|
||||
### 2.2 登录、用户和权限基础
|
||||
|
||||
- 用户登录、退出、当前用户信息和密码修改接口已经存在。
|
||||
- 已有 Token 会话、Redis 会话记录和登录限流逻辑。
|
||||
- 已建立用户、角色、权限码和角色权限关系。
|
||||
- 已实现管理员、普通用户等基础角色分层。
|
||||
- 已实现页面路由守卫、菜单过滤和前端按钮级权限的基础能力。
|
||||
- 已建立资源 ACL 管理页面和相关接口,可对用户或角色授予资源级权限。
|
||||
- 已建立审批模板、审批实例和审批步骤的基本数据模型与页面。
|
||||
- 已建立运行日志、审计日志查询页面及审计记录写入机制。
|
||||
- 已加入软删除相关字段和部分删除逻辑,避免直接物理删除业务资源。
|
||||
|
||||
### 2.3 算力节点与 GPU 资源
|
||||
|
||||
- 已实现算力节点的新增、编辑、启用、禁用、维护/删除、连通性测试和健康检查。
|
||||
- 已实现节点列表、节点详情、节点副本/同步状态和 Compute Agent 连接。
|
||||
- 已实现 GPU 信息发现、GPU 状态查询和队列查询。
|
||||
- 已建立 `gpu_allocations`、`gpu_assignments`、调度锁等资源分配表。
|
||||
- 训练任务已经支持选择调度节点和一张或多张 GPU,并在预检阶段校验资源可用性。
|
||||
- Compute Agent 已支持训练、评测、推理和缓存准备等任务接口。
|
||||
- 已存在资源副本和同步任务模型,用于记录节点侧资源同步状态。
|
||||
|
||||
### 2.4 数据集管理
|
||||
|
||||
- 已实现数据集创建、列表、详情、编辑、删除和文件上传。
|
||||
- 已实现数据集文件下载、预览、记录列表和数据记录编辑入口。
|
||||
- 已处理 JSON 与 JSONL 的记录数差异:JSON 数组按元素计数,JSONL 按有效行计数,避免把整个 JSON 文件误按行数统计。
|
||||
- 已提供数据集版本列表、版本详情、创建版本、切换当前激活版本和删除版本接口。
|
||||
- 已增加数据集文件、版本、数据记录等初始化表结构。
|
||||
- 已支持数据集文件在数据库小内容和 MinIO 大文件之间按策略存储。
|
||||
- 已在训练预检中检查数据集文件是否存在、是否可从 MinIO 获取以及是否能准备到目标算力节点。
|
||||
|
||||
### 2.5 数据处理与数据转换
|
||||
|
||||
- 已提供结构化数据、非结构化数据、外部数据源的处理创建流程。
|
||||
- 已实现源文件上传、预览、分片/切分、生成、质量检查、去重和结果管理等数据处理流程。
|
||||
- 已支持处理结果生成数据集或导入数据集版本。
|
||||
- 已建立数据处理任务、源文件、预览项、结果等数据表。
|
||||
- 已提供 JSON、JSONL 等数据格式转换页面和后端任务接口。
|
||||
- 已将数据转换输出接入 MinIO/数据库分层存储:小型文本结果可存数据库,大文件存 MinIO。
|
||||
- 已处理输出文件下载和转换结果元数据保存问题。
|
||||
|
||||
### 2.6 模型训练
|
||||
|
||||
- 已实现训练任务创建、配置预检、命令预览、启动、停止、重试和删除。
|
||||
- 已接入 LLaMA-Factory 等训练适配逻辑。
|
||||
- 已支持选择训练数据、基座模型、算力节点和 GPU。
|
||||
- 已实现训练日志获取、训练任务概览、诊断信息、检查点和训练指标查询。
|
||||
- 前端训练详情已经具备训练曲线解析和展示逻辑,日志轮询间隔已调整为 3 秒。
|
||||
- 已增加 GPU 详情展示入口,包括显存和利用率等 Compute Agent 上报信息。
|
||||
- 已支持训练任务的 MinIO 数据准备和目标算力节点缓存准备。
|
||||
|
||||
### 2.7 模型管理与权重合并
|
||||
|
||||
- 已实现在线模型/基座模型和训练模型的列表、创建、详情、用途修改和删除。
|
||||
- 已建立模型、训练模型、模型血缘、模型产物和导出任务相关表。
|
||||
- 已提供权重合并入口,能够根据训练任务准备基座模型和 Adapter,并提交 Compute Agent 执行合并。
|
||||
- 已增加模型产物和 MinIO 对象关联字段。
|
||||
- 合并结果能够在任务完成后归档到 MinIO 的设计和主要代码路径已经建立。
|
||||
|
||||
### 2.8 模型推理与模型对比
|
||||
|
||||
- 已实现推理模型列表、创建、详情和删除入口。
|
||||
- 已实现模型加载、卸载、服务启动、服务状态查询和对话调用。
|
||||
- 已实现模型对比任务及多模型聊天相关接口。
|
||||
- 已增加推理失败重试、停止和资源释放的处理路径。
|
||||
- 已支持根据页面选择的算力节点准备模型缓存,兼容训练时所选节点优先的业务要求。
|
||||
- Compute Agent 已提供本地推理会话和模型缓存状态接口。
|
||||
|
||||
### 2.9 模型评测
|
||||
|
||||
- 已实现评测任务列表、创建、详情和删除。
|
||||
- 已实现评测维度管理和评测规则配置页面。
|
||||
- 已建立评测任务、评测维度、对比任务等数据库表。
|
||||
- 已支持选择模型、数据集、评测维度、算力节点和 GPU 的基础流程。
|
||||
- 已接入 Compute Agent 执行评测任务,并保存评测结果和报告相关元数据。
|
||||
|
||||
### 2.10 数据存储策略
|
||||
|
||||
- 已建立 `storage_objects`、`storage_cache_jobs` 等 MinIO 元数据和缓存任务表。
|
||||
- 已建立 MinIO 对象上传、下载、预签名 URL 和节点缓存准备的主要接口。
|
||||
- 已采用分层策略:
|
||||
- 小型 JSON、JSONL、CSV、任务参数快照、预览数据保留在数据库,降低频繁预览的 MinIO 延迟。
|
||||
- 模型权重、训练产物、评测报告和大文件使用 MinIO。
|
||||
- 小型 PDF、DOCX、XLSX 仍优先存 MinIO,以保留原始二进制文件内容。
|
||||
- 已增加 `data_convert_tasks.output_content`,用于保存小型转换结果,避免所有小结果都依赖 MinIO。
|
||||
- Backend 和离线包中的 `000_full_init.sql` 已同步,当前两份初始化脚本内容一致。
|
||||
|
||||
## 三、部分完成、仍需完善的功能
|
||||
|
||||
### 3.1 MinIO 统一数据源尚未完全闭环
|
||||
|
||||
当前 MinIO 已成为模型、大文件和跨节点资源的主存储方向,但仍保留以下兼容路径:
|
||||
|
||||
- Compute Agent 仍有本地文件上传、导入本地模型和扫描本地模型目录的旧接口。
|
||||
- 部分历史数据仍使用数据库中的 `content` 或 `output_content` 字段,这是当前已确认的小文件性能策略,不是错误,但必须统一记录来源、大小、校验值和版本。
|
||||
- Compute Agent 节点侧的大文件上传已改为流式读取;Backend 端部分历史上传/下载路径仍未完成统一的分片传输。
|
||||
- MinIO 对象和业务资源之间采用多态 `resource_type/resource_id` 关联,数据库没有直接外键,删除和数据一致性需要应用层保证。
|
||||
- 删除业务资源后,对应 MinIO 对象的延迟清理、失败重试和孤儿对象扫描尚未形成完整闭环。
|
||||
|
||||
### 3.2 MinIO 预签名接口的权限边界
|
||||
|
||||
资源写权限、服务端对象 Key、上传完成确认和对象大小校验已经完成;仍需补充 Content-Type 白名单、对象过期回收和完整审计事件。
|
||||
|
||||
### 3.3 激活版本和跨节点资源版本仍需加强
|
||||
|
||||
数据集已经有 `active_version_id` 和版本表,但以下场景仍需补充:
|
||||
|
||||
- 训练、评测、模型对比和权重合并已在任务创建时固化资源版本 ID;推理服务启动和导出任务仍需统一补齐。
|
||||
- 同一文件名的不同版本不能只依靠文件名同步,应使用资源 ID、版本 ID 和对象 Key 组成唯一定位。
|
||||
- 已创建任务在后续切换激活版本后,不能被意外切换到新版本。
|
||||
- 已为资源副本保存版本、对象 ID 和本地路径;对象 ETag/校验值及多文件 manifest 仍需补齐。
|
||||
- 历史版本的数据库内容回退和 MinIO 对象回退逻辑还需要补全并增加测试。
|
||||
|
||||
### 3.4 权限 2.0 尚未完全落地
|
||||
|
||||
已有用户、角色、权限码、ACL、审批和审计基础,但仍存在以下差距:
|
||||
|
||||
- 租户、用户、资源、算力节点、模型、数据集之间的隔离规则没有全部在 SQL 查询层统一执行。
|
||||
- 项目空间设计已经讨论过取消,但数据库中仍保留 `projects`、`project_members` 等历史结构,需要明确兼容策略和最终迁移方式。
|
||||
- 训练创建的模型、数据集和训练任务之间的联合权限约束还没有完全统一。
|
||||
- 评测、推理、模型合并、导出、缓存准备等动作需要逐一校验资源读权限和操作权限。
|
||||
- 前端按钮权限已经有基础实现,但不能替代后端鉴权;仍需要对所有关键动作进行后端默认拒绝校验。
|
||||
- 审批拦截范围、管理员豁免规则和跨租户资源访问规则需要形成可执行矩阵。
|
||||
|
||||
### 3.5 模型合并、导出和评测报告闭环不足
|
||||
|
||||
- 权重合并前自动准备 Base Model 和 Adapter 的主要路径已建立,但失败时的清理、重试和幂等性仍需加强。
|
||||
- 合并结果归档已增加失败状态和服务重启后的补偿轮询;仍需加入独立归档队列和幂等对象清单,降低重复扫描成本。
|
||||
- 模型导出任务目前有查询模型和表结构,但完整的创建、执行、进度、失败重试和下载闭环尚未完成。
|
||||
- 评测结果和报告字段已经存在,但报告对象归档、报告下载、报告版本和报告与任务的稳定关联仍需验证。
|
||||
- 评测指标配置和执行器返回指标之间仍需要强类型映射,避免前端显示为通用的 `custom`。
|
||||
|
||||
### 3.6 GPU 资源分配需要统一到所有任务类型
|
||||
|
||||
- 训练已经有较完整的节点/GPU 选择和预检流程。
|
||||
- 推理和评测已经出现节点选择、缓存准备和 GPU 选择的接入代码,但还需要确认从页面选择到 Compute Agent 启动参数、进程环境变量和释放逻辑的全链路生效。
|
||||
- 需要防止同一张 GPU 被多个任务绕过调度锁重复占用。
|
||||
- 需要处理服务异常退出、Backend 重启、Compute Agent 重启后的分配回收和状态对账。
|
||||
- 训练详情中的显存使用量、GPU 使用率等指标依赖 Compute Agent 上报,仍需要校验采样时间、单位、空值和任务对应关系。
|
||||
|
||||
## 四、尚未完成的功能
|
||||
|
||||
以下功能在当前代码中没有形成可验收的完整闭环,或仍处于设计/基础代码阶段:
|
||||
|
||||
1. **完整的租户隔离和资源继承模型**:核心列表、详情、下载、缓存、训练、推理、评测和导出接口已补齐基础租户/ACL校验;历史 NULL 租户归属仍需专项迁移。
|
||||
2. **项目取消后的正式数据迁移方案**:当前保留项目表作为兼容结构,正式删除项目设计前仍需为历史数据生成归属迁移和回滚脚本。
|
||||
3. **预签名上传策略的完整约束**:已完成 Content-Type、大小、过期时间、Key 白名单、资源写权限、对象存在性和真实 SHA-256 校验;定时清理过期未完成对象仍需接入运维调度。
|
||||
4. **MinIO 对象生命周期管理**:已提供软删除清理、失败记录/重试、孤儿扫描和管理员清理入口;自动定时执行策略需由部署环境接入。
|
||||
5. **Compute Agent 缓存治理**:已完成容量上限、LRU、TTL、保护窗口、版本/校验清单和状态查询;运行中任务动态保护和磁盘告警仍需结合生产指标系统。
|
||||
6. **统一的资源归档编排器**:训练、合并、导出、评测已纳入重启补偿轮询和 MinIO 归档;独立消息队列和大规模断点分片仍属于生产增强项。
|
||||
7. **模型导出完整流程**:已完成后端创建、节点准备、CPU 导出、量化参数、任务记录、制品血缘、归档轮询、权限和前端按钮;真实大模型多格式压力测试待专用环境执行。
|
||||
8. **流式和分片文件传输**:数据集单文件下载、Compute Agent 上传/下载已采用流式处理;多文件 ZIP 和超大对象的分片上传仍需继续增强。
|
||||
9. **生产级 MinIO 安全和高可用**:开发环境接入和故障快速失败已完成;默认密钥替换、TLS、网络隔离、Console 隔离、容量监控、备份恢复需在生产部署阶段实施。
|
||||
10. **完整的端到端测试和持续集成**:已新增前端构建、后端编译和存储安全测试 CI 基线;跨租户、多节点、多 GPU 并行压力和故障注入仍需扩展执行矩阵。
|
||||
11. **统一数据库迁移体系**:已形成 005/006/007 幂等增量迁移并加入运行时兼容执行;后续可再替换为 Alembic 等正式迁移工具以满足生产审计要求。
|
||||
|
||||
## 五、需要优化的功能
|
||||
|
||||
### 5.1 后端响应性能
|
||||
|
||||
- 页面列表接口需要避免每条记录重复查询用户、资源、MinIO 元数据和 Compute 节点状态。
|
||||
- MinIO 的 Bucket 检查、对象 Head 和预签名生成应使用连接复用、短期缓存和批量查询。
|
||||
- 训练、推理、评测页面不应通过过短间隔轮询大量详情接口,应按任务状态动态退避,并在完成后停止轮询。
|
||||
- 对 dashboard、节点健康、GPU 状态等高频数据应区分实时数据和缓存数据。
|
||||
- 后端日志轮询和健康检查日志需要继续降噪,仅在状态变化、失败或达到较长周期时输出。
|
||||
|
||||
### 5.2 前端加载和交互
|
||||
|
||||
- 列表页面应区分首屏 loading、刷新 loading、操作 loading,避免整页长时间无反馈。
|
||||
- 推理、评测、训练详情应使用统一的任务状态刷新策略和超时提示。
|
||||
- 前端仍有 FontAwesome 在线资源解析警告,应清理对外部网络文件的依赖,保证离线环境打开速度。
|
||||
- 应继续拆分首屏大体积 chunk,并减少一次性加载不相关页面组件。
|
||||
- GPU 选择组件需要明确显示空闲、占用、不可达、预留和已分配状态。
|
||||
- 错误提示应携带资源名称、节点名称、版本和下一步处理建议,减少只显示 500/404 的情况。
|
||||
|
||||
### 5.3 训练、推理和评测可靠性
|
||||
|
||||
- 所有任务创建前应执行同一套资源权限、版本存在性、MinIO 可用性和 GPU 原子分配校验。
|
||||
- 任务创建接口应支持幂等键,避免前端重复点击造成重复任务。
|
||||
- 节点不可达时应快速失败或进入可见的等待状态,不能让页面长时间无反馈。
|
||||
- 失败重试应区分网络瞬时失败、资源不足、模型文件缺失、参数错误和执行器失败。
|
||||
- 任务停止后必须释放 GPU 分配、推理端口、缓存锁和临时目录。
|
||||
|
||||
### 5.4 数据和模型一致性
|
||||
|
||||
- 每个对象都应保存大小、校验值、版本 ID、来源、创建者、租户和引用状态。
|
||||
- 数据库中的小文件内容和 MinIO 对象不能同时被当作可独立修改的主副本;需要明确唯一写入入口。
|
||||
- 数据集激活版本变更需要留下审计记录,并影响后续任务创建但不改变已创建任务。
|
||||
- 模型权重、Adapter、合并结果和导出结果需要形成完整血缘关系。
|
||||
|
||||
## 六、数据库和初始化脚本状态
|
||||
|
||||
当前 `backend/app/db/sql/000_full_init.sql` 已包含以下主要类别:
|
||||
|
||||
- 用户、模型、训练模型、模型血缘、模型产物、模型导出任务。
|
||||
- 数据集、数据集文件、数据集版本、数据集记录。
|
||||
- 算力节点、GPU、GPU 分配、调度锁、Compute Job。
|
||||
- 资源副本、资源同步任务、MinIO 对象、缓存任务。
|
||||
- 评测任务、评测维度、模型对比任务。
|
||||
- 租户、项目兼容表、项目成员、角色、会话、ACL。
|
||||
- 审批模板、审批实例、审批步骤、审计日志、留存策略。
|
||||
- 数据处理任务、源文件、预览项、处理结果、数据转换任务。
|
||||
|
||||
已确认的近期字段包括:
|
||||
|
||||
- `model_artifacts.storage_object_id`
|
||||
- `model_artifacts.storage_backend`
|
||||
- `dataset_files.storage_object_id`
|
||||
- `data_convert_tasks.output_content`
|
||||
- `data_convert_tasks.output_storage_object_id`
|
||||
- `data_convert_tasks.storage_backend`
|
||||
- `eval_tasks.report_storage_object_id`
|
||||
|
||||
离线包中的 `docker/offline/src/backend/app/db/sql/000_full_init.sql` 应与主工程初始化脚本保持同步。需要注意:
|
||||
|
||||
- 初始化 SQL 主要用于新数据库或新数据卷;已有数据库不能仅靠重启容器自动获得全部新字段。
|
||||
- 生产/测试数据库需要执行可追踪的迁移脚本,并在迁移前备份或生成结构快照。
|
||||
- `ensure_schema` 类运行时补字段逻辑只能作为兼容兜底,不能替代正式迁移。
|
||||
- 后续如果正式移除项目设计,需要先完成数据归属迁移,再决定是否删除历史表,不能直接从初始化 SQL 中删除表。
|
||||
|
||||
## 七、当前验证结果
|
||||
|
||||
### 7.1 2026-08-19 本轮按计划落地内容
|
||||
|
||||
- P0 MinIO 预签名上传已增加资源存在性、资源写权限、管理员基座模型写权限、资源版本和对象 Key 前缀校验;新增上传完成确认接口,会校验 MinIO 对象存在、大小和状态后再标记为可用。
|
||||
- 训练、评测、模型对比和权重合并任务会保存创建时的租户信息与资源版本快照,后续切换数据集激活版本不会改变已创建任务的输入版本。
|
||||
- 数据集、评测任务、训练任务和模型对比列表增加租户范围过滤;用户表、模型/数据集创建入口补齐租户归属;数据转换资源补充所有者权限映射。
|
||||
- Compute Agent 准备缓存后会回写资源副本的版本、MinIO 对象和本地路径;缓存支持可选容量上限、按访问时间淘汰非临时文件,并提供当前占用量和上限状态。
|
||||
- 训练产物、权重合并结果和评测报告增加 MinIO 归档、失败状态记录以及 Backend 重启后的补偿轮询;离线部署源码已同步对应逻辑。
|
||||
- Compute Agent 大文件上传已改为流式读取,避免将整个文件一次性读入内存;离线 Compute Agent 同步完成。
|
||||
- 增加 `005_storage_progress_migration.sql` 增量迁移脚本,并修复 `000_full_init.sql` 中旧数据库执行时索引早于字段补齐的问题;主工程和离线初始化脚本已同步。
|
||||
- 增加 `MINIO_PRESIGN_MAX_BYTES` 配置和上传 Content-Type 白名单;首次数据库 schema 检查移出 Compute Poller 的 Uvicorn 事件循环,避免远程 PostgreSQL 慢连接拖垮健康检查;轮询相同失败改为 300 秒限频记录,并跳过已标记 offline 节点。
|
||||
- 前端 `npm run build` 已通过;容器内 MinIO Key 越权校验专项测试为 `5 passed`,Backend 和 Compute Agent 重启后均为 healthy。
|
||||
|
||||
已完成的静态和局部验证:
|
||||
|
||||
- Backend 和离线 Backend 源码 `compileall` 检查通过。
|
||||
- MinIO 分层策略冒烟验证通过:小型 JSON/JSONL 可落数据库,小型二进制和超过阈值的内容进入 MinIO。
|
||||
- 主工程和离线包初始化 SQL 已做同步检查,内容一致。
|
||||
- 前端此前已完成 `npm run build` 类型错误修复,构建剩余问题主要是非阻断的资源/分包警告。
|
||||
- 已对训练日志、数据集 JSON/JSONL 统计、MinIO 资源准备等重点链路进行过问题修复。
|
||||
- 当前 WSL 运行验证中 Backend、Compute Agent、MinIO 均为 healthy;`gpu-node-02`(`172.25.179.69:19100`)连接、GPU 0 分配和任务执行均正常。`gpu-node-01` 的历史地址不可达,已通过健康检查标记为 offline,轮询器不再重复轮询其历史任务。
|
||||
|
||||
### 7.2 2026-08-19 gpu-node-02 真实流程验证
|
||||
|
||||
- 训练:使用 `qwen3.5-0.8B` + `test_data_0817`,任务 `ft_172a2da65140` 完成,GPU 0 使用期间可看到显存、利用率、温度和进程,结束后恢复 idle;24 个训练产物已归档 MinIO。
|
||||
- 资源快照:任务 `ft_d93b0fdae1c9` 创建时已保存数据集 `ds_8f6b8c5714c7` 的活动版本 `file_d550c2128722_v1`。
|
||||
- 训练曲线:任务 `ft_d93b0fdae1c9` 通过 `logging_steps=1` 生成 3 个 loss/epoch/learning-rate/grad-norm 数据点,并生成 `training_loss.png`;后端解析器已兼容带引号数字格式。
|
||||
- 权重合并:任务 `merge_1dc15a290810` 完成,基座模型路径、合并路径已回写,8 个合并模型文件归档 MinIO。
|
||||
- 推理:任务 `cmp_abdf0762869d` 在 GPU 0 加载 `qwen3.5-0.8B` 成功,对话接口返回正常;卸载后 GPU 恢复 idle。
|
||||
- 评测:任务 `eval_3c3f84263e23` 完成 2 条样本评测,报告、样本明细和基础指标已落库;GPU 恢复 idle。评审模型 HTTP 400 导致评审分数为 0,属于评审模型接口配置问题,算力评测链路本身已跑通。
|
||||
|
||||
### 7.3 多 GPU、MinIO 故障和跨用户权限专项验证
|
||||
|
||||
- 多 GPU 调度开发:新增 `gpu_reservations` 表,评测和推理在远程提交/加载前与训练统一纳入数据库原子预留;失败、停止、删除、节点不可达和卸载路径自动释放预留。当前 `gpu-node-02` 只有 GPU 0,已通过同卡“推理预留后评测抢占”测试,评测被明确拒绝,释放后 GPU 恢复 idle。多节点、多卡的真实并行测试待增加第二个可达节点和多卡节点后执行。
|
||||
- 调度锁优化:调度锁改为事务内持有并在提交前释放,避免一次调度成功后后续请求等待 30 秒 TTL;schema 初始化增加 PostgreSQL advisory lock,避免轮询器与首个请求并发初始化造成死锁。
|
||||
- MinIO 故障注入:停止 `yg-ft-minio` 后,`GET /modelTF/health` 返回 HTTP 200 且 `storage.status=unavailable`;恢复容器后返回 `storage.status=ready`。MinIO 客户端关闭默认重试链,故障健康探测耗时从约 6 秒降至约 0.3 秒。
|
||||
- 跨用户权限:创建临时用户 `qa_user_0819`,未授权访问管理员数据集返回 403;授予资源 `read/download` ACL 后列表和详情可访问;撤销 ACL 后再次返回 403;非管理员创建用户返回 403。测试用户已删除,未遗留测试 ACL 或 GPU 预留。
|
||||
- 用户管理接口已补齐管理员依赖,创建、列表、修改、删除和重置密码不再允许普通用户调用。
|
||||
|
||||
当前不能据此宣称“全量功能测试通过”:
|
||||
|
||||
- 现有部分自动化测试仍保留旧的本地文件或旧 MinIO 行为假设,需要按当前分层存储策略更新。
|
||||
- 本轮已完成当前 WSL Docker 容器健康检查、`gpu-node-02` 单节点真实流程、单卡冲突、MinIO 故障恢复和跨用户 ACL 专项验证;多节点、多卡的真实并行测试仍需要第二个可达节点和多卡节点。
|
||||
|
||||
- 本轮专项安全测试为 `5 passed`;全量 pytest 仍未执行完毕,需要按测试类别拆分并设置超时。
|
||||
|
||||
### 7.4 本轮 11 项未验证能力的补齐结果
|
||||
|
||||
- 租户管理接口已统一要求管理员身份;模型制品、模型血缘、导出任务、评测报告和 MinIO 资源清单均增加资源级访问校验。
|
||||
- 新增 `POST /modelTF/model-manage/export`,导出沿用节点选择、MinIO 缓存准备、GPU/调度约束和归档轮询;导出结果记录到 `model_export_jobs`,并建立导出制品与模型血缘。
|
||||
- 新增 `GET /modelTF/model-eval/{task_id}/report`,优先流式返回 MinIO 报告,历史任务无归档对象时返回数据库报告兼容结果。
|
||||
- 新增 `GET /modelTF/storage/resources/{resource_type}/{resource_id}/manifest`、管理员对象清理和孤儿扫描接口;预签名上传增加过期时间和真实 SHA-256 内容校验。
|
||||
- Compute Agent 增加缓存 TTL、缓存保护窗口和元数据清单;超过 TTL 的非保护缓存会在状态检查时清理,容量淘汰会跳过保护中的资源。
|
||||
- 数据集单文件下载改为 MinIO 流式传输,避免 Backend 一次性载入完整大文件;训练、合并、导出、评测仍由统一轮询器负责重启后的归档补偿。
|
||||
- 新增 `007_platform_completion.sql`,并已加入运行时兼容迁移;主工程和 `docker/offline/src` 的源码及初始化 SQL 已同步。
|
||||
- 以上为代码闭环和单节点验证;生产级 MinIO TLS/HA、第二节点/多卡并行压力测试、全量 CI 和历史项目数据正式迁移仍属于上线前专项工作。
|
||||
|
||||
## 八、下一阶段开发计划
|
||||
|
||||
### P0:安全与数据正确性
|
||||
|
||||
1. 为预签名上传补充 Content-Type、大小上限、过期对象清理和上传完成审计;当前已完成 Key、资源写权限、对象存在性和大小校验。
|
||||
2. 将资源版本快照继续接入推理服务启动、模型导出和缓存准备的所有入口,并增加版本切换回归测试。
|
||||
3. 完成模型导出接口的后端权限、租户范围和审计闭环。
|
||||
4. 补充历史数据租户归属迁移;当前新建资源和主要任务列表已完成租户过滤,历史 NULL 租户仍按兼容策略处理。
|
||||
|
||||
### P1:跨节点可靠性
|
||||
|
||||
1. 将当前资源副本字段升级为完整 manifest,记录每个文件的校验值、大小、目标节点路径和准备时间。
|
||||
2. 完善推理模型缓存的重启对账、失效版本清理和服务级重试;训练、合并、评测归档已具备补偿轮询基础。
|
||||
3. GPU 原子分配、异常回收和任务释放已完成基础闭环;下一步补充多节点重连对账及多卡并行压力测试。
|
||||
4. 增加缓存 TTL、运行任务保护、磁盘占用告警和可视化清理入口;当前已实现可选容量上限和按访问时间淘汰。
|
||||
5. 增加 MinIO 对象引用清理、孤儿对象扫描和软删除回收任务。
|
||||
|
||||
### P2:性能与用户体验
|
||||
|
||||
1. 优化页面列表接口和高频轮询,采用批量查询、短期缓存和动态退避。
|
||||
2. 将大文件上传/下载/复制改为流式或分片传输。
|
||||
3. 统一前端任务状态组件、loading、超时、重试和错误诊断信息。
|
||||
4. 处理前端离线资源警告,继续拆分首屏 chunk。
|
||||
5. 统一 GPU 状态展示及训练指标采样时间、单位和空值处理。
|
||||
|
||||
### P3:工程化和上线准备
|
||||
|
||||
1. 建立正式数据库版本迁移机制和离线升级脚本。
|
||||
2. 增加 CI:前端类型检查/构建、Backend 单元测试、Compute Agent 测试、SQL 新库初始化测试。
|
||||
3. 增加第二个可达节点/多卡节点后执行多节点端到端并行测试;MinIO 故障注入基础测试已完成。
|
||||
4. 完善 MinIO TLS、密钥管理、网络隔离、监控、备份和恢复方案。
|
||||
5. 建立生产运行手册,包括首次部署、升级、回滚、数据库迁移、对象清理和故障处理。
|
||||
|
||||
## 九、阶段验收标准
|
||||
|
||||
完成下一阶段后,至少应满足:
|
||||
|
||||
- 用户只能看到和操作其所属租户授权的模型、数据集、训练任务、推理服务和评测任务。
|
||||
- 任何任务创建都能明确记录用户、租户、资源版本、算力节点、GPU 列表和 MinIO 对象版本。
|
||||
- 同一个节点的同一张 GPU 不能被两个活动任务同时分配。
|
||||
- MinIO 临时不可用时,任务进入可解释的等待/失败状态,并能按策略重试,页面不会无限等待。
|
||||
- Backend 或 Compute Agent 重启后,任务、缓存、GPU 分配和归档状态可以对账恢复。
|
||||
- 训练、合并、评测和推理产物都能在 MinIO 中找到,并且可以通过权限校验后的接口下载或使用。
|
||||
- 删除资源后不会继续出现在普通列表中,关联对象能够按引用状态延迟清理并留下审计记录。
|
||||
- 新数据库初始化和已有数据库迁移后,所有业务接口不再因为缺表或缺字段启动失败。
|
||||
- 离线部署不依赖外部字体、图标或 CDN,前端首屏和核心业务操作在无网络环境下可用。
|
||||
|
||||
## 十、相关文件索引
|
||||
|
||||
- 平台架构:[platform-architecture-requirements.md](./platform-architecture-requirements.md)
|
||||
- 权限设计:[permissions-design.md](./permissions-design.md)
|
||||
- MinIO 与 Compute 缓存方案:[minio-compute-cache-plan.md](./minio-compute-cache-plan.md)
|
||||
- 平台治理菜单设计:[platform-governance-menu-design.md](./platform-governance-menu-design.md)
|
||||
- 数据处理设计:[data-process-design.md](./data-process-design.md)
|
||||
- 数据库初始化脚本:[../backend/app/db/sql/000_full_init.sql](../backend/app/db/sql/000_full_init.sql)
|
||||
- 离线部署目录:[../docker/offline](../docker/offline)
|
||||
|
||||
447
docs/20260812/权限开发进度.md
Normal file
447
docs/20260812/权限开发进度.md
Normal file
@@ -0,0 +1,447 @@
|
||||
# 权限开发进度
|
||||
|
||||
> 更新时间:2026-08-20
|
||||
> 适用范围:YG_FT 平台当前主工程、Backend、Frontend、Compute Agent、MinIO 资源访问及 `docker/offline/src` 离线源码。
|
||||
> 当前结论:权限 2.0 的基础能力已形成闭环;本轮继续完成 GPU/租户配额原子预留、租户成员邀请与接受、审批动作白名单/幂等/过期处理、GPU 节点与卡冲突校验,并补充租户详情页成员管理。在线数据库迁移已执行并核验,前端构建、后端静态检查、权限用例和基础容器健康检查通过。由于当前只有一个可达算力节点,跨租户双用户、第二节点/多卡并发、节点故障回收仍需后续专项验证,暂不能标记为“全部完成”。按工作包估算,核心权限开发约完成 94%,上线验收约完成 76%。
|
||||
|
||||
## 本轮 11 项完成情况(2026-08-19)
|
||||
|
||||
| 编号 | 权限能力 | 完成内容 | 状态 |
|
||||
|---|---|---|---|
|
||||
| 1 | 审批决策安全 | 审批人从当前会话获取,校验指定审批人、租户管理员、禁止申请人自审,记录审批审计 | 已完成 |
|
||||
| 2 | 资源访问申请 | 新增资源访问申请记录、申请权限/期限/理由、审批后自动写入 ACL、支持撤回和过期 | 已完成 |
|
||||
| 3 | 审批策略执行 | 按租户、动作、资源类型匹配策略;高风险操作审批通过后可一次性重试执行 | 已完成 |
|
||||
| 4 | 租户与项目隔离 | `tenant_members`、活跃租户校验、历史资源归属补齐、跨租户 ACL 主体校验、项目软删除 | 已完成 |
|
||||
| 5 | 用户与角色边界 | 禁用用户立即注销会话;租户成员支持 owner/admin/member/viewer,保护最后一个 owner | 已完成 |
|
||||
| 6 | 数据集权限入口 | 预览、来源、版本查询/创建/激活/删除、上传/编辑/下载统一接入资源动作权限 | 已完成 |
|
||||
| 7 | 模型和推理权限 | 训练模型合并/导出分别校验 execute/download;聊天、预加载、批量、卸载绑定授权模型或推理任务 | 已完成 |
|
||||
| 8 | GPU 分配申请 | 普通用户可提交 GPU 分配申请,审批通过后自动分配;管理员可直接分配 | 已完成 |
|
||||
| 9 | 租户配额申请 | 租户成员可提交配额变更申请,平台管理员审批后自动更新配额 | 已完成 |
|
||||
| 10 | 软删除与安全状态 | 资源删除撤销 ACL、取消待处理申请和审批;租户/项目采用软删除状态 | 已完成 |
|
||||
| 11 | 前端按钮与审计 | 审批决策、ACL 编辑、访问申请/撤回按权限显示;下载、导出、审批、GPU 等敏感操作补充结构化审计 | 已完成 |
|
||||
|
||||
### 数据库迁移结果
|
||||
|
||||
- 新增增量迁移:`backend/app/db/sql/009_permission_completion.sql`,可独立兼容旧库执行,并已在当前远程 PostgreSQL 执行成功。
|
||||
- 当前远程库已核验包含:`tenant_members`、`resource_access_requests`、审批策略/执行状态字段、审计结果字段、ACL 生命周期字段、项目/租户软删除字段、数据转换任务租户字段。
|
||||
- 已有用户已补齐到 `tenant_members`,当前迁移后共生成 5 条租户成员关系。
|
||||
- `backend/app/db/sql/000_full_init.sql` 已合并完整结构;离线目录继续只保留该完整脚本。
|
||||
|
||||
### 验证结果
|
||||
|
||||
- 后端相关模块 `python -m py_compile`:通过。
|
||||
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 路径提示和大 chunk 警告,无 TypeScript 错误。
|
||||
- `docker/offline/src` 的后端权限代码、Compute Agent、前端源码和完整初始化 SQL 已与主工程关键文件哈希一致。
|
||||
- 运行中的 Backend、Frontend、Compute API 容器已重启,健康检查通过;当前容器采用源码挂载方式,无需重建镜像即可加载本轮代码。已验证健康接口可用,未登录访问受保护接口返回 401;完整双用户、跨租户和多 GPU 回归仍待执行。
|
||||
|
||||
## 一、检查依据
|
||||
|
||||
本次按代码和初始化脚本逐项核对,主要依据如下:
|
||||
|
||||
- `docs/permissions-design.md`
|
||||
- `backend/app/core/auth.py`
|
||||
- `backend/app/api/v1/endpoints/platform.py`
|
||||
- `backend/app/modules/resource/router.py`
|
||||
- `backend/app/modules/approval/router.py`
|
||||
- `backend/app/modules/tenant/router.py`
|
||||
- `backend/app/modules/system/router.py`
|
||||
- `backend/app/db/platform_store.py`
|
||||
- `backend/app/db/sql/000_full_init.sql`
|
||||
- `frontend/src/stores/auth.ts`
|
||||
- `frontend/src/router/index.ts`
|
||||
- `frontend/src/views/governance/ResourceAclView.vue`
|
||||
|
||||
检查口径不是只判断“是否有接口”,还检查了接口是否验证当前用户、是否校验资源所有权和 ACL、是否校验租户边界、审批结果是否真正改变授权、前端按钮是否与后端动作一致。
|
||||
|
||||
## 二、改造前总体进度(历史基线)
|
||||
|
||||
| 能力模块 | 当前状态 | 结论 |
|
||||
|---|---|---|
|
||||
| 登录、密码、Token 会话 | 已实现基础能力 | 有会话过期、注销、状态校验和登录限流基础,仍需统一续期和失败审计 |
|
||||
| 平台角色与权限码 | 部分实现 | `admin/operator/viewer` 和业务权限码存在,但后端部分业务只校验登录,未统一校验权限码 |
|
||||
| 用户创建与管理 | 部分实现 | 管理员可创建、修改、删除和重置密码;租户范围、角色边界、邀请/申请流程未完成 |
|
||||
| 租户与配额 | 部分实现 | 租户 CRUD、配额和留存策略接口为管理员专属;缺少租户成员、租户管理员和统一隔离 |
|
||||
| 资源 ACL | 已实现基础能力 | 支持用户/角色的 `read/write/execute/download/delete/admin`,授权边界和跨租户限制不足 |
|
||||
| 资源申请 | 未完整实现 | 没有独立的资源访问申请对象,现有审批实例不能可靠地落地 ACL 或配额变更 |
|
||||
| 资源审批 | 部分实现且存在安全缺口 | 模板、实例、步骤和部分高风险操作存在;审批决策接口必须先修复越权问题 |
|
||||
| 基座模型权限 | 平台共享已实现 | 登录用户可查看和使用,上传/修改/删除限制管理员;缺少按租户/用途/配额的精细控制 |
|
||||
| 训练模型权限 | 部分实现 | 所有者、ACL、删除、合并、推理加载已有校验;导出下载动作和派生权限继承还不完整 |
|
||||
| 数据集权限 | 部分实现且入口不一致 | 列表、详情、删除、部分下载和训练/评测使用有校验;上传、编辑、预览、版本接口仍有缺口 |
|
||||
| 训练/评测/推理权限 | 部分实现 | 资源执行权和 GPU 分配已有基础校验;部分聊天、状态和历史入口没有统一鉴权 |
|
||||
| GPU 与节点权限 | 基础能力已实现 | 管理员分配、用户可用 GPU 过滤、原子预留和释放已存在;配额审批和跨节点回收对账仍需完善 |
|
||||
| 前端按钮级权限 | 部分实现 | 页面和菜单有基础控制,资源动作没有集中式权限决策,很多按钮依赖后端报错 |
|
||||
| 审计与软删除 | 部分实现 | 主要写操作有审计,资源软删除已覆盖若干表;actor、下载、拒绝和跨租户查询仍需统一 |
|
||||
|
||||
## 三、已经实现的内容
|
||||
|
||||
### 3.1 认证、角色与用户
|
||||
|
||||
- `get_current_user` 会校验 Bearer Token、用户存在性、用户状态和会话有效期;`sessions` 支持注销和过期时间。
|
||||
- `require_admin` 对管理员专属接口提供后端保护,受保护用户也具备管理员旁路能力。
|
||||
- 用户列表、创建、修改、删除、重置密码均已增加管理员依赖;用户可修改自己的密码。
|
||||
- 用户记录包含 `tenant_id`、`role`、`permissions`、`protected` 等字段,角色权限在初始化脚本中有基础种子数据。
|
||||
- 登录失败限流和旧明文密码升级已经具备基础实现。
|
||||
|
||||
### 3.2 租户、资源和 ACL
|
||||
|
||||
- `tenants` 表和租户 CRUD、配额、留存策略接口已经存在,当前接口统一要求管理员。
|
||||
- 数据集、模型、训练模型、评测任务等核心资源已经具备 `created_by`、`tenant_id` 或任务 payload 中的归属信息。
|
||||
- `acls` 表支持用户和角色两类授权主体,权限包括 `read`、`write`、`execute`、`download`、`delete`、`admin`。
|
||||
- 资源 ACL 查询和全量替换接口已经存在,资源所有者或管理员可以管理 ACL。
|
||||
- 列表接口对数据集、评测、训练和推理任务已增加“本人资源 + ACL 授权资源”的过滤逻辑。
|
||||
- MinIO 预签名、资源清单、对象列表、模型制品、模型血缘和评测报告等新入口已增加登录和资源访问校验。
|
||||
|
||||
### 3.3 训练、评测、推理和 GPU
|
||||
|
||||
- 训练创建会检查训练数据集的 `execute` 权限,并对用户选择的 GPU 执行分配校验。
|
||||
- 评测创建会检查训练模型、数据集的 `execute` 权限,并校验算力节点和 GPU。
|
||||
- 推理任务加载会检查任务及训练模型的执行权,同时使用 `gpu_reservations` 防止同一张 GPU 被并发占用。
|
||||
- GPU 分配接口和用户可用 GPU 查询已经存在,失败、停止、删除、节点异常等路径具备基础释放逻辑。
|
||||
- 训练模型删除、训练任务停止/删除、评测任务删除和推理任务删除已接入部分审批拦截。
|
||||
- 权重合并、导出、缓存准备和 MinIO 归档已经能记录模型、节点、租户和部分血缘信息。
|
||||
|
||||
### 3.4 审计和前端
|
||||
|
||||
- `audit_logs`、`operation_logs` 表及管理员查询/导出页面已经存在。
|
||||
- 资源 ACL 变更、租户管理、模型/数据集/任务等主要写操作已经接入审计或操作日志装饰器。
|
||||
- 前端路由和侧边栏对治理、组织、资源授权、审批、日志、算力节点等页面做了管理员限制。
|
||||
- `ResourceAclView` 已支持资源类型、用户/角色主体和多权限编辑。
|
||||
|
||||
## 四、改造前未实现或存在明显安全缺口(历史基线)
|
||||
|
||||
> 本节保留本轮改造前的检查快照,不代表当前状态。当前剩余问题以“十、当前仍需开发的功能”和“十一、下一步开发计划”为准。
|
||||
|
||||
以下项目属于必须继续开发的内容,优先级高于页面样式和性能优化。
|
||||
|
||||
### 4.1 审批决策不能直接信任请求参数
|
||||
|
||||
`backend/app/modules/approval/router.py` 的审批决策接口当前没有 `get_current_user` 依赖,并且从请求体读取 `approver_id`。调用方可以伪造审批人 ID,属于高风险越权问题。
|
||||
|
||||
必须改为:服务端从当前会话取得审批人;校验其是否为当前步骤指定审批人、租户管理员或平台管理员;校验当前步骤、实例状态和申请人不能自审;审批通过后再执行对应动作或写入 ACL。
|
||||
|
||||
### 4.2 资源申请流程尚未形成
|
||||
|
||||
当前有 `approval_templates`、`approval_instances`、`approval_steps`,但没有独立的资源访问申请记录,也没有统一的“申请资源 -> 审批 -> 授权/配额变更”事务流程:
|
||||
|
||||
- 创建审批实例时未统一验证资源是否存在、申请人是否属于资源租户、申请动作是否合法。
|
||||
- 审批实例批准后不会自动创建 ACL、GPU 分配或租户配额变更。
|
||||
- 不能表达申请权限、申请期限、申请原因、审批后的 ACL 权限和撤销时间。
|
||||
- 审批模板查询和详情接口没有完整的租户/角色范围控制。
|
||||
|
||||
### 4.3 租户隔离不是全量强制
|
||||
|
||||
- 当前用户只有单一 `tenant_id`,没有 `tenant_members` 或租户角色关系;无法支持租户管理员、跨租户平台管理员和成员邀请的清晰边界。
|
||||
- `filter_accessible_resource_ids` 和批量版本主要按 ACL/所有者过滤,不在统一函数中校验资源租户。
|
||||
- 数据集、评测等查询仍对 `tenant_id IS NULL` 做兼容放行;历史数据未完成归属迁移。
|
||||
- `trained_models()` 没有统一 tenant 参数,资源过滤依赖上层二次处理。
|
||||
- ACL 设置接口没有校验授权主体和资源是否属于同一租户,存在跨租户授权风险。
|
||||
- 新建模型、数据集、任务虽然多数会补默认租户,但缺少“租户必须存在且处于 active”的统一校验。
|
||||
|
||||
### 4.4 数据集权限入口不一致
|
||||
|
||||
核心列表、详情、删除、部分下载已校验,但以下文件/版本接口当前未统一接入当前用户和资源权限:
|
||||
|
||||
- 文件预览和记录来源查询。
|
||||
- 文件版本列表、版本内容查询。
|
||||
- 创建、激活、删除数据集文件版本。
|
||||
- 数据集上传接口没有统一的当前用户、写权限和租户校验。
|
||||
- 数据集编辑接口没有统一的当前用户和写权限校验。
|
||||
|
||||
此外,数据集下载和单文件下载目前检查的是 `read`,没有严格使用设计中的独立 `download` 权限。
|
||||
|
||||
### 4.5 模型使用、导出和推理入口不一致
|
||||
|
||||
- 基座模型按平台共享资源处理,登录用户可以查看和使用;但模型名称查询、本地模型列表和部分本地聊天/状态/卸载入口缺少统一鉴权。
|
||||
- 训练模型列表、详情、合并和加载已有 ACL 校验,但导出接口实际属于下载/外发动作,不能只检查 `execute`。
|
||||
- 评测报告下载当前检查 `read`,应单独检查 `download` 并记录下载审计。
|
||||
- 训练模型由训练任务生成时,尚未完整实现“基座模型 + 数据集授权关系”向派生模型权限和血缘策略的统一继承。
|
||||
- 推理聊天接口没有始终绑定到已授权的推理任务、模型资源和指定算力节点,存在绕过模型使用流程的风险。
|
||||
|
||||
### 4.6 用户创建和角色边界不完整
|
||||
|
||||
- 当前只有平台管理员创建用户,普通用户不能申请加入租户,也没有邀请、审批、禁用后会话清理的完整流程。
|
||||
- 用户只能直接挂在一个 `tenant_id` 上,不能表达一个用户属于多个租户或在不同租户中拥有不同角色。
|
||||
- 后端 `create_user` 对非管理员角色会归一为普通用户,前端出现的 `operator` 角色与后端实际行为可能不一致。
|
||||
- 创建用户时缺少租户存在性、租户状态、租户用户配额和角色白名单校验。
|
||||
- 管理员可以创建管理员角色,尚未区分平台管理员和租户管理员的授予权限。
|
||||
|
||||
### 4.7 前端按钮级权限没有闭环
|
||||
|
||||
- 前端已有菜单和路由权限基础,但 `hasPermission` 没有覆盖所有业务路由动作,部分业务页对已登录用户直接开放。
|
||||
- 资源级按钮主要靠资源对象中的所有者字段判断,没有统一使用后端返回的 ACL 决策。
|
||||
- 下载、执行、删除、授权、导出、审批等动作没有统一的 `can(resource, action)` 机制。
|
||||
- 即使按钮隐藏,前端 API 模块仍可能直接调用敏感接口;必须以后端鉴权为最终边界。
|
||||
|
||||
### 4.8 审计、软删除和权限拒绝记录不完整
|
||||
|
||||
- 部分模块的 `_actor` 直接保存 Authorization Token,而不是规范的用户 ID,导致审计主体不一致。
|
||||
- 访问、下载、导出、ACL 授权、审批拒绝、GPU 分配和权限拒绝没有全部统一记录租户、资源和结果。
|
||||
- `record_visit` 公开接口容易被伪造;如果继续保留匿名访问,应明确它不是安全审计日志。
|
||||
- 资源软删除已覆盖模型、训练模型、数据集、评测任务等主要表,但关联 MinIO 对象、ACL、审批和血缘的延迟清理策略还不完整。
|
||||
|
||||
## 五、需要优化的现有流程
|
||||
|
||||
### 5.1 统一权限模型
|
||||
|
||||
将当前分散的 `is_admin`、所有者判断、ACL 查询、租户判断、GPU 判断收敛为统一服务:
|
||||
|
||||
```text
|
||||
认证 -> 平台/租户角色 -> 租户边界 -> 资源所有权/ACL -> 动作权限 -> GPU/配额 -> 审批 -> 审计
|
||||
```
|
||||
|
||||
每个敏感接口都应明确动作,例如 `dataset.read`、`dataset.download`、`dataset.execute`、`trained_model.export`、`inference.load`、`gpu.reserve`,禁止只使用“已登录”作为业务权限。
|
||||
|
||||
### 5.2 重新设计资源申请和审批
|
||||
|
||||
推荐流程:
|
||||
|
||||
```text
|
||||
申请人选择资源和动作
|
||||
-> 校验申请人所属租户和基础权限
|
||||
-> 创建 resource_access_requests
|
||||
-> 根据租户/资源类型匹配审批策略
|
||||
-> 指定审批人完成审批
|
||||
-> 事务内写入 ACL/配额/GPU 预留
|
||||
-> 记录授权有效期、来源和审计
|
||||
```
|
||||
|
||||
审批拒绝、撤回、过期和资源删除都应撤销或冻结对应授权,不能仅修改审批实例状态。
|
||||
|
||||
### 5.3 模型、数据集、训练任务联合授权
|
||||
|
||||
训练、评测、推理分别使用以下最小权限:
|
||||
|
||||
| 场景 | 必须具备的权限 |
|
||||
|---|---|
|
||||
| 查看基座模型 | `model.read`;基座模型默认平台共享 |
|
||||
| 使用基座模型训练 | `model.execute` 或平台共享策略 + 数据集 `execute` |
|
||||
| 下载基座模型 | 单独的 `model.download`,默认不授予 |
|
||||
| 使用训练模型推理 | `trained_model.execute` |
|
||||
| 下载/导出训练模型 | `trained_model.download` 或 `trained_model.export` |
|
||||
| 使用数据集训练/评测 | `dataset.execute` |
|
||||
| 查看数据集 | `dataset.read` |
|
||||
| 下载数据集文件 | `dataset.download` |
|
||||
| 创建训练任务 | 上述资源权限 + 指定节点/GPU 使用权 + 租户配额 |
|
||||
|
||||
训练模型应保留创建者、租户、基座模型、数据集、训练任务和资源版本快照。派生模型默认只对创建者和同租户授权,不应因为基座模型共享而自动公开训练产物。
|
||||
|
||||
## 六、建议的数据库改造
|
||||
|
||||
当前 `000_full_init.sql` 已包含用户、角色、会话、ACL、租户、审批、审计、GPU 分配和 GPU 预留表,但要完成权限 2.0,建议增加或扩展以下结构。实施时必须同步主工程和 `docker/offline/src/backend/app/db/sql/000_full_init.sql`。
|
||||
|
||||
1. `tenant_members`:用户、租户、租户角色、状态、加入来源和有效期,解决一个用户多租户和租户管理员问题。
|
||||
2. `resource_access_requests`:申请人、租户、资源、动作、申请原因、申请权限、有效期、审批状态和最终授权记录。
|
||||
3. `acls` 增加 `tenant_id`、`granted_by`、`source_request_id`、`expires_at`、`revoked_at`,保留授权来源和自动过期能力。
|
||||
4. `approval_templates` 增加 `tenant_id`、`action`、`resource_type`、`scope`、`status`;审批步骤增加主体类型、主体 ID 和租户范围。
|
||||
5. 资源表统一补齐非空租户策略、归属用户、软删除字段和必要索引;历史 NULL 数据通过一次性迁移处理。
|
||||
6. `audit_logs` 增加结果、拒绝原因、request_id、认证会话和结构化 detail,避免把 Token 当作 actor。
|
||||
|
||||
不建议把完整 ACL 和审批状态继续塞入模型、数据集或任务 JSON 字段;JSON 可保留兼容信息,但权限判断应以结构化表为准。
|
||||
|
||||
## 七、历史开发计划(已执行)
|
||||
|
||||
### 第一阶段:P0 安全修复
|
||||
|
||||
- 修复审批决策鉴权和审批人伪造问题。
|
||||
- 补齐数据集文件/版本/上传/编辑接口权限。
|
||||
- 补齐本地模型聊天、状态、卸载、模型名称查询等历史入口鉴权。
|
||||
- 统一 `download`、`execute`、`write`、`delete` 动作检查。
|
||||
- 限制 ACL 授权范围,校验主体存在、同租户和资源归属。
|
||||
- 增加至少 20 个后端权限回归用例,覆盖未登录、本人、同租户他人、跨租户、管理员和已撤销 ACL。
|
||||
|
||||
### 第二阶段:P1 租户和资源申请
|
||||
|
||||
- 引入租户成员和租户角色,明确平台管理员、租户管理员、成员、只读成员边界。
|
||||
- 开发资源访问申请接口和前端申请页面。
|
||||
- 重做审批模板匹配、审批人校验、审批结果落地 ACL、有效期和撤销流程。
|
||||
- 将配额申请、GPU 分配申请、模型导出和跨用户删除纳入审批策略。
|
||||
- 新资源强制租户归属并完成历史数据迁移。
|
||||
|
||||
### 第三阶段:P1 联合资源权限
|
||||
|
||||
- 建立模型/数据集/训练任务/评测任务/推理任务的统一资源授权服务。
|
||||
- 训练前一次性校验基座模型、数据集、节点、GPU 和租户配额。
|
||||
- 训练模型生成时写入血缘和权限来源;推理、评测、合并、导出使用同一套动作权限。
|
||||
- 版本快照、MinIO 对象、算力节点本地缓存沿用同一资源授权结果。
|
||||
|
||||
### 第四阶段:P2 前端和审计
|
||||
|
||||
- 增加统一 `can(resource, action)` 和按钮权限组件。
|
||||
- 授权和审批界面使用用户/租户/资源中文名称,展示授权来源、有效期和审批状态。
|
||||
- 规范审计 actor、租户、请求 ID、资源、动作、结果和失败原因。
|
||||
- 将权限不足、审批中、资源过期、MinIO 不可用分别展示,避免全部显示为通用 500。
|
||||
|
||||
### 第五阶段:P3 测试与上线
|
||||
|
||||
- 新库初始化、增量迁移、离线目录同步和前端构建全部纳入 CI。
|
||||
- 执行跨租户、跨用户、ACL 撤销、审批越权、软删除、MinIO 故障和 GPU 冲突专项测试。
|
||||
- 在第二个可达节点或多卡节点到位后,执行多节点、多 GPU 的权限和并发测试。
|
||||
- 补充权限运维手册:新建租户、创建用户、授权模型/数据集、审批、撤销权限、审计追踪和故障恢复。
|
||||
|
||||
## 八、验收标准
|
||||
|
||||
- 未登录用户不能访问任何模型、数据集、任务、聊天、版本、下载和审批接口。
|
||||
- 用户只能访问所属租户中本人拥有或被明确授权的资源;跨租户 ACL 默认禁止。
|
||||
- 查看、下载、执行、编辑、删除和授权是独立动作,不能用 `read` 替代所有动作。
|
||||
- 普通用户不能伪造审批人、审批其他租户资源或审批自己的申请。
|
||||
- 训练、评测和推理创建必须同时满足资源权限、GPU 权限、节点权限和租户配额。
|
||||
- 审批通过后才产生授权,审批拒绝、撤回、过期和资源删除后授权不会继续生效。
|
||||
- 基座模型共享不等于训练产物共享;训练后的模型和数据集必须按租户、所有者和 ACL 控制。
|
||||
- 前端隐藏按钮不能替代后端校验,直接调用 API 也必须返回明确的 401/403。
|
||||
- 所有敏感操作可通过用户、租户、资源、动作和请求 ID追溯到审计记录。
|
||||
|
||||
## 九、历史实施记录(已完成)
|
||||
|
||||
本轮已完成权限闭环的代码实现:
|
||||
|
||||
1. 统一校验当前会话、会话过期、退出状态和可用租户范围。
|
||||
2. 补齐模型、数据集、训练、评测、推理、数据处理、数据转换、算力、存储和审计入口的登录及模块权限。
|
||||
3. 新增 `tenant_members`,新建用户、项目、数据集、训练任务和数据处理任务写入当前租户与创建者。
|
||||
4. ACL 写入校验主体存在性、状态、租户边界、有效期和撤销状态;普通所有者不能授予 `delete/admin` 或跨租户权限。
|
||||
5. 新增 `resource_access_requests`;审批人由当前会话确定,禁止伪造审批人和申请人自审;审批通过后才落 ACL。
|
||||
6. 训练、评测和推理统一校验数据集、基座模型、训练模型、任务、节点和 GPU 使用权限;下载和导出使用独立的 `download` 权限。
|
||||
7. 前端认证 store 新增 `can(resource, action)`,模型管理和审批页面按权限显示操作按钮,后端 401/403 仍是最终防线。
|
||||
8. 新增 `009_permission_completion.sql`;主工程与离线目录的完整初始化 SQL 已同步且 SHA-256 一致,离线目录只保留完整初始化脚本。
|
||||
|
||||
### 本轮验证
|
||||
|
||||
- 后端权限相关文件 `py_compile` 通过。
|
||||
- 前端 `npm run build` 通过;仅保留已有字体路径和 chunk size 警告。
|
||||
- 当前 WSL 容器已确认 Backend、Frontend、Compute、Redis、MinIO 均运行;基础健康和未登录拦截已验证,历史治理测试夹具与当前鉴权/数据库行为不完全兼容,不能替代新的权限专项回归。
|
||||
|
||||
### 上线前验证
|
||||
|
||||
- 第二个可达节点或多卡节点到位后的多租户、多 GPU 并行压力测试。
|
||||
- 对已执行的 `009_permission_completion.sql` 进行旧数据租户归属、ACL、审批和软删除记录对账。
|
||||
- 更新 Backend/Frontend 容器后重新执行治理测试和权限专项测试。
|
||||
|
||||
## 十、当前复核结论(2026-08-19)
|
||||
|
||||
### 10.1 已完成的基础能力
|
||||
|
||||
本轮 11 项权限改造已经形成基础闭环:会话和用户状态校验、租户成员关系、资源 ACL、资源访问申请、审批决策安全、模型/数据集/训练/评测/推理入口权限、GPU 分配申请、配额申请、软删除和前端基础按钮控制均已落地;数据库迁移和完整初始化 SQL 已同步到主工程及离线目录。
|
||||
|
||||
这些能力可以作为后续完善的基础,但“接口存在”不等于“所有资源和所有异常路径均已达到上线标准”。尤其是密钥暴露、配额实际拦截、资源列表一致性和专项测试仍需要继续处理。
|
||||
|
||||
### 10.2 仍需开发的功能
|
||||
|
||||
| 优先级 | 功能 | 当前缺口 | 处理结论 |
|
||||
|---|---|---|---|
|
||||
| P0 | 模型密钥和敏感信息保护 | 模型列表、详情、名称查询、创建和更新响应已移除真实 `api_key`,仍需继续排查任务详情、日志和其他敏感配置输出 | 基础闭环已完成;继续做全量敏感字段扫描和受控密钥管理 |
|
||||
| P0 | 统一资源动作策略 | 已增加资源动作白名单和 `export -> download` 归一化,但各业务入口仍需逐步迁移到统一授权服务 | 第一阶段已完成;继续完成全量入口收敛 |
|
||||
| P0 | 数据转换、数据处理和存储权限一致性 | 部分列表、文件、预览、版本、缓存和 MinIO 对象入口仍需逐接口核对“租户 + 所有者/ACL + 动作” | 必须完成全量入口审计,尤其是 `read/download/execute/write/delete` 的区分 |
|
||||
| P0 | 审计失败链路 | 审计装饰器已记录失败结果、原因、请求 ID、会话 ID 和租户;手工审计入口仍需继续统一 | 基础闭环已完成;继续补齐所有权限拒绝和异常入口 |
|
||||
| P1 | 租户成员生命周期 | 已有成员表和角色,但缺少邀请、加入申请、审批、过期、移除和前端租户切换的完整流程 | 需要开发,明确平台管理员与租户管理员的授予边界 |
|
||||
| P1 | 配额强制执行 | 配额申请和审批已实现,但训练、评测、推理、存储等资源消耗尚未全部进行原子配额检查和扣减 | 需要开发配额使用量/预留量/释放量账本,不能只保存配额配置 |
|
||||
| P1 | GPU 分配强校验 | 申请链路已实现,但分配前仍需统一校验节点状态、GPU 存在性、冲突、租户配额和释放对账 | 需要开发原子预留、超时回收和节点故障对账 |
|
||||
| P1 | 审批策略完整性 | 需要严格限制动作白名单、资源类型、模板作用域和重复申请;过期处理不应只依赖查询触发 | 需要补充定时过期、幂等键、执行失败重试和策略管理边界 |
|
||||
| P1 | 派生模型和数据血缘授权 | 基座模型、数据集、训练模型之间已有部分血缘,但权限来源、版本快照和派生资源默认授权规则还不够统一 | 需要固化“创建者 + 租户 + 显式 ACL”,禁止共享基座模型自动公开训练产物 |
|
||||
| P1 | 用户软删除和对象清理 | 用户及部分关联关系仍有物理删除风险;MinIO 对象、ACL、审批、缓存的异步清理缺少统一编排 | 需要补齐软删除、撤销、延迟清理和失败重试 |
|
||||
| P2 | 前端资源级权限体验 | 已有菜单/按钮级基础控制,但缺少统一 `can(resource, action)`、授权来源、有效期、审批中和 403 状态展示 | 需要开发统一权限组件和错误状态处理,后端校验仍是最终边界 |
|
||||
| P2 | 权限专项测试与上线检查 | 基础构建、静态检查、健康接口已验证,尚未完成双用户、跨租户、撤销、过期、MinIO 故障、GPU 冲突的全流程矩阵 | 必须补充自动化测试、迁移回归和离线部署验收 |
|
||||
|
||||
### 10.3 需要优化的设计
|
||||
|
||||
1. **从“角色判断”改为“动作授权”**:统一使用 `resource_type + resource_id + action + tenant_id + actor` 判断,平台管理员只作为明确的管理范围,不再作为各业务模块的隐式旁路。
|
||||
2. **区分平台角色和租户角色**:`users.role` 只表达平台级角色,`tenant_members.role` 表达租户内角色;禁止通过租户成员关系授予平台管理员权限。
|
||||
3. **区分查看、下载、执行、编辑、删除、授权**:`read` 不能替代 `download`,`execute` 不能替代 `export`,高风险动作必须绑定审批和审计。
|
||||
4. **统一资源列表和详情规则**:列表、详情、文件、版本、预览、缓存、下载和导出必须调用同一授权服务,避免“列表看不到但接口可访问”或“列表能看到但操作必然 403”。
|
||||
5. **权限与配额采用预留模型**:任务提交时原子预留 GPU、显存、并发数和存储额度,任务完成、失败、取消和节点失联时统一释放或对账。
|
||||
6. **审批采用可执行状态机**:申请、审批、拒绝、撤回、过期、执行中、执行失败、已执行状态分离;审批结果应有幂等执行记录,避免重复授权或重复分配。
|
||||
7. **敏感字段默认拒绝返回**:API key、对象内部凭据、节点访问凭据不能随普通资源详情返回;日志、审计和错误信息也不能泄露 Token、密码或完整连接串。
|
||||
8. **安全审计与访问统计分离**:权限成功、拒绝、下载、导出、授权、审批和异常进入不可篡改审计;页面访问统计单独存储,避免污染安全审计记录。
|
||||
|
||||
## 十一、下一步开发计划
|
||||
|
||||
### 阶段一:P0 安全封堵与统一策略
|
||||
|
||||
1. 对模型列表、详情、名称查询及相关 DTO 做 API key/凭据脱敏,增加“仅后端内部读取”的封装。(基础闭环已完成,继续扫描任务和日志输出)
|
||||
2. 建立统一 `authorize(resource, action)` 服务,定义动作白名单和平台管理员、租户管理员、所有者、ACL 的判定顺序。(已完成动作白名单,继续迁移全部入口)
|
||||
3. 逐项审计平台、数据处理、数据转换、存储、MinIO、模型、数据集、训练、评测、推理的列表、详情、预览、下载、导出、缓存和删除入口。
|
||||
4. 统一记录权限成功、拒绝和异常审计,补齐 `tenant_id`、`resource_id`、`action`、`request_id`、`session_id`、`reason` 和 `result`。(装饰器基础闭环已完成,继续覆盖手工记录入口)
|
||||
|
||||
### 阶段二:租户成员、审批和配额闭环
|
||||
|
||||
1. 开发租户邀请/加入申请/审批/移除/过期流程及前端租户切换。
|
||||
2. 为审批模板增加动作和资源类型白名单、租户作用域、幂等键、过期任务和执行失败重试。
|
||||
3. 建立配额预留账本,训练、评测、推理、存储和 GPU 任务提交前统一原子检查;任务终态和故障恢复统一释放。
|
||||
4. 完善 GPU 节点、GPU 卡、租户、用户和任务的占用关系校验,覆盖冲突、超时、节点不可达和服务重启恢复。
|
||||
|
||||
### 阶段三:资源血缘和生命周期
|
||||
|
||||
1. 固化基座模型、数据集、数据处理结果、训练任务、训练模型、评测和推理任务的资源血缘及版本快照。
|
||||
2. 明确派生模型默认授权规则,训练产物不因基座模型共享而自动对外公开。
|
||||
3. 补齐用户、租户、资源、ACL、审批、MinIO 对象和本地缓存的软删除、撤销、延迟清理和失败重试。
|
||||
|
||||
### 阶段四:前端权限体验与测试
|
||||
|
||||
1. 开发统一资源级权限组件,按动作隐藏/禁用按钮,并展示授权来源、有效期、审批状态和明确的 401/403 原因。
|
||||
2. 将审批、ACL、审计列表中的用户、租户、资源 ID 映射为可读名称,同时保留 ID 作为详情字段。
|
||||
3. 编写并执行权限专项测试矩阵:未登录、同租户成员、资源所有者、ACL 授权、跨租户、禁用用户、会话注销、审批撤回/过期、软删除、MinIO 故障、GPU 冲突和配额不足。
|
||||
4. 在第二个可达节点或多卡节点准备后执行多节点、多 GPU 并发及故障恢复测试;完成主工程与 `docker/offline/src` 的源码、初始化 SQL、迁移和部署文档一致性检查。
|
||||
|
||||
## 十二、下一阶段完成标准
|
||||
|
||||
- 普通资源接口不再返回 API key、密码、Token 或节点访问凭据。
|
||||
- 所有资源入口都经过统一的租户边界和动作授权,跨租户访问返回明确 403。
|
||||
- 训练、评测、推理创建同时满足资源权限、GPU 预留和租户配额,失败时不会留下孤儿占用。
|
||||
- 审批只能由合法审批人执行,申请人不能自审;重复回调不会重复授权、分配或扣减配额。
|
||||
- 权限拒绝、下载、导出、授权、审批和异常均能按用户、租户、资源和请求 ID追溯。
|
||||
- 主工程和离线目录初始化新库均无缺表、缺字段;迁移可重复执行且不破坏既有数据。
|
||||
- 权限专项自动化测试通过,且完成至少一次双用户、跨租户和 MinIO 故障场景的真实容器验证。
|
||||
|
||||
## 十三、上一阶段权限闭环开发结果(2026-08-20)
|
||||
|
||||
本轮围绕 P0 安全封堵完成了一个可验证的权限闭环:
|
||||
|
||||
1. **模型凭据不出接口**:模型列表、详情、按名称查询、创建、更新和用途更新响应统一经过公开 DTO 脱敏,移除 `api_key`、密码、Token 等字段,仅返回 `api_key_configured` 布尔状态;后端内部评测、数据生成仍使用数据库中的真实配置。
|
||||
2. **编辑密钥不被意外清空**:前端编辑在线模型时不回填真实密钥,留空表示保留已有配置,只有管理员主动输入新值时才提交替换。
|
||||
3. **资源动作统一入口**:增加资源动作白名单 `read/write/execute/download/export/delete/admin`,并将 `export` 统一归一到下载权限,非法动作默认拒绝,避免把模块权限误当成资源权限。
|
||||
4. **失败审计闭环**:审计装饰器对成功和异常分别记录,失败记录包含结果、失败原因、租户、请求 ID、会话 ID和耗时,并对异常中的常见凭据进行脱敏。
|
||||
5. **访问统计受控**:模块访问统计只接受平台已登记的模块名,不能通过请求参数向安全审计表写入任意动作;审计 CSV 导出改为标准 CSV 编码,并补充结果、原因、请求和会话字段。
|
||||
6. **离线版本同步**:上述后端权限代码、前端模型编辑代码和权限安全回归用例已同步到 `docker/offline/src`;本轮未新增数据库字段,因此 `000_full_init.sql` 无需变更。
|
||||
|
||||
### 上一阶段验证结果
|
||||
|
||||
- 后端权限相关模块 `python -m py_compile`:通过。
|
||||
- WSL Backend 容器执行权限安全用例:8 passed;仅有 pytest 缓存目录只读警告。
|
||||
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 路径和 chunk size 警告。
|
||||
- 容器接口验证:未登录访问模型接口返回 401;管理员访问模型列表/详情时响应不包含 `api_key`,仅返回 `api_key_configured`。
|
||||
- Backend 容器已重启并加载当前源码;数据库无需迁移。
|
||||
|
||||
### 上一阶段未覆盖的范围(已在第十四节继续处理)
|
||||
|
||||
本轮没有声称完成配额账本、GPU 原子预留、租户邀请/加入申请、审批定时过期、所有资源入口的逐接口审计,以及第二节点/多 GPU 的真实并发测试;这些仍按“十一、下一步开发计划”执行。
|
||||
|
||||
## 十四、本轮继续开发结果(2026-08-20)
|
||||
|
||||
### 已完成
|
||||
|
||||
1. 新增 `tenant_quota_reservations` 配额预留账本,支持按租户统计 GPU 预留量、原子限制 GPU 配额,以及任务完成、失败、停止、删除和节点故障时释放预留。
|
||||
2. 训练、评测和推理统一接入租户 GPU 配额预留;评测/推理使用的 `gpu_reservations` 与配额账本在同一事务内创建或释放,避免只释放算力卡而遗留配额占用。
|
||||
3. 租户成员支持邀请、接受、过期、角色更新和移除;邀请不允许授予 `owner`,成员状态和租户有效性由后端校验,租户详情页补充成员管理和 GPU 配额使用量展示。
|
||||
4. 审批动作增加白名单,非法动作拒绝创建;相同申请人在同一资源上的待审批申请幂等复用;审批实例读取时自动处理过期状态,资源访问申请也避免重复创建。
|
||||
5. GPU 分配增加节点启用状态、GPU 卡存在性、用户 active 状态和同卡跨用户冲突校验;冲突返回 409,不再静默覆盖或产生重复授权。
|
||||
6. 完整初始化 SQL 增加配额预留表和索引,新增 `010_permission_quota_membership.sql` 增量迁移;主工程相关源码、前端租户 API/页面和 SQL 已同步到离线源码目录。
|
||||
|
||||
### 本轮验证
|
||||
|
||||
- WSL Backend 容器重启后,`tenant_quota_reservations` 可正常查询,默认租户配额使用量返回正常。
|
||||
- WSL Backend 容器执行 `test_permission_security.py`:3 passed。
|
||||
- 后端相关文件 `python -m py_compile`:通过。
|
||||
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 资源路径和大 chunk 警告。
|
||||
|
||||
### 必须后续验证的场景
|
||||
|
||||
1. 创建第二个 active 用户和第二个租户,验证邀请接受、租户切换、跨租户资源访问均按预期返回 401/403。
|
||||
2. 将租户 GPU 配额设为 1,同时提交两个需要 GPU 的训练/评测/推理任务,确认第二个任务被拒绝;第一个任务终态后确认配额可再次使用。
|
||||
3. 在同一多卡节点上让两个用户申请同一张卡,确认审批执行阶段冲突返回 409,另一张空闲卡仍可正常分配。
|
||||
4. 构造过期审批、重复提交、审批拒绝/撤回,确认不会重复创建 ACL、GPU 分配或配额预留。
|
||||
5. 准备第二个可达节点或多卡节点,执行训练、评测、推理的多节点/多 GPU 并发和节点失联回收测试。
|
||||
6. 注入 MinIO 故障,确认任务失败后 GPU 与租户配额均能释放,恢复 MinIO 后可以重新提交任务。
|
||||
|
||||
### 下一步计划
|
||||
|
||||
- 补齐数据处理、数据转换、MinIO 对象、缓存、版本和报告下载等剩余资源入口的逐接口动作授权审计。
|
||||
- 将用户物理删除改为统一软删除,并编排成员关系、ACL、审批、MinIO 对象和本地缓存的撤销与延迟清理。
|
||||
- 将上述后续验证场景加入自动化测试矩阵和离线部署验收脚本;在多节点条件满足后更新本文件的上线验收进度。
|
||||
38
docs/database-migration.md
Normal file
38
docs/database-migration.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 数据库迁移说明
|
||||
|
||||
## 当前迁移文件
|
||||
|
||||
- 新库初始化:`backend/app/db/sql/000_full_init.sql`
|
||||
- 已有数据库增量迁移:`backend/app/db/sql/005_storage_progress_migration.sql`
|
||||
- GPU 预留迁移:`backend/app/db/sql/006_gpu_reservations.sql`
|
||||
- 平台闭环迁移:`backend/app/db/sql/007_platform_completion.sql`
|
||||
- 离线部署使用:`docker/offline/src/backend/app/db/sql/000_full_init.sql`
|
||||
|
||||
## 执行方式
|
||||
|
||||
```bash
|
||||
for migration in 005_storage_progress_migration.sql 006_gpu_reservations.sql 007_platform_completion.sql; do
|
||||
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f "backend/app/db/sql/$migration"
|
||||
done
|
||||
```
|
||||
|
||||
迁移前应完成数据库备份,并保存以下结构快照:
|
||||
|
||||
```sql
|
||||
SELECT table_name, column_name, data_type
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
ORDER BY table_name, ordinal_position;
|
||||
```
|
||||
|
||||
## 本次迁移内容
|
||||
|
||||
- 为算力节点资源副本增加 `version_id` 和 `storage_object_id`,用于记录 MinIO 版本与本地缓存对应关系。
|
||||
- 补齐 `storage_objects.metadata`、模型产物、数据集文件和数据转换任务的 MinIO 字段。
|
||||
- 补齐评测任务软删除、创建者、租户和报告对象字段。
|
||||
- 增加活动评测任务、资源副本和 MinIO 对象索引。
|
||||
- 增加 GPU 预留表,统一训练、推理、评测的卡级占用约束。
|
||||
- 增加模型导出创建者/租户/归档状态字段。
|
||||
- 增加 MinIO 对象软删除清理、缓存版本校验和访问保护字段及清理任务表。
|
||||
|
||||
`000_full_init.sql` 已包含相同的幂等变更,新增数据库直接执行初始化脚本即可;已有数据库不要依赖容器重启自动完成迁移。
|
||||
@@ -110,7 +110,7 @@
|
||||
| 平台治理 - 组织与权限 | 用户、角色、租户与配额 | `/organization` |
|
||||
| 平台治理 - 资源授权 | 数据集、模型等资源 ACL | `/resource-acl` |
|
||||
| 平台治理 - 审批中心 | 待审批请求、审批历史与策略 | `/approval-instances` |
|
||||
| 系统设置 - 运行日志 | 系统/训练日志;管理员可查看审计记录、操作诊断 | `/logs` |
|
||||
| 系统设置 - 运行日志 | 普通用户查看本人操作记录;管理员可查看系统/训练日志、审计记录和全量操作诊断 | `/logs` |
|
||||
| 算力资源 - 算力节点 | GPU 分配与管理 | `/compute` |
|
||||
|
||||
### 2.4 重置用户密码
|
||||
|
||||
@@ -131,7 +131,9 @@
|
||||
| `compute` | `/compute` | 算力节点 |
|
||||
| `hardware` | `/hardware` | 平台性能 |
|
||||
| `logs` | `/logs`, `/training-log/:id` | 查看日志 |
|
||||
| `user-settings` | `/organization`, `/resource-acl`, `/approval-instances`, `/logs` | 平台治理和运行日志(管理员) |
|
||||
| `user-settings` | `/organization`, `/resource-acl`, `/approval-instances` | 平台治理管理功能(管理员) |
|
||||
|
||||
运行日志采用分层访问模型:拥有 `logs` 权限的普通用户可以进入 `/logs`,页面只展示其本人产生的操作记录,后端按当前用户 ID 强制过滤,忽略普通用户传入的跨用户筛选条件。管理员在同一入口保留系统日志、训练日志、审计记录和全量操作诊断能力。
|
||||
|
||||
---
|
||||
|
||||
|
||||
191
docs/当前项目开发进度.md
191
docs/当前项目开发进度.md
@@ -1,6 +1,6 @@
|
||||
# 当前项目开发进度
|
||||
|
||||
> 评估基线:2026-08-19 当前工作区代码、数据库初始化脚本、Docker 部署文件、前端页面和现有设计文档。
|
||||
> 评估基线:2026-08-20 当前工作区代码、数据库初始化脚本、增量迁移脚本、Docker 部署文件、前端页面和 WSL 容器验证结果。
|
||||
>
|
||||
> 本文以代码实际情况为准。设计文档中已经提出但代码没有形成完整闭环的内容,统一标记为“部分完成”或“未完成”。
|
||||
|
||||
@@ -24,14 +24,16 @@ FastAPI Backend API
|
||||
|
||||
| 范围 | 当前状态 | 结论 |
|
||||
|---|---|---|
|
||||
| 平台基础架构 | 基本完成 | 前后端、数据库、Redis、MinIO、Compute Agent 和 Docker 部署均已具备 |
|
||||
| 核心业务闭环 | 基本可用 | 数据集、数据处理、数据转换、训练、模型、推理、评测均有页面和接口 |
|
||||
| 平台基础架构 | 已完成开发基线 | 前端、Backend、PostgreSQL、Redis、MinIO、Compute Agent 和离线 Docker 编排均已具备 |
|
||||
| 核心业务闭环 | 基本可用 | 数据集、数据处理、数据转换、训练、模型、推理、评测主要流程已闭环 |
|
||||
| 多算力节点 | 部分完成 | 节点选择、GPU 分配和缓存准备已经接入,跨节点一致性和失败恢复仍需加强 |
|
||||
| 权限治理 | 部分完成 | 登录、角色、权限码、ACL、审批、审计已实现,但完整的租户/项目隔离尚未闭环 |
|
||||
| MinIO 统一存储 | 部分完成 | 大文件和模型已接入,仍存在兼容性的本地路径和部分数据双写/回退路径 |
|
||||
| 生产可靠性 | 未完成 | 缓存容量治理、对象清理、流式上传、归档重试、备份和高可用尚未完成 |
|
||||
| 权限治理 | 功能闭环基本完成 | 登录、角色、权限码、ACL、审批、资源申请、GPU 申请和审计已实现,历史数据迁移与全量回归待完成 |
|
||||
| MinIO 统一存储 | 基本完成 | 大文件、模型、产物、报告和节点缓存已接入;小型内容保留数据库属于明确的性能策略 |
|
||||
| 生产可靠性 | 部分完成 | 重试、补偿、缓存治理和故障快速失败已实现,生命周期运维、高可用、备份和大规模压力测试未完成 |
|
||||
| 前端体验 | 基本可用,需优化 | 构建问题已持续修复,但页面响应等待、首屏体积和部分错误提示仍需优化 |
|
||||
|
||||
当前结论:项目已经进入“核心功能闭环后的专项验证和上线前加固阶段”,不再是单纯的功能骨架开发。尚不能宣称生产可上线,主要风险集中在历史数据迁移、跨节点多 GPU 并发、评测指标质量、MinIO 运维和全量回归测试。
|
||||
|
||||
## 二、已完成的功能
|
||||
|
||||
### 2.1 平台基础与部署
|
||||
@@ -55,6 +57,7 @@ FastAPI Backend API
|
||||
- 已建立资源 ACL 管理页面和相关接口,可对用户或角色授予资源级权限。
|
||||
- 已建立审批模板、审批实例和审批步骤的基本数据模型与页面。
|
||||
- 已建立运行日志、审计日志查询页面及审计记录写入机制。
|
||||
- “运行日志”已按分层模型实现:普通用户只查看本人操作日志,管理员查看系统日志、训练日志、审计记录和全量操作诊断。
|
||||
- 已加入软删除相关字段和部分删除逻辑,避免直接物理删除业务资源。
|
||||
|
||||
### 2.3 算力节点与 GPU 资源
|
||||
@@ -141,72 +144,61 @@ FastAPI Backend API
|
||||
|
||||
- Compute Agent 仍有本地文件上传、导入本地模型和扫描本地模型目录的旧接口。
|
||||
- 部分历史数据仍使用数据库中的 `content` 或 `output_content` 字段,这是当前已确认的小文件性能策略,不是错误,但必须统一记录来源、大小、校验值和版本。
|
||||
- 大文件在部分代码路径中仍通过 `read()` 或 `put_bytes()` 一次性读入内存,未完成流式或分片上传。
|
||||
- Compute Agent 节点侧的大文件上传已改为流式读取;Backend 端部分历史上传/下载路径仍未完成统一的分片传输。
|
||||
- MinIO 对象和业务资源之间采用多态 `resource_type/resource_id` 关联,数据库没有直接外键,删除和数据一致性需要应用层保证。
|
||||
- 删除业务资源后,对应 MinIO 对象的延迟清理、失败重试和孤儿对象扫描尚未形成完整闭环。
|
||||
|
||||
### 3.2 MinIO 预签名接口的权限边界需要加强
|
||||
### 3.2 MinIO 预签名接口的权限边界
|
||||
|
||||
当前预签名接口已经存在,但 PUT 上传场景仍需要重点补强:
|
||||
|
||||
- 需要根据资源类型和资源 ID 校验当前用户的写权限,而不应只校验读取权限。
|
||||
- 需要服务端生成并校验对象 Key,避免客户端任意写入其他用户或其他资源的对象路径。
|
||||
- 需要增加上传完成确认接口,校验对象实际存在、大小和校验值后再写入业务表。
|
||||
- 需要限制允许的 Bucket、Content-Type、大小和有效期。
|
||||
- 需要记录预签名创建、上传完成、失败和过期事件,便于审计。
|
||||
资源写权限、服务端对象 Key、上传完成确认和对象大小校验已经完成;仍需补充 Content-Type 白名单、对象过期回收和完整审计事件。
|
||||
|
||||
### 3.3 激活版本和跨节点资源版本仍需加强
|
||||
|
||||
数据集已经有 `active_version_id` 和版本表,但以下场景仍需补充:
|
||||
|
||||
- 训练、推理和评测必须只使用资源当前激活版本,并在任务创建时固化版本 ID。
|
||||
- 训练、评测、模型对比和权重合并已在任务创建时固化资源版本 ID;推理服务启动和导出任务仍需统一补齐。
|
||||
- 同一文件名的不同版本不能只依靠文件名同步,应使用资源 ID、版本 ID 和对象 Key 组成唯一定位。
|
||||
- 已创建任务在后续切换激活版本后,不能被意外切换到新版本。
|
||||
- 需要为每个准备到算力节点的资源保存版本、对象 ETag/校验值和本地路径清单。
|
||||
- 已为资源副本保存版本、对象 ID 和本地路径;对象 ETag/校验值及多文件 manifest 仍需补齐。
|
||||
- 历史版本的数据库内容回退和 MinIO 对象回退逻辑还需要补全并增加测试。
|
||||
|
||||
### 3.4 权限 2.0 尚未完全落地
|
||||
### 3.4 权限 2.0 已基本闭环,仍需历史迁移和全量回归
|
||||
|
||||
已有用户、角色、权限码、ACL、审批和审计基础,但仍存在以下差距:
|
||||
已有用户、角色、权限码、ACL、审批、资源申请、GPU 申请、审计和普通用户自助日志能力,仍存在以下差距:
|
||||
|
||||
- 租户、用户、资源、算力节点、模型、数据集之间的隔离规则没有全部在 SQL 查询层统一执行。
|
||||
- 项目空间设计已经讨论过取消,但数据库中仍保留 `projects`、`project_members` 等历史结构,需要明确兼容策略和最终迁移方式。
|
||||
- 训练创建的模型、数据集和训练任务之间的联合权限约束还没有完全统一。
|
||||
- 评测、推理、模型合并、导出、缓存准备等动作需要逐一校验资源读权限和操作权限。
|
||||
- 前端按钮权限已经有基础实现,但不能替代后端鉴权;仍需要对所有关键动作进行后端默认拒绝校验。
|
||||
- 审批拦截范围、管理员豁免规则和跨租户资源访问规则需要形成可执行矩阵。
|
||||
- 历史数据中的 NULL 租户归属仍需盘点和迁移,之后再增加更严格的数据库约束。
|
||||
- 项目空间已从前端和新业务流程移除,但 `projects`、`project_members` 等历史表仍需兼容迁移和下线方案。
|
||||
- 训练、推理、评测、模型合并、导出、缓存准备和下载接口仍需执行全量跨用户/跨租户回归。
|
||||
- 资源动作鉴权已经分散接入,仍需继续统一授权函数和后端默认拒绝策略。
|
||||
- 审批策略、配额、GPU 预留和资源 ACL 的组合规则需要继续用自动化矩阵验证。
|
||||
|
||||
### 3.5 模型合并、导出和评测报告闭环不足
|
||||
### 3.5 模型合并、导出和评测报告已基本闭环
|
||||
|
||||
- 权重合并前自动准备 Base Model 和 Adapter 的主要路径已建立,但失败时的清理、重试和幂等性仍需加强。
|
||||
- 合并结果归档到 MinIO 的逻辑主要依赖任务完成轮询,服务重启或轮询中断时可能需要补偿扫描。
|
||||
- 模型导出任务目前有查询模型和表结构,但完整的创建、执行、进度、失败重试和下载闭环尚未完成。
|
||||
- 评测结果和报告字段已经存在,但报告对象归档、报告下载、报告版本和报告与任务的稳定关联仍需验证。
|
||||
- 评测指标配置和执行器返回指标之间仍需要强类型映射,避免前端显示为通用的 `custom`。
|
||||
- 权重合并前自动准备 Base Model 和 Adapter、失败清理、重试和 MinIO 归档路径已经接入,仍需进行更多幂等和长任务测试。
|
||||
- 模型导出已经具备创建、节点准备、CPU 执行、制品血缘、归档轮询、权限和前端入口,真实大模型多格式压力测试待完成。
|
||||
- 评测报告接口已支持 MinIO 流式返回和历史数据库兼容结果,但报告为空、报告版本和下载流程仍需回归。
|
||||
- 评测指标配置和执行器返回指标之间仍需强类型映射,避免前端显示为通用的 `custom`。
|
||||
|
||||
### 3.6 GPU 资源分配需要统一到所有任务类型
|
||||
### 3.6 GPU 资源分配已统一接入,待多节点多卡验证
|
||||
|
||||
- 训练已经有较完整的节点/GPU 选择和预检流程。
|
||||
- 推理和评测已经出现节点选择、缓存准备和 GPU 选择的接入代码,但还需要确认从页面选择到 Compute Agent 启动参数、进程环境变量和释放逻辑的全链路生效。
|
||||
- 需要防止同一张 GPU 被多个任务绕过调度锁重复占用。
|
||||
- 需要处理服务异常退出、Backend 重启、Compute Agent 重启后的分配回收和状态对账。
|
||||
- 训练详情中的显存使用量、GPU 使用率等指标依赖 Compute Agent 上报,仍需要校验采样时间、单位、空值和任务对应关系。
|
||||
- 训练、推理和评测已经接入节点/GPU 选择、原子预留和释放流程。
|
||||
- 单节点同卡冲突已经验证;多节点、多 GPU 并行和长时间压力仍需真实环境验证。
|
||||
- 需要继续处理服务异常退出、Backend 重启、Compute Agent 重启后的分配回收和状态对账。
|
||||
- 训练详情中的显存使用量、GPU 使用率等指标需要继续校验采样时间、单位、空值和任务对应关系。
|
||||
|
||||
## 四、尚未完成的功能
|
||||
## 四、待完成或待专项验证的功能
|
||||
|
||||
以下功能在当前代码中没有形成可验收的完整闭环,或仍处于设计/基础代码阶段:
|
||||
以下内容已经有代码基础或单节点验证,但尚未达到上线验收条件:
|
||||
|
||||
1. **完整的租户隔离和资源继承模型**:所有列表、详情、下载、缓存、训练、推理、评测和导出接口都需要统一的租户范围过滤。
|
||||
2. **项目取消后的正式数据迁移方案**:需要决定历史项目数据如何归属到用户或租户,并提供一次性迁移脚本和回滚方案。
|
||||
3. **预签名上传完成确认和对象校验**:包括 Key 白名单、ACL、大小限制、哈希/ETag 和状态回写。
|
||||
4. **MinIO 对象生命周期管理**:软删除后的延迟删除、失败重试、孤儿对象扫描、对象引用检查和管理员清理入口。
|
||||
5. **Compute Agent 缓存治理**:容量上限、LRU/TTL、运行任务保护、磁盘占用监控、缓存清单和版本校验。
|
||||
6. **统一的资源归档编排器**:训练、合并、评测和推理相关产物需要支持断点恢复、幂等重试和服务重启补偿。
|
||||
7. **模型导出完整流程**:导出任务创建、格式/量化参数、进度、失败重试、MinIO 归档和下载权限。
|
||||
8. **流式和分片文件传输**:避免大文件上传、下载和对象复制时将完整内容读入 Backend 或 Compute Agent 内存。
|
||||
9. **生产级 MinIO 安全和高可用**:默认密钥替换、TLS、网络访问控制、管理员 Console 隔离、容量监控、备份和恢复。
|
||||
10. **完整的端到端测试和持续集成**:至少覆盖单节点、多节点、多 GPU、跨用户、跨租户、版本切换、MinIO 不可用和服务重启恢复。
|
||||
11. **统一数据库迁移体系**:当前初始化 SQL 适合新库初始化,但尚未替代正式的版本化迁移工具;已有数据库更新仍需要明确迁移脚本和执行记录。
|
||||
1. **历史租户和项目数据迁移**:新数据已补齐租户/ACL 基础校验,历史 NULL 租户和项目兼容表仍需迁移、校验和下线方案。
|
||||
2. **MinIO 生命周期运维**:预签名安全、软删除、失败记录、重试、孤儿扫描和管理员清理接口已存在,自动定时清理和运行监控仍需接入。
|
||||
3. **Compute Agent 缓存生产治理**:容量上限、LRU、TTL、保护窗口、版本/校验清单已实现,运行中任务动态保护、磁盘告警和大规模缓存压力待验证。
|
||||
4. **多节点、多 GPU 并行**:节点/GPU 选择、原子预留、冲突拒绝和释放已实现,真实多节点、多卡并发尚未执行。
|
||||
5. **模型导出和评测报告质量**:创建、执行、归档、权限和下载接口已建立,真实大模型多格式导出、报告版本和指标质量仍需专项验证。
|
||||
6. **超大文件传输**:单文件流式下载和 Compute Agent 流式上传已完成,多文件 ZIP、分片上传和断点续传未完成。
|
||||
7. **生产级 MinIO 安全和高可用**:开发环境接入和故障快速失败已完成,TLS、密钥管理、Console 隔离、容量监控、备份恢复需在生产阶段实施。
|
||||
8. **全量端到端测试和持续集成**:已有前端构建、Backend 编译和存储安全 CI 基线,权限全矩阵、跨节点并行和故障注入仍需扩展。
|
||||
9. **正式数据库迁移体系**:已形成 `005` 至 `012` 幂等增量迁移和运行时兼容执行,仍需增加版本记录、迁移前检查和离线升级演练。
|
||||
|
||||
## 五、需要优化的功能
|
||||
|
||||
@@ -265,6 +257,8 @@ FastAPI Backend API
|
||||
- `data_convert_tasks.storage_backend`
|
||||
- `eval_tasks.report_storage_object_id`
|
||||
|
||||
当前增量迁移脚本为 `005_storage_progress_migration.sql` 至 `012_tenant_user_hierarchy.sql`,已覆盖存储进度、GPU 预留、平台补全、权限 2.0、配额/成员关系、权限生命周期和租户/用户层级等结构。
|
||||
|
||||
离线包中的 `docker/offline/src/backend/app/db/sql/000_full_init.sql` 应与主工程初始化脚本保持同步。需要注意:
|
||||
|
||||
- 初始化 SQL 主要用于新数据库或新数据卷;已有数据库不能仅靠重启容器自动获得全部新字段。
|
||||
@@ -274,6 +268,18 @@ FastAPI Backend API
|
||||
|
||||
## 七、当前验证结果
|
||||
|
||||
### 7.1 2026-08-19 本轮按计划落地内容
|
||||
|
||||
- P0 MinIO 预签名上传已增加资源存在性、资源写权限、管理员基座模型写权限、资源版本和对象 Key 前缀校验;新增上传完成确认接口,会校验 MinIO 对象存在、大小和状态后再标记为可用。
|
||||
- 训练、评测、模型对比和权重合并任务会保存创建时的租户信息与资源版本快照,后续切换数据集激活版本不会改变已创建任务的输入版本。
|
||||
- 数据集、评测任务、训练任务和模型对比列表增加租户范围过滤;用户表、模型/数据集创建入口补齐租户归属;数据转换资源补充所有者权限映射。
|
||||
- Compute Agent 准备缓存后会回写资源副本的版本、MinIO 对象和本地路径;缓存支持可选容量上限、按访问时间淘汰非临时文件,并提供当前占用量和上限状态。
|
||||
- 训练产物、权重合并结果和评测报告增加 MinIO 归档、失败状态记录以及 Backend 重启后的补偿轮询;离线部署源码已同步对应逻辑。
|
||||
- Compute Agent 大文件上传已改为流式读取,避免将整个文件一次性读入内存;离线 Compute Agent 同步完成。
|
||||
- 增加 `005_storage_progress_migration.sql` 增量迁移脚本,并修复 `000_full_init.sql` 中旧数据库执行时索引早于字段补齐的问题;主工程和离线初始化脚本已同步。
|
||||
- 增加 `MINIO_PRESIGN_MAX_BYTES` 配置和上传 Content-Type 白名单;首次数据库 schema 检查移出 Compute Poller 的 Uvicorn 事件循环,避免远程 PostgreSQL 慢连接拖垮健康检查;轮询相同失败改为 300 秒限频记录,并跳过已标记 offline 节点。
|
||||
- 前端 `npm run build` 已通过;容器内 MinIO Key 越权校验专项测试为 `5 passed`,Backend 和 Compute Agent 重启后均为 healthy。
|
||||
|
||||
已完成的静态和局部验证:
|
||||
|
||||
- Backend 和离线 Backend 源码 `compileall` 检查通过。
|
||||
@@ -281,45 +287,80 @@ FastAPI Backend API
|
||||
- 主工程和离线包初始化 SQL 已做同步检查,内容一致。
|
||||
- 前端此前已完成 `npm run build` 类型错误修复,构建剩余问题主要是非阻断的资源/分包警告。
|
||||
- 已对训练日志、数据集 JSON/JSONL 统计、MinIO 资源准备等重点链路进行过问题修复。
|
||||
- 当前 WSL 运行验证中 Backend、Compute Agent、MinIO 均为 healthy;`gpu-node-02`(`172.25.179.69:19100`)连接、GPU 0 分配和任务执行均正常。`gpu-node-01` 的历史地址不可达,已通过健康检查标记为 offline,轮询器不再重复轮询其历史任务。
|
||||
|
||||
### 7.2 2026-08-19 gpu-node-02 真实流程验证
|
||||
|
||||
- 训练:使用 `qwen3.5-0.8B` + `test_data_0817`,任务 `ft_172a2da65140` 完成,GPU 0 使用期间可看到显存、利用率、温度和进程,结束后恢复 idle;24 个训练产物已归档 MinIO。
|
||||
- 资源快照:任务 `ft_d93b0fdae1c9` 创建时已保存数据集 `ds_8f6b8c5714c7` 的活动版本 `file_d550c2128722_v1`。
|
||||
- 训练曲线:任务 `ft_d93b0fdae1c9` 通过 `logging_steps=1` 生成 3 个 loss/epoch/learning-rate/grad-norm 数据点,并生成 `training_loss.png`;后端解析器已兼容带引号数字格式。
|
||||
- 权重合并:任务 `merge_1dc15a290810` 完成,基座模型路径、合并路径已回写,8 个合并模型文件归档 MinIO。
|
||||
- 推理:任务 `cmp_abdf0762869d` 在 GPU 0 加载 `qwen3.5-0.8B` 成功,对话接口返回正常;卸载后 GPU 恢复 idle。
|
||||
- 评测:任务 `eval_3c3f84263e23` 完成 2 条样本评测,报告、样本明细和基础指标已落库;GPU 恢复 idle。评审模型 HTTP 400 导致评审分数为 0,属于评审模型接口配置问题,算力评测链路本身已跑通。
|
||||
|
||||
### 7.3 多 GPU、MinIO 故障和跨用户权限专项验证
|
||||
|
||||
- 多 GPU 调度开发:新增 `gpu_reservations` 表,评测和推理在远程提交/加载前与训练统一纳入数据库原子预留;失败、停止、删除、节点不可达和卸载路径自动释放预留。当前 `gpu-node-02` 只有 GPU 0,已通过同卡“推理预留后评测抢占”测试,评测被明确拒绝,释放后 GPU 恢复 idle。多节点、多卡的真实并行测试待增加第二个可达节点和多卡节点后执行。
|
||||
- 调度锁优化:调度锁改为事务内持有并在提交前释放,避免一次调度成功后后续请求等待 30 秒 TTL;schema 初始化增加 PostgreSQL advisory lock,避免轮询器与首个请求并发初始化造成死锁。
|
||||
- MinIO 故障注入:停止 `yg-ft-minio` 后,`GET /modelTF/health` 返回 HTTP 200 且 `storage.status=unavailable`;恢复容器后返回 `storage.status=ready`。MinIO 客户端关闭默认重试链,故障健康探测耗时从约 6 秒降至约 0.3 秒。
|
||||
- 跨用户权限:创建临时用户 `qa_user_0819`,未授权访问管理员数据集返回 403;授予资源 `read/download` ACL 后列表和详情可访问;撤销 ACL 后再次返回 403;非管理员创建用户返回 403。测试用户已删除,未遗留测试 ACL 或 GPU 预留。
|
||||
- 用户管理接口已补齐管理员依赖,创建、列表、修改、删除和重置密码不再允许普通用户调用。
|
||||
|
||||
当前不能据此宣称“全量功能测试通过”:
|
||||
|
||||
- 现有部分自动化测试仍保留旧的本地文件或旧 MinIO 行为假设,需要按当前分层存储策略更新。
|
||||
- WSL Docker 运行时验证受当前环境的 `E_ACCESSDENIED` 影响,不能在本次文档生成时完成全部容器健康、数据库字段和跨节点测试。
|
||||
- 多节点、多 GPU、MinIO 临时不可用、服务重启恢复和跨用户权限测试仍需要在可用运行环境中执行。
|
||||
- 本轮已完成当前 WSL Docker 容器健康检查、`gpu-node-02` 单节点真实流程、单卡冲突、MinIO 故障恢复和跨用户 ACL 专项验证;多节点、多卡的真实并行测试仍需要第二个可达节点和多卡节点。
|
||||
|
||||
- 本轮专项安全测试为 `5 passed`;全量 pytest 仍未执行完毕,需要按测试类别拆分并设置超时。
|
||||
|
||||
### 7.4 本轮 11 项未验证能力的补齐结果
|
||||
|
||||
- 租户管理接口已统一要求管理员身份;模型制品、模型血缘、导出任务、评测报告和 MinIO 资源清单均增加资源级访问校验。
|
||||
- 新增 `POST /modelTF/model-manage/export`,导出沿用节点选择、MinIO 缓存准备、GPU/调度约束和归档轮询;导出结果记录到 `model_export_jobs`,并建立导出制品与模型血缘。
|
||||
- 新增 `GET /modelTF/model-eval/{task_id}/report`,优先流式返回 MinIO 报告,历史任务无归档对象时返回数据库报告兼容结果。
|
||||
- 新增 `GET /modelTF/storage/resources/{resource_type}/{resource_id}/manifest`、管理员对象清理和孤儿扫描接口;预签名上传增加过期时间和真实 SHA-256 内容校验。
|
||||
- Compute Agent 增加缓存 TTL、缓存保护窗口和元数据清单;超过 TTL 的非保护缓存会在状态检查时清理,容量淘汰会跳过保护中的资源。
|
||||
- 数据集单文件下载改为 MinIO 流式传输,避免 Backend 一次性载入完整大文件;训练、合并、导出、评测仍由统一轮询器负责重启后的归档补偿。
|
||||
- 新增 `007_platform_completion.sql`,并已加入运行时兼容迁移;主工程和 `docker/offline/src` 的源码及初始化 SQL 已同步。
|
||||
- 以上为代码闭环和单节点验证;生产级 MinIO TLS/HA、第二节点/多卡并行压力测试、全量 CI 和历史项目数据正式迁移仍属于上线前专项工作。
|
||||
|
||||
### 7.5 2026-08-20 普通用户运行日志验证
|
||||
|
||||
- 已修复普通用户进入“运行日志”调用管理员专属 `/log-files` 接口导致 403 的问题。
|
||||
- 普通用户现在查看本人操作日志,后端按当前用户 ID 强制过滤,忽略普通用户传入的跨用户 `user_id` 条件。
|
||||
- 管理员仍可查看系统日志、训练日志、审计记录和全量操作诊断。
|
||||
- 临时普通用户创建数据转换任务后验证:操作日志查询和统计均返回 200,返回记录全部属于该用户;测试用户和测试资源已清理。
|
||||
- 前端 `npm run build` 再次通过,离线前端静态资源和源码已同步,离线 Frontend/Backend 容器健康。
|
||||
|
||||
## 八、下一阶段开发计划
|
||||
|
||||
### P0:安全与数据正确性
|
||||
### P0:权限与租户隔离安全闭环
|
||||
|
||||
1. 完善 MinIO 预签名 PUT 的资源写权限、对象 Key 白名单、大小/类型限制和上传完成确认。
|
||||
2. 统一任务创建时的资源版本固化,训练、推理、评测只使用已授权的激活版本快照。
|
||||
3. 逐一补齐评测、推理、模型合并、模型导出、缓存准备的后端权限校验和审计记录。
|
||||
4. 完成租户隔离查询范围,清理或兼容历史项目字段,补充数据迁移脚本。
|
||||
1. 对现有数据库执行结构差异检查,盘点所有 `tenant_id`、创建者、ACL、资源版本和历史 NULL 数据。
|
||||
2. 编写历史租户归属迁移和项目兼容数据迁移脚本,迁移前生成结构/数据快照,迁移后增加一致性检查。
|
||||
3. 建立接口权限矩阵,覆盖数据集下载、模型使用、推理、评测、权重合并、导出、缓存准备、审批和运行日志。
|
||||
4. 补齐跨用户、跨租户、已撤销 ACL、软删除资源和审批未通过场景的自动化测试。
|
||||
|
||||
### P1:跨节点可靠性
|
||||
### P1:资源申请、审批和联合权限
|
||||
|
||||
1. 建立资源清单/manifest,记录 MinIO 对象版本、校验值、目标节点路径和缓存状态。
|
||||
2. 完善训练、合并、评测和推理的准备、执行、归档、失败重试和服务重启补偿。
|
||||
3. 完善 GPU 原子分配、异常回收、节点重连对账和任务释放。
|
||||
4. 增加缓存容量、TTL/LRU、运行任务保护和磁盘占用监控。
|
||||
5. 增加 MinIO 对象引用清理、孤儿对象扫描和软删除回收任务。
|
||||
1. 对资源申请、审批通过后的 ACL 写入、配额扣减和 GPU 预留执行事务一致性回归,重点验证重复审批和撤回。
|
||||
2. 验证租户管理员、普通成员、只读成员和平台管理员在跨租户资源、模型、数据集和算力上的差异。
|
||||
3. 验证训练创建的基座模型、数据集、GPU、训练产物之间的联合授权和血缘快照。
|
||||
4. 统一审批策略、资源 ACL、租户配额和 GPU 预留的错误提示,避免只返回 403/500。
|
||||
|
||||
### P2:性能与用户体验
|
||||
### P2:前端权限体验与审计完善
|
||||
|
||||
1. 优化页面列表接口和高频轮询,采用批量查询、短期缓存和动态退避。
|
||||
2. 将大文件上传/下载/复制改为流式或分片传输。
|
||||
3. 统一前端任务状态组件、loading、超时、重试和错误诊断信息。
|
||||
4. 处理前端离线资源警告,继续拆分首屏 chunk。
|
||||
5. 统一 GPU 状态展示及训练指标采样时间、单位和空值处理。
|
||||
1. 完善页面级权限与资源动作权限的统一组件,重点覆盖下载、导出、执行、删除、授权和审批按钮。
|
||||
2. 运行日志保持普通用户只看本人、管理员看全量的分层模型,并补充权限拒绝和下载/导出审计字段。
|
||||
3. 优化模型推理、模型评测、训练详情、数据集和运行日志页面的首屏 loading、超时、重试和空状态。
|
||||
4. 减少列表接口重复查询,继续拆分首屏大 chunk,移除离线环境不需要的外部资源请求。
|
||||
|
||||
### P3:工程化和上线准备
|
||||
### P3:可靠性、测试和上线准备
|
||||
|
||||
1. 建立正式数据库版本迁移机制和离线升级脚本。
|
||||
2. 增加 CI:前端类型检查/构建、Backend 单元测试、Compute Agent 测试、SQL 新库初始化测试。
|
||||
3. 增加多节点端到端测试和 MinIO 故障注入测试。
|
||||
4. 完善 MinIO TLS、密钥管理、网络隔离、监控、备份和恢复方案。
|
||||
5. 建立生产运行手册,包括首次部署、升级、回滚、数据库迁移、对象清理和故障处理。
|
||||
1. 准备第二个可达节点或多卡节点,执行训练、推理、评测并发、节点不可达和服务重启测试。
|
||||
2. 接入 MinIO 对象生命周期定时清理、容量监控、TLS、密钥管理、备份恢复和故障演练。
|
||||
3. 建立正式数据库迁移版本记录、迁移前结构检查、离线升级和回滚演练。
|
||||
4. 将前端构建、Backend 编译、权限安全、存储安全和端到端流程测试分层纳入 CI。
|
||||
|
||||
## 九、阶段验收标准
|
||||
|
||||
|
||||
493
docs/权限开发进度.md
Normal file
493
docs/权限开发进度.md
Normal file
@@ -0,0 +1,493 @@
|
||||
# 权限开发进度
|
||||
|
||||
> 更新时间:2026-08-20
|
||||
> 适用范围:YG_FT 平台当前主工程、Backend、Frontend、Compute Agent、MinIO 资源访问及 `docker/offline/src` 离线源码。
|
||||
> 当前结论:权限 2.0 的核心功能已形成闭环。本轮继续补齐租户成员角色在 ACL 中的实际判定、有效期租户隔离、用户软删除、资源/MinIO 对象待清理、训练模型预加载资源存在性校验和推理状态接口授权,并已执行在线数据库迁移。自动化权限/存储安全用例、前端构建、后端静态检查、容器健康和用户删除闭环均已验证。由于当前只有一个可达算力节点,跨租户双用户、第二节点/多卡并发、节点故障回收和 MinIO 故障注入仍需专项验证,因此保留为上线前场景。按工作包估算,核心权限开发约完成 98%,上线验收约完成 82%。
|
||||
|
||||
## 本轮 11 项完成情况(2026-08-19)
|
||||
|
||||
| 编号 | 权限能力 | 完成内容 | 状态 |
|
||||
|---|---|---|---|
|
||||
| 1 | 审批决策安全 | 审批人从当前会话获取,校验指定审批人、租户管理员、禁止申请人自审,记录审批审计 | 已完成 |
|
||||
| 2 | 资源访问申请 | 新增资源访问申请记录、申请权限/期限/理由、审批后自动写入 ACL、支持撤回和过期 | 已完成 |
|
||||
| 3 | 审批策略执行 | 按租户、动作、资源类型匹配策略;高风险操作审批通过后可一次性重试执行 | 已完成 |
|
||||
| 4 | 租户与项目隔离 | `tenant_members`、活跃租户校验、历史资源归属补齐、跨租户 ACL 主体校验、项目软删除 | 已完成 |
|
||||
| 5 | 用户与角色边界 | 禁用用户立即注销会话;租户成员支持 owner/admin/member/viewer,保护最后一个 owner | 已完成 |
|
||||
| 6 | 数据集权限入口 | 预览、来源、版本查询/创建/激活/删除、上传/编辑/下载统一接入资源动作权限 | 已完成 |
|
||||
| 7 | 模型和推理权限 | 训练模型合并/导出分别校验 execute/download;聊天、预加载、批量、卸载绑定授权模型或推理任务 | 已完成 |
|
||||
| 8 | GPU 分配申请 | 普通用户可提交 GPU 分配申请,审批通过后自动分配;管理员可直接分配 | 已完成 |
|
||||
| 9 | 租户配额申请 | 租户成员可提交配额变更申请,平台管理员审批后自动更新配额 | 已完成 |
|
||||
| 10 | 软删除与安全状态 | 资源删除撤销 ACL、取消待处理申请和审批;租户/项目采用软删除状态 | 已完成 |
|
||||
| 11 | 前端按钮与审计 | 审批决策、ACL 编辑、访问申请/撤回按权限显示;下载、导出、审批、GPU 等敏感操作补充结构化审计 | 已完成 |
|
||||
|
||||
### 数据库迁移结果
|
||||
|
||||
- 新增增量迁移:`backend/app/db/sql/009_permission_completion.sql`,可独立兼容旧库执行,并已在当前远程 PostgreSQL 执行成功。
|
||||
- 当前远程库已核验包含:`tenant_members`、`resource_access_requests`、审批策略/执行状态字段、审计结果字段、ACL 生命周期字段、项目/租户软删除字段、数据转换任务租户字段。
|
||||
- 已有用户已补齐到 `tenant_members`,当前迁移后共生成 5 条租户成员关系。
|
||||
- `backend/app/db/sql/000_full_init.sql` 已合并完整结构;离线目录继续只保留该完整脚本。
|
||||
|
||||
### 验证结果
|
||||
|
||||
- 后端相关模块 `python -m py_compile`:通过。
|
||||
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 路径提示和大 chunk 警告,无 TypeScript 错误。
|
||||
- `docker/offline/src` 的后端权限代码、Compute Agent、前端源码和完整初始化 SQL 已与主工程关键文件哈希一致。
|
||||
- 运行中的 Backend、Frontend、Compute API 容器已重启,健康检查通过;当前容器采用源码挂载方式,无需重建镜像即可加载本轮代码。已验证健康接口可用,未登录访问受保护接口返回 401;完整双用户、跨租户和多 GPU 回归仍待执行。
|
||||
|
||||
## 一、检查依据
|
||||
|
||||
本次按代码和初始化脚本逐项核对,主要依据如下:
|
||||
|
||||
- `docs/permissions-design.md`
|
||||
- `backend/app/core/auth.py`
|
||||
- `backend/app/api/v1/endpoints/platform.py`
|
||||
- `backend/app/modules/resource/router.py`
|
||||
- `backend/app/modules/approval/router.py`
|
||||
- `backend/app/modules/tenant/router.py`
|
||||
- `backend/app/modules/system/router.py`
|
||||
- `backend/app/db/platform_store.py`
|
||||
- `backend/app/db/sql/000_full_init.sql`
|
||||
- `frontend/src/stores/auth.ts`
|
||||
- `frontend/src/router/index.ts`
|
||||
- `frontend/src/views/governance/ResourceAclView.vue`
|
||||
|
||||
检查口径不是只判断“是否有接口”,还检查了接口是否验证当前用户、是否校验资源所有权和 ACL、是否校验租户边界、审批结果是否真正改变授权、前端按钮是否与后端动作一致。
|
||||
|
||||
## 二、改造前总体进度(历史基线)
|
||||
|
||||
| 能力模块 | 当前状态 | 结论 |
|
||||
|---|---|---|
|
||||
| 登录、密码、Token 会话 | 已实现基础能力 | 有会话过期、注销、状态校验和登录限流基础,仍需统一续期和失败审计 |
|
||||
| 平台角色与权限码 | 部分实现 | `admin/operator/viewer` 和业务权限码存在,但后端部分业务只校验登录,未统一校验权限码 |
|
||||
| 用户创建与管理 | 部分实现 | 管理员可创建、修改、删除和重置密码;租户范围、角色边界、邀请/申请流程未完成 |
|
||||
| 租户与配额 | 部分实现 | 租户 CRUD、配额和留存策略接口为管理员专属;缺少租户成员、租户管理员和统一隔离 |
|
||||
| 资源 ACL | 已实现基础能力 | 支持用户/角色的 `read/write/execute/download/delete/admin`,授权边界和跨租户限制不足 |
|
||||
| 资源申请 | 未完整实现 | 没有独立的资源访问申请对象,现有审批实例不能可靠地落地 ACL 或配额变更 |
|
||||
| 资源审批 | 部分实现且存在安全缺口 | 模板、实例、步骤和部分高风险操作存在;审批决策接口必须先修复越权问题 |
|
||||
| 基座模型权限 | 平台共享已实现 | 登录用户可查看和使用,上传/修改/删除限制管理员;缺少按租户/用途/配额的精细控制 |
|
||||
| 训练模型权限 | 部分实现 | 所有者、ACL、删除、合并、推理加载已有校验;导出下载动作和派生权限继承还不完整 |
|
||||
| 数据集权限 | 部分实现且入口不一致 | 列表、详情、删除、部分下载和训练/评测使用有校验;上传、编辑、预览、版本接口仍有缺口 |
|
||||
| 训练/评测/推理权限 | 部分实现 | 资源执行权和 GPU 分配已有基础校验;部分聊天、状态和历史入口没有统一鉴权 |
|
||||
| GPU 与节点权限 | 基础能力已实现 | 管理员分配、用户可用 GPU 过滤、原子预留和释放已存在;配额审批和跨节点回收对账仍需完善 |
|
||||
| 前端按钮级权限 | 部分实现 | 页面和菜单有基础控制,资源动作没有集中式权限决策,很多按钮依赖后端报错 |
|
||||
| 审计与软删除 | 部分实现 | 主要写操作有审计,资源软删除已覆盖若干表;actor、下载、拒绝和跨租户查询仍需统一 |
|
||||
|
||||
## 三、已经实现的内容
|
||||
|
||||
### 3.1 认证、角色与用户
|
||||
|
||||
- `get_current_user` 会校验 Bearer Token、用户存在性、用户状态和会话有效期;`sessions` 支持注销和过期时间。
|
||||
- `require_admin` 对管理员专属接口提供后端保护,受保护用户也具备管理员旁路能力。
|
||||
- 用户列表、创建、修改、删除、重置密码均已增加管理员依赖;用户可修改自己的密码。
|
||||
- 用户记录包含 `tenant_id`、`role`、`permissions`、`protected` 等字段,角色权限在初始化脚本中有基础种子数据。
|
||||
- 登录失败限流和旧明文密码升级已经具备基础实现。
|
||||
|
||||
### 3.2 租户、资源和 ACL
|
||||
|
||||
- `tenants` 表和租户 CRUD、配额、留存策略接口已经存在,当前接口统一要求管理员。
|
||||
- 数据集、模型、训练模型、评测任务等核心资源已经具备 `created_by`、`tenant_id` 或任务 payload 中的归属信息。
|
||||
- `acls` 表支持用户和角色两类授权主体,权限包括 `read`、`write`、`execute`、`download`、`delete`、`admin`。
|
||||
- 资源 ACL 查询和全量替换接口已经存在,资源所有者或管理员可以管理 ACL。
|
||||
- 列表接口对数据集、评测、训练和推理任务已增加“本人资源 + ACL 授权资源”的过滤逻辑。
|
||||
- MinIO 预签名、资源清单、对象列表、模型制品、模型血缘和评测报告等新入口已增加登录和资源访问校验。
|
||||
|
||||
### 3.3 训练、评测、推理和 GPU
|
||||
|
||||
- 训练创建会检查训练数据集的 `execute` 权限,并对用户选择的 GPU 执行分配校验。
|
||||
- 评测创建会检查训练模型、数据集的 `execute` 权限,并校验算力节点和 GPU。
|
||||
- 推理任务加载会检查任务及训练模型的执行权,同时使用 `gpu_reservations` 防止同一张 GPU 被并发占用。
|
||||
- GPU 分配接口和用户可用 GPU 查询已经存在,失败、停止、删除、节点异常等路径具备基础释放逻辑。
|
||||
- 训练模型删除、训练任务停止/删除、评测任务删除和推理任务删除已接入部分审批拦截。
|
||||
- 权重合并、导出、缓存准备和 MinIO 归档已经能记录模型、节点、租户和部分血缘信息。
|
||||
|
||||
### 3.4 审计和前端
|
||||
|
||||
- `audit_logs`、`operation_logs` 表及管理员查询/导出页面已经存在。
|
||||
- 资源 ACL 变更、租户管理、模型/数据集/任务等主要写操作已经接入审计或操作日志装饰器。
|
||||
- 前端路由和侧边栏对治理、组织、资源授权、审批、日志、算力节点等页面做了管理员限制。
|
||||
- `ResourceAclView` 已支持资源类型、用户/角色主体和多权限编辑。
|
||||
|
||||
## 四、改造前未实现或存在明显安全缺口(历史基线)
|
||||
|
||||
> 本节保留本轮改造前的检查快照,不代表当前状态。当前剩余问题以“十、当前仍需开发的功能”和“十一、下一步开发计划”为准。
|
||||
|
||||
以下项目属于必须继续开发的内容,优先级高于页面样式和性能优化。
|
||||
|
||||
### 4.1 审批决策不能直接信任请求参数
|
||||
|
||||
`backend/app/modules/approval/router.py` 的审批决策接口当前没有 `get_current_user` 依赖,并且从请求体读取 `approver_id`。调用方可以伪造审批人 ID,属于高风险越权问题。
|
||||
|
||||
必须改为:服务端从当前会话取得审批人;校验其是否为当前步骤指定审批人、租户管理员或平台管理员;校验当前步骤、实例状态和申请人不能自审;审批通过后再执行对应动作或写入 ACL。
|
||||
|
||||
### 4.2 资源申请流程尚未形成
|
||||
|
||||
当前有 `approval_templates`、`approval_instances`、`approval_steps`,但没有独立的资源访问申请记录,也没有统一的“申请资源 -> 审批 -> 授权/配额变更”事务流程:
|
||||
|
||||
- 创建审批实例时未统一验证资源是否存在、申请人是否属于资源租户、申请动作是否合法。
|
||||
- 审批实例批准后不会自动创建 ACL、GPU 分配或租户配额变更。
|
||||
- 不能表达申请权限、申请期限、申请原因、审批后的 ACL 权限和撤销时间。
|
||||
- 审批模板查询和详情接口没有完整的租户/角色范围控制。
|
||||
|
||||
### 4.3 租户隔离不是全量强制
|
||||
|
||||
- 当前用户只有单一 `tenant_id`,没有 `tenant_members` 或租户角色关系;无法支持租户管理员、跨租户平台管理员和成员邀请的清晰边界。
|
||||
- `filter_accessible_resource_ids` 和批量版本主要按 ACL/所有者过滤,不在统一函数中校验资源租户。
|
||||
- 数据集、评测等查询仍对 `tenant_id IS NULL` 做兼容放行;历史数据未完成归属迁移。
|
||||
- `trained_models()` 没有统一 tenant 参数,资源过滤依赖上层二次处理。
|
||||
- ACL 设置接口没有校验授权主体和资源是否属于同一租户,存在跨租户授权风险。
|
||||
- 新建模型、数据集、任务虽然多数会补默认租户,但缺少“租户必须存在且处于 active”的统一校验。
|
||||
|
||||
### 4.4 数据集权限入口不一致
|
||||
|
||||
核心列表、详情、删除、部分下载已校验,但以下文件/版本接口当前未统一接入当前用户和资源权限:
|
||||
|
||||
- 文件预览和记录来源查询。
|
||||
- 文件版本列表、版本内容查询。
|
||||
- 创建、激活、删除数据集文件版本。
|
||||
- 数据集上传接口没有统一的当前用户、写权限和租户校验。
|
||||
- 数据集编辑接口没有统一的当前用户和写权限校验。
|
||||
|
||||
此外,数据集下载和单文件下载目前检查的是 `read`,没有严格使用设计中的独立 `download` 权限。
|
||||
|
||||
### 4.5 模型使用、导出和推理入口不一致
|
||||
|
||||
- 基座模型按平台共享资源处理,登录用户可以查看和使用;但模型名称查询、本地模型列表和部分本地聊天/状态/卸载入口缺少统一鉴权。
|
||||
- 训练模型列表、详情、合并和加载已有 ACL 校验,但导出接口实际属于下载/外发动作,不能只检查 `execute`。
|
||||
- 评测报告下载当前检查 `read`,应单独检查 `download` 并记录下载审计。
|
||||
- 训练模型由训练任务生成时,尚未完整实现“基座模型 + 数据集授权关系”向派生模型权限和血缘策略的统一继承。
|
||||
- 推理聊天接口没有始终绑定到已授权的推理任务、模型资源和指定算力节点,存在绕过模型使用流程的风险。
|
||||
|
||||
### 4.6 用户创建和角色边界不完整
|
||||
|
||||
- 当前只有平台管理员创建用户,普通用户不能申请加入租户,也没有邀请、审批、禁用后会话清理的完整流程。
|
||||
- 用户只能直接挂在一个 `tenant_id` 上,不能表达一个用户属于多个租户或在不同租户中拥有不同角色。
|
||||
- 后端 `create_user` 对非管理员角色会归一为普通用户,前端出现的 `operator` 角色与后端实际行为可能不一致。
|
||||
- 创建用户时缺少租户存在性、租户状态、租户用户配额和角色白名单校验。
|
||||
- 管理员可以创建管理员角色,尚未区分平台管理员和租户管理员的授予权限。
|
||||
|
||||
### 4.7 前端按钮级权限没有闭环
|
||||
|
||||
- 前端已有菜单和路由权限基础,但 `hasPermission` 没有覆盖所有业务路由动作,部分业务页对已登录用户直接开放。
|
||||
- 资源级按钮主要靠资源对象中的所有者字段判断,没有统一使用后端返回的 ACL 决策。
|
||||
- 下载、执行、删除、授权、导出、审批等动作没有统一的 `can(resource, action)` 机制。
|
||||
- 即使按钮隐藏,前端 API 模块仍可能直接调用敏感接口;必须以后端鉴权为最终边界。
|
||||
|
||||
### 4.8 审计、软删除和权限拒绝记录不完整
|
||||
|
||||
- 部分模块的 `_actor` 直接保存 Authorization Token,而不是规范的用户 ID,导致审计主体不一致。
|
||||
- 访问、下载、导出、ACL 授权、审批拒绝、GPU 分配和权限拒绝没有全部统一记录租户、资源和结果。
|
||||
- `record_visit` 公开接口容易被伪造;如果继续保留匿名访问,应明确它不是安全审计日志。
|
||||
- 资源软删除已覆盖模型、训练模型、数据集、评测任务等主要表,但关联 MinIO 对象、ACL、审批和血缘的延迟清理策略还不完整。
|
||||
|
||||
## 五、需要优化的现有流程
|
||||
|
||||
### 5.1 统一权限模型
|
||||
|
||||
将当前分散的 `is_admin`、所有者判断、ACL 查询、租户判断、GPU 判断收敛为统一服务:
|
||||
|
||||
```text
|
||||
认证 -> 平台/租户角色 -> 租户边界 -> 资源所有权/ACL -> 动作权限 -> GPU/配额 -> 审批 -> 审计
|
||||
```
|
||||
|
||||
每个敏感接口都应明确动作,例如 `dataset.read`、`dataset.download`、`dataset.execute`、`trained_model.export`、`inference.load`、`gpu.reserve`,禁止只使用“已登录”作为业务权限。
|
||||
|
||||
### 5.2 重新设计资源申请和审批
|
||||
|
||||
推荐流程:
|
||||
|
||||
```text
|
||||
申请人选择资源和动作
|
||||
-> 校验申请人所属租户和基础权限
|
||||
-> 创建 resource_access_requests
|
||||
-> 根据租户/资源类型匹配审批策略
|
||||
-> 指定审批人完成审批
|
||||
-> 事务内写入 ACL/配额/GPU 预留
|
||||
-> 记录授权有效期、来源和审计
|
||||
```
|
||||
|
||||
审批拒绝、撤回、过期和资源删除都应撤销或冻结对应授权,不能仅修改审批实例状态。
|
||||
|
||||
### 5.3 模型、数据集、训练任务联合授权
|
||||
|
||||
训练、评测、推理分别使用以下最小权限:
|
||||
|
||||
| 场景 | 必须具备的权限 |
|
||||
|---|---|
|
||||
| 查看基座模型 | `model.read`;基座模型默认平台共享 |
|
||||
| 使用基座模型训练 | `model.execute` 或平台共享策略 + 数据集 `execute` |
|
||||
| 下载基座模型 | 单独的 `model.download`,默认不授予 |
|
||||
| 使用训练模型推理 | `trained_model.execute` |
|
||||
| 下载/导出训练模型 | `trained_model.download` 或 `trained_model.export` |
|
||||
| 使用数据集训练/评测 | `dataset.execute` |
|
||||
| 查看数据集 | `dataset.read` |
|
||||
| 下载数据集文件 | `dataset.download` |
|
||||
| 创建训练任务 | 上述资源权限 + 指定节点/GPU 使用权 + 租户配额 |
|
||||
|
||||
训练模型应保留创建者、租户、基座模型、数据集、训练任务和资源版本快照。派生模型默认只对创建者和同租户授权,不应因为基座模型共享而自动公开训练产物。
|
||||
|
||||
## 六、建议的数据库改造
|
||||
|
||||
当前 `000_full_init.sql` 已包含用户、角色、会话、ACL、租户、审批、审计、GPU 分配和 GPU 预留表,但要完成权限 2.0,建议增加或扩展以下结构。实施时必须同步主工程和 `docker/offline/src/backend/app/db/sql/000_full_init.sql`。
|
||||
|
||||
1. `tenant_members`:用户、租户、租户角色、状态、加入来源和有效期,解决一个用户多租户和租户管理员问题。
|
||||
2. `resource_access_requests`:申请人、租户、资源、动作、申请原因、申请权限、有效期、审批状态和最终授权记录。
|
||||
3. `acls` 增加 `tenant_id`、`granted_by`、`source_request_id`、`expires_at`、`revoked_at`,保留授权来源和自动过期能力。
|
||||
4. `approval_templates` 增加 `tenant_id`、`action`、`resource_type`、`scope`、`status`;审批步骤增加主体类型、主体 ID 和租户范围。
|
||||
5. 资源表统一补齐非空租户策略、归属用户、软删除字段和必要索引;历史 NULL 数据通过一次性迁移处理。
|
||||
6. `audit_logs` 增加结果、拒绝原因、request_id、认证会话和结构化 detail,避免把 Token 当作 actor。
|
||||
|
||||
不建议把完整 ACL 和审批状态继续塞入模型、数据集或任务 JSON 字段;JSON 可保留兼容信息,但权限判断应以结构化表为准。
|
||||
|
||||
## 七、历史开发计划(已执行)
|
||||
|
||||
### 第一阶段:P0 安全修复
|
||||
|
||||
- 修复审批决策鉴权和审批人伪造问题。
|
||||
- 补齐数据集文件/版本/上传/编辑接口权限。
|
||||
- 补齐本地模型聊天、状态、卸载、模型名称查询等历史入口鉴权。
|
||||
- 统一 `download`、`execute`、`write`、`delete` 动作检查。
|
||||
- 限制 ACL 授权范围,校验主体存在、同租户和资源归属。
|
||||
- 增加至少 20 个后端权限回归用例,覆盖未登录、本人、同租户他人、跨租户、管理员和已撤销 ACL。
|
||||
|
||||
### 第二阶段:P1 租户和资源申请
|
||||
|
||||
- 引入租户成员和租户角色,明确平台管理员、租户管理员、成员、只读成员边界。
|
||||
- 开发资源访问申请接口和前端申请页面。
|
||||
- 重做审批模板匹配、审批人校验、审批结果落地 ACL、有效期和撤销流程。
|
||||
- 将配额申请、GPU 分配申请、模型导出和跨用户删除纳入审批策略。
|
||||
- 新资源强制租户归属并完成历史数据迁移。
|
||||
|
||||
### 第三阶段:P1 联合资源权限
|
||||
|
||||
- 建立模型/数据集/训练任务/评测任务/推理任务的统一资源授权服务。
|
||||
- 训练前一次性校验基座模型、数据集、节点、GPU 和租户配额。
|
||||
- 训练模型生成时写入血缘和权限来源;推理、评测、合并、导出使用同一套动作权限。
|
||||
- 版本快照、MinIO 对象、算力节点本地缓存沿用同一资源授权结果。
|
||||
|
||||
### 第四阶段:P2 前端和审计
|
||||
|
||||
- 增加统一 `can(resource, action)` 和按钮权限组件。
|
||||
- 授权和审批界面使用用户/租户/资源中文名称,展示授权来源、有效期和审批状态。
|
||||
- 规范审计 actor、租户、请求 ID、资源、动作、结果和失败原因。
|
||||
- 将权限不足、审批中、资源过期、MinIO 不可用分别展示,避免全部显示为通用 500。
|
||||
|
||||
### 第五阶段:P3 测试与上线
|
||||
|
||||
- 新库初始化、增量迁移、离线目录同步和前端构建全部纳入 CI。
|
||||
- 执行跨租户、跨用户、ACL 撤销、审批越权、软删除、MinIO 故障和 GPU 冲突专项测试。
|
||||
- 在第二个可达节点或多卡节点到位后,执行多节点、多 GPU 的权限和并发测试。
|
||||
- 补充权限运维手册:新建租户、创建用户、授权模型/数据集、审批、撤销权限、审计追踪和故障恢复。
|
||||
|
||||
## 八、验收标准
|
||||
|
||||
- 未登录用户不能访问任何模型、数据集、任务、聊天、版本、下载和审批接口。
|
||||
- 用户只能访问所属租户中本人拥有或被明确授权的资源;跨租户 ACL 默认禁止。
|
||||
- 查看、下载、执行、编辑、删除和授权是独立动作,不能用 `read` 替代所有动作。
|
||||
- 普通用户不能伪造审批人、审批其他租户资源或审批自己的申请。
|
||||
- 训练、评测和推理创建必须同时满足资源权限、GPU 权限、节点权限和租户配额。
|
||||
- 审批通过后才产生授权,审批拒绝、撤回、过期和资源删除后授权不会继续生效。
|
||||
- 基座模型共享不等于训练产物共享;训练后的模型和数据集必须按租户、所有者和 ACL 控制。
|
||||
- 前端隐藏按钮不能替代后端校验,直接调用 API 也必须返回明确的 401/403。
|
||||
- 所有敏感操作可通过用户、租户、资源、动作和请求 ID追溯到审计记录。
|
||||
|
||||
## 九、历史实施记录(已完成)
|
||||
|
||||
本轮已完成权限闭环的代码实现:
|
||||
|
||||
1. 统一校验当前会话、会话过期、退出状态和可用租户范围。
|
||||
2. 补齐模型、数据集、训练、评测、推理、数据处理、数据转换、算力、存储和审计入口的登录及模块权限。
|
||||
3. 新增 `tenant_members`,新建用户、项目、数据集、训练任务和数据处理任务写入当前租户与创建者。
|
||||
4. ACL 写入校验主体存在性、状态、租户边界、有效期和撤销状态;普通所有者不能授予 `delete/admin` 或跨租户权限。
|
||||
5. 新增 `resource_access_requests`;审批人由当前会话确定,禁止伪造审批人和申请人自审;审批通过后才落 ACL。
|
||||
6. 训练、评测和推理统一校验数据集、基座模型、训练模型、任务、节点和 GPU 使用权限;下载和导出使用独立的 `download` 权限。
|
||||
7. 前端认证 store 新增 `can(resource, action)`,模型管理和审批页面按权限显示操作按钮,后端 401/403 仍是最终防线。
|
||||
8. 新增 `009_permission_completion.sql`;主工程与离线目录的完整初始化 SQL 已同步且 SHA-256 一致,离线目录只保留完整初始化脚本。
|
||||
|
||||
### 本轮验证
|
||||
|
||||
- 后端权限相关文件 `py_compile` 通过。
|
||||
- 前端 `npm run build` 通过;仅保留已有字体路径和 chunk size 警告。
|
||||
- 当前 WSL 容器已确认 Backend、Frontend、Compute、Redis、MinIO 均运行;基础健康和未登录拦截已验证,历史治理测试夹具与当前鉴权/数据库行为不完全兼容,不能替代新的权限专项回归。
|
||||
|
||||
### 上线前验证
|
||||
|
||||
- 第二个可达节点或多卡节点到位后的多租户、多 GPU 并行压力测试。
|
||||
- 对已执行的 `009_permission_completion.sql` 进行旧数据租户归属、ACL、审批和软删除记录对账。
|
||||
- 更新 Backend/Frontend 容器后重新执行治理测试和权限专项测试。
|
||||
|
||||
## 十、当前复核结论(2026-08-19)
|
||||
|
||||
### 10.1 已完成的基础能力
|
||||
|
||||
本轮 11 项权限改造已经形成基础闭环:会话和用户状态校验、租户成员关系、资源 ACL、资源访问申请、审批决策安全、模型/数据集/训练/评测/推理入口权限、GPU 分配申请、配额申请、软删除和前端基础按钮控制均已落地;数据库迁移和完整初始化 SQL 已同步到主工程及离线目录。
|
||||
|
||||
这些能力可以作为后续完善的基础,但“接口存在”不等于“所有资源和所有异常路径均已达到上线标准”。尤其是密钥暴露、配额实际拦截、资源列表一致性和专项测试仍需要继续处理。
|
||||
|
||||
### 10.2 仍需开发的功能
|
||||
|
||||
| 优先级 | 功能 | 当前缺口 | 处理结论 |
|
||||
|---|---|---|---|
|
||||
| P0 | 模型密钥和敏感信息保护 | 模型列表、详情、名称查询、创建和更新响应已移除真实 `api_key`,仍需继续排查任务详情、日志和其他敏感配置输出 | 基础闭环已完成;继续做全量敏感字段扫描和受控密钥管理 |
|
||||
| P0 | 统一资源动作策略 | 已增加资源动作白名单和 `export -> download` 归一化,但各业务入口仍需逐步迁移到统一授权服务 | 第一阶段已完成;继续完成全量入口收敛 |
|
||||
| P0 | 数据转换、数据处理和存储权限一致性 | 部分列表、文件、预览、版本、缓存和 MinIO 对象入口仍需逐接口核对“租户 + 所有者/ACL + 动作” | 必须完成全量入口审计,尤其是 `read/download/execute/write/delete` 的区分 |
|
||||
| P0 | 审计失败链路 | 审计装饰器已记录失败结果、原因、请求 ID、会话 ID 和租户;手工审计入口仍需继续统一 | 基础闭环已完成;继续补齐所有权限拒绝和异常入口 |
|
||||
| P1 | 租户成员生命周期 | 已有成员表和角色,但缺少邀请、加入申请、审批、过期、移除和前端租户切换的完整流程 | 需要开发,明确平台管理员与租户管理员的授予边界 |
|
||||
| P1 | 配额强制执行 | 配额申请和审批已实现,但训练、评测、推理、存储等资源消耗尚未全部进行原子配额检查和扣减 | 需要开发配额使用量/预留量/释放量账本,不能只保存配额配置 |
|
||||
| P1 | GPU 分配强校验 | 申请链路已实现,但分配前仍需统一校验节点状态、GPU 存在性、冲突、租户配额和释放对账 | 需要开发原子预留、超时回收和节点故障对账 |
|
||||
| P1 | 审批策略完整性 | 需要严格限制动作白名单、资源类型、模板作用域和重复申请;过期处理不应只依赖查询触发 | 需要补充定时过期、幂等键、执行失败重试和策略管理边界 |
|
||||
| P1 | 派生模型和数据血缘授权 | 基座模型、数据集、训练模型之间已有部分血缘,但权限来源、版本快照和派生资源默认授权规则还不够统一 | 需要固化“创建者 + 租户 + 显式 ACL”,禁止共享基座模型自动公开训练产物 |
|
||||
| P1 | 用户软删除和对象清理 | 用户及部分关联关系仍有物理删除风险;MinIO 对象、ACL、审批、缓存的异步清理缺少统一编排 | 需要补齐软删除、撤销、延迟清理和失败重试 |
|
||||
| P2 | 前端资源级权限体验 | 已有菜单/按钮级基础控制,但缺少统一 `can(resource, action)`、授权来源、有效期、审批中和 403 状态展示 | 需要开发统一权限组件和错误状态处理,后端校验仍是最终边界 |
|
||||
| P2 | 权限专项测试与上线检查 | 基础构建、静态检查、健康接口已验证,尚未完成双用户、跨租户、撤销、过期、MinIO 故障、GPU 冲突的全流程矩阵 | 必须补充自动化测试、迁移回归和离线部署验收 |
|
||||
|
||||
### 10.3 需要优化的设计
|
||||
|
||||
1. **从“角色判断”改为“动作授权”**:统一使用 `resource_type + resource_id + action + tenant_id + actor` 判断,平台管理员只作为明确的管理范围,不再作为各业务模块的隐式旁路。
|
||||
2. **区分平台角色和租户角色**:`users.role` 只表达平台级角色,`tenant_members.role` 表达租户内角色;禁止通过租户成员关系授予平台管理员权限。
|
||||
3. **区分查看、下载、执行、编辑、删除、授权**:`read` 不能替代 `download`,`execute` 不能替代 `export`,高风险动作必须绑定审批和审计。
|
||||
4. **统一资源列表和详情规则**:列表、详情、文件、版本、预览、缓存、下载和导出必须调用同一授权服务,避免“列表看不到但接口可访问”或“列表能看到但操作必然 403”。
|
||||
5. **权限与配额采用预留模型**:任务提交时原子预留 GPU、显存、并发数和存储额度,任务完成、失败、取消和节点失联时统一释放或对账。
|
||||
6. **审批采用可执行状态机**:申请、审批、拒绝、撤回、过期、执行中、执行失败、已执行状态分离;审批结果应有幂等执行记录,避免重复授权或重复分配。
|
||||
7. **敏感字段默认拒绝返回**:API key、对象内部凭据、节点访问凭据不能随普通资源详情返回;日志、审计和错误信息也不能泄露 Token、密码或完整连接串。
|
||||
8. **安全审计与访问统计分离**:权限成功、拒绝、下载、导出、授权、审批和异常进入不可篡改审计;页面访问统计单独存储,避免污染安全审计记录。
|
||||
|
||||
## 十一、下一步开发计划
|
||||
|
||||
### 阶段一:P0 安全封堵与统一策略
|
||||
|
||||
1. 对模型列表、详情、名称查询及相关 DTO 做 API key/凭据脱敏,增加“仅后端内部读取”的封装。(基础闭环已完成,继续扫描任务和日志输出)
|
||||
2. 建立统一 `authorize(resource, action)` 服务,定义动作白名单和平台管理员、租户管理员、所有者、ACL 的判定顺序。(已完成动作白名单,继续迁移全部入口)
|
||||
3. 逐项审计平台、数据处理、数据转换、存储、MinIO、模型、数据集、训练、评测、推理的列表、详情、预览、下载、导出、缓存和删除入口。
|
||||
4. 统一记录权限成功、拒绝和异常审计,补齐 `tenant_id`、`resource_id`、`action`、`request_id`、`session_id`、`reason` 和 `result`。(装饰器基础闭环已完成,继续覆盖手工记录入口)
|
||||
|
||||
### 阶段二:租户成员、审批和配额闭环
|
||||
|
||||
1. 开发租户邀请/加入申请/审批/移除/过期流程及前端租户切换。
|
||||
2. 为审批模板增加动作和资源类型白名单、租户作用域、幂等键、过期任务和执行失败重试。
|
||||
3. 建立配额预留账本,训练、评测、推理、存储和 GPU 任务提交前统一原子检查;任务终态和故障恢复统一释放。
|
||||
4. 完善 GPU 节点、GPU 卡、租户、用户和任务的占用关系校验,覆盖冲突、超时、节点不可达和服务重启恢复。
|
||||
|
||||
### 阶段三:资源血缘和生命周期
|
||||
|
||||
1. 固化基座模型、数据集、数据处理结果、训练任务、训练模型、评测和推理任务的资源血缘及版本快照。
|
||||
2. 明确派生模型默认授权规则,训练产物不因基座模型共享而自动对外公开。
|
||||
3. 补齐用户、租户、资源、ACL、审批、MinIO 对象和本地缓存的软删除、撤销、延迟清理和失败重试。
|
||||
|
||||
### 阶段四:前端权限体验与测试
|
||||
|
||||
1. 开发统一资源级权限组件,按动作隐藏/禁用按钮,并展示授权来源、有效期、审批状态和明确的 401/403 原因。
|
||||
2. 将审批、ACL、审计列表中的用户、租户、资源 ID 映射为可读名称,同时保留 ID 作为详情字段。
|
||||
3. 编写并执行权限专项测试矩阵:未登录、同租户成员、资源所有者、ACL 授权、跨租户、禁用用户、会话注销、审批撤回/过期、软删除、MinIO 故障、GPU 冲突和配额不足。
|
||||
4. 在第二个可达节点或多卡节点准备后执行多节点、多 GPU 并发及故障恢复测试;完成主工程与 `docker/offline/src` 的源码、初始化 SQL、迁移和部署文档一致性检查。
|
||||
|
||||
## 十二、下一阶段完成标准
|
||||
|
||||
- 普通资源接口不再返回 API key、密码、Token 或节点访问凭据。
|
||||
- 所有资源入口都经过统一的租户边界和动作授权,跨租户访问返回明确 403。
|
||||
- 训练、评测、推理创建同时满足资源权限、GPU 预留和租户配额,失败时不会留下孤儿占用。
|
||||
- 审批只能由合法审批人执行,申请人不能自审;重复回调不会重复授权、分配或扣减配额。
|
||||
- 权限拒绝、下载、导出、授权、审批和异常均能按用户、租户、资源和请求 ID追溯。
|
||||
- 主工程和离线目录初始化新库均无缺表、缺字段;迁移可重复执行且不破坏既有数据。
|
||||
- 权限专项自动化测试通过,且完成至少一次双用户、跨租户和 MinIO 故障场景的真实容器验证。
|
||||
|
||||
## 十三、上一阶段权限闭环开发结果(2026-08-20)
|
||||
|
||||
本轮围绕 P0 安全封堵完成了一个可验证的权限闭环:
|
||||
|
||||
1. **模型凭据不出接口**:模型列表、详情、按名称查询、创建、更新和用途更新响应统一经过公开 DTO 脱敏,移除 `api_key`、密码、Token 等字段,仅返回 `api_key_configured` 布尔状态;后端内部评测、数据生成仍使用数据库中的真实配置。
|
||||
2. **编辑密钥不被意外清空**:前端编辑在线模型时不回填真实密钥,留空表示保留已有配置,只有管理员主动输入新值时才提交替换。
|
||||
3. **资源动作统一入口**:增加资源动作白名单 `read/write/execute/download/export/delete/admin`,并将 `export` 统一归一到下载权限,非法动作默认拒绝,避免把模块权限误当成资源权限。
|
||||
4. **失败审计闭环**:审计装饰器对成功和异常分别记录,失败记录包含结果、失败原因、租户、请求 ID、会话 ID和耗时,并对异常中的常见凭据进行脱敏。
|
||||
5. **访问统计受控**:模块访问统计只接受平台已登记的模块名,不能通过请求参数向安全审计表写入任意动作;审计 CSV 导出改为标准 CSV 编码,并补充结果、原因、请求和会话字段。
|
||||
6. **离线版本同步**:上述后端权限代码、前端模型编辑代码和权限安全回归用例已同步到 `docker/offline/src`;本轮未新增数据库字段,因此 `000_full_init.sql` 无需变更。
|
||||
|
||||
### 上一阶段验证结果
|
||||
|
||||
- 后端权限相关模块 `python -m py_compile`:通过。
|
||||
- WSL Backend 容器执行权限安全用例:8 passed;仅有 pytest 缓存目录只读警告。
|
||||
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 路径和 chunk size 警告。
|
||||
- 容器接口验证:未登录访问模型接口返回 401;管理员访问模型列表/详情时响应不包含 `api_key`,仅返回 `api_key_configured`。
|
||||
- Backend 容器已重启并加载当前源码;数据库无需迁移。
|
||||
|
||||
### 上一阶段未覆盖的范围(已在第十四节继续处理)
|
||||
|
||||
本轮没有声称完成配额账本、GPU 原子预留、租户邀请/加入申请、审批定时过期、所有资源入口的逐接口审计,以及第二节点/多 GPU 的真实并发测试;这些仍按“十一、下一步开发计划”执行。
|
||||
|
||||
## 十四、本轮继续开发结果(2026-08-20)
|
||||
|
||||
### 已完成
|
||||
|
||||
1. 新增 `tenant_quota_reservations` 配额预留账本,支持按租户统计 GPU 预留量、原子限制 GPU 配额,以及任务完成、失败、停止、删除和节点故障时释放预留。
|
||||
2. 训练、评测和推理统一接入租户 GPU 配额预留;评测/推理使用的 `gpu_reservations` 与配额账本在同一事务内创建或释放,避免只释放算力卡而遗留配额占用。
|
||||
3. 租户成员支持邀请、接受、过期、角色更新和移除;邀请不允许授予 `owner`,成员状态和租户有效性由后端校验,租户详情页补充成员管理和 GPU 配额使用量展示。
|
||||
4. 审批动作增加白名单,非法动作拒绝创建;相同申请人在同一资源上的待审批申请幂等复用;审批实例读取时自动处理过期状态,资源访问申请也避免重复创建。
|
||||
5. GPU 分配增加节点启用状态、GPU 卡存在性、用户 active 状态和同卡跨用户冲突校验;冲突返回 409,不再静默覆盖或产生重复授权。
|
||||
6. 完整初始化 SQL 增加配额预留表和索引,新增 `010_permission_quota_membership.sql` 增量迁移;主工程相关源码、前端租户 API/页面和 SQL 已同步到离线源码目录。
|
||||
|
||||
### 本轮验证
|
||||
|
||||
- WSL Backend 容器重启后,`tenant_quota_reservations` 可正常查询,默认租户配额使用量返回正常。
|
||||
- WSL Backend 容器执行 `test_permission_security.py`:3 passed。
|
||||
- 后端相关文件 `python -m py_compile`:通过。
|
||||
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 资源路径和大 chunk 警告。
|
||||
|
||||
### 必须后续验证的场景
|
||||
|
||||
1. 创建第二个 active 用户和第二个租户,验证邀请接受、租户切换、跨租户资源访问均按预期返回 401/403。
|
||||
2. 将租户 GPU 配额设为 1,同时提交两个需要 GPU 的训练/评测/推理任务,确认第二个任务被拒绝;第一个任务终态后确认配额可再次使用。
|
||||
3. 在同一多卡节点上让两个用户申请同一张卡,确认审批执行阶段冲突返回 409,另一张空闲卡仍可正常分配。
|
||||
4. 构造过期审批、重复提交、审批拒绝/撤回,确认不会重复创建 ACL、GPU 分配或配额预留。
|
||||
5. 准备第二个可达节点或多卡节点,执行训练、评测、推理的多节点/多 GPU 并发和节点失联回收测试。
|
||||
6. 注入 MinIO 故障,确认任务失败后 GPU 与租户配额均能释放,恢复 MinIO 后可以重新提交任务。
|
||||
|
||||
### 下一步计划
|
||||
|
||||
- 对数据处理、数据转换、MinIO 对象、缓存、版本和报告下载入口继续执行一次接口级回归,重点验证跨租户、过期 ACL 和下载/执行动作分离。
|
||||
- 将双用户、跨租户、配额不足、同卡冲突、审批过期/幂等、MinIO 故障和节点失联场景加入可重复的自动化测试夹具;当前单节点环境先完成无需第二节点的部分。
|
||||
- 在第二个可达节点或多卡节点到位后,执行多节点、多 GPU 并发、任务失败回收和重启恢复测试,完成上线验收闭环。
|
||||
|
||||
## 十五、本轮权限全量收口结果(2026-08-20)
|
||||
|
||||
### 已完成的开发
|
||||
|
||||
1. **租户成员角色真正参与资源授权**:ACL 的 `role` 主体不再只读取平台角色,改为读取资源所属租户中的有效成员角色;成员过期、禁用或不属于资源租户时不能通过角色 ACL 访问。
|
||||
2. **租户有效期隔离**:用户可用租户集合和资源授权均校验成员有效期,避免过期成员继续访问资源。
|
||||
3. **用户生命周期闭环**:用户删除改为软删除,保留用户和审计链路;同时注销会话、禁用租户成员、撤销用户 ACL、取消待审批申请、释放 GPU 分配,并禁止删除租户最后一个 owner。
|
||||
4. **资源和对象清理链路**:被删除用户创建的模型、训练模型、数据集、评测、推理、数据处理和数据转换资源统一标记删除;关联 MinIO `storage_objects` 标记为 `deleted`,进入既有清理/重试队列;资源 ACL 和安全状态同步撤销。
|
||||
5. **推理入口补强**:训练模型预加载必须引用真实且未删除的训练模型资源,普通用户不能通过任意本地路径绕过资源授权;本地推理状态查询要求普通用户提供有 `read` 权限的推理任务。
|
||||
6. **初始化和迁移完整性**:新增 `011_permission_lifecycle.sql`,完整初始化脚本同步补齐用户、评测、推理、数据转换和存储对象生命周期字段;离线目录仍只保留完整的 `000_full_init.sql`。
|
||||
|
||||
### 自动验证结果
|
||||
|
||||
- `python -m py_compile backend/app/core/auth.py backend/app/db/platform_store.py backend/app/api/v1/endpoints/platform.py`:通过。
|
||||
- `git diff --check`:通过。
|
||||
- WSL Backend 容器启动并自动执行迁移后为 `healthy`;已核对 `users`、`eval_tasks`、`compare_tasks`、`data_convert_tasks`、`storage_objects` 的新增字段均存在。
|
||||
- `test_permission_security.py` 与 `test_storage_security.py`:8 passed;仅有容器内 pytest 缓存目录只读警告。
|
||||
- 真实 API 闭环:临时用户删除后状态为 `deleted`、存在 `deleted_at`,使用原凭据登录返回 HTTP 401。
|
||||
- 前端 `npm run build`:需在本轮同步后再次执行,预期仅保留既有资源路径和 chunk size 警告;该项以最终命令结果为准。
|
||||
|
||||
### 仍需现场验证的场景
|
||||
|
||||
1. 第二个 active 用户和第二个租户的邀请、接受、租户切换及跨租户资源访问。
|
||||
2. 租户 GPU 配额为 1 时,训练/评测/推理并发预留、终态释放和服务重启恢复。
|
||||
3. 同一多卡节点的同卡冲突、不同卡并行和节点不可达后的回收。
|
||||
4. 审批过期、重复回调、拒绝、撤回和执行失败重试的真实链路。
|
||||
5. MinIO 故障注入后的任务失败、GPU/配额释放、对象清理重试和恢复后重新提交。
|
||||
|
||||
以上项目属于环境依赖型验收,不再作为代码未开发项;在当前单节点、单用户测试环境中保留为上线前验证项。
|
||||
|
||||
## 十六、前端权限页面收口结果(2026-08-20)
|
||||
|
||||
本轮已完成前端权限页面的主要操作闭环:
|
||||
|
||||
1. `用户权限设置`由占位页改为完整权限矩阵,支持按平台角色、账号状态和页面权限保存;已删除用户进入只读态,管理员角色自动拥有全部页面权限。
|
||||
2. 用户创建页增加页面权限配置,普通用户默认不授予组织管理和算力节点权限。
|
||||
3. 用户管理页增加权限入口、权限数量、软删除状态和危险操作禁用逻辑。
|
||||
4. 资源 ACL 页支持用户/租户角色主体、权限标签、全部撤销二次确认和加载失败提示。
|
||||
5. 审批策略页从 JSON 文本改为可视化配置指定用户、租户管理员和平台管理员审批步骤。
|
||||
6. 审批申请和访问申请页增加中文事项、资源类型、权限和状态展示,保留资源 ID 作为详情信息。
|
||||
7. 普通用户可进入审批中心的“我的申请”“访问申请”“租户邀请”,支持撤回访问申请和接受有效租户邀请。
|
||||
8. 租户成员邀请页增加邀请有效期设置;租户配额和 GPU 预留量继续在租户详情页展示。
|
||||
9. 本轮前端源码已同步至 `docker/offline/src/frontend/src`,初始化 SQL 目录仍只保留 `000_full_init.sql`。
|
||||
|
||||
前端 `npm run build` 已通过。尚需浏览器实际点击验证页面布局、不同账号菜单差异、双用户跨租户流程和多 GPU/MinIO 故障场景;这些属于环境验收,不再是页面缺少开发入口。
|
||||
227
docs/权限验收测试用例.md
Normal file
227
docs/权限验收测试用例.md
Normal file
@@ -0,0 +1,227 @@
|
||||
# 权限验收测试用例
|
||||
|
||||
> 版本:权限 2.0 前端权限页面收口版
|
||||
> 编写日期:2026-08-20
|
||||
> 适用系统:YG_FT 微调平台主工程、Backend、Frontend、Compute Agent、PostgreSQL、Redis、MinIO
|
||||
> 说明:本文件将自动化验证、单节点页面验证和多用户/多节点专项验证分开记录。
|
||||
|
||||
## 1. 验收目标
|
||||
|
||||
验证平台权限功能是否能够形成以下闭环:
|
||||
|
||||
`登录认证 → 页面权限 → 租户成员 → 资源创建 → ACL/访问申请 → 审批 → 训练/评测/推理执行 → GPU/配额预留 → 任务释放 → 审计 → 软删除和对象清理`
|
||||
|
||||
验收重点:
|
||||
|
||||
- 前端页面是否提供完整的权限管理入口。
|
||||
- 普通用户是否可以提交访问申请、查看自己的申请和接受租户邀请。
|
||||
- 管理员是否可以配置用户页面权限、租户成员、租户配额、资源 ACL 和审批策略。
|
||||
- 页面按钮隐藏只是辅助体验,直接调用接口仍必须由后端返回 401/403。
|
||||
- 用户、租户、资源、ACL、审批、GPU、配额和 MinIO 对象状态是否能够保持一致。
|
||||
|
||||
## 2. 测试环境
|
||||
|
||||
### 2.1 服务
|
||||
|
||||
| 服务 | 地址/容器 | 验收要求 |
|
||||
|---|---|---|
|
||||
| Frontend | `http://127.0.0.1:16801` | 页面可打开,路由切换无白屏 |
|
||||
| Backend | `http://127.0.0.1:17861/modelTF` | 健康接口返回成功 |
|
||||
| Compute API | `http://172.25.179.69:19100` | 当前可达节点可进行单节点验证 |
|
||||
| Redis | WSL Docker `yg-ft-redis` | 容器 healthy |
|
||||
| MinIO | WSL Docker `yg-ft-minio` | 容器 healthy,可进行对象读写 |
|
||||
| PostgreSQL | 当前环境实际远程 PostgreSQL | 初始化字段和增量迁移均存在 |
|
||||
|
||||
### 2.2 测试账号和数据
|
||||
|
||||
准备以下测试对象,禁止使用生产账号和真实敏感数据:
|
||||
|
||||
| 对象 | 建议值 | 说明 |
|
||||
|---|---|---|
|
||||
| 平台管理员 | 当前环境管理员账号 | 执行用户、租户、ACL、审批和配额管理 |
|
||||
| 普通用户 A | 新建测试用户 | 作为资源所有者 |
|
||||
| 普通用户 B | 新建测试用户 | 作为被授权用户和申请人 |
|
||||
| 租户 A | 新建测试租户 | 与租户 B 隔离验证 |
|
||||
| 租户 B | 新建测试租户 | 跨租户访问验证 |
|
||||
| 测试数据集 | `test_data_0817` 或新的小数据集 | 用于 ACL、训练和下载验证 |
|
||||
| 测试模型 | `qwen3.5-0.8B` | 用于模型使用权限和推理验证 |
|
||||
|
||||
## 3. 自动化验证结果
|
||||
|
||||
以下项目已在当前开发环境执行:
|
||||
|
||||
| 编号 | 验证内容 | 结果 |
|
||||
|---|---|---|
|
||||
| AUTO-01 | `npm run build` | 通过;仅有既有 Font Awesome 路径和 chunk size 警告 |
|
||||
| AUTO-02 | `test_permission_security.py` | 通过,8 passed |
|
||||
| AUTO-03 | `test_storage_security.py` | 已包含在 8 passed 中 |
|
||||
| AUTO-04 | 后端权限文件 `py_compile` | 通过 |
|
||||
| AUTO-05 | `git diff --check` | 通过 |
|
||||
| AUTO-06 | Backend、Frontend、Compute、Redis、MinIO 容器状态 | 通过,Backend healthy |
|
||||
| AUTO-07 | 迁移后字段核对 | 通过,users、eval_tasks、compare_tasks、data_convert_tasks、storage_objects 字段存在 |
|
||||
| AUTO-08 | 临时用户软删除闭环 | 通过,状态为 deleted、存在 deleted_at,原凭据登录返回 401 |
|
||||
| AUTO-09 | `docker/offline/src` 同步 | 通过,离线 SQL 目录只保留 `000_full_init.sql` |
|
||||
|
||||
## 4. 前端页面验收
|
||||
|
||||
### 4.1 组织与权限
|
||||
|
||||
页面入口:`/organization`
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| UI-ORG-01 | 管理员打开“组织与权限” | 显示“用户与角色”“租户与配额”两个页签 |
|
||||
| UI-ORG-02 | 点击“创建用户” | 进入用户创建页面,可填写账号、角色、状态和页面权限 |
|
||||
| UI-ORG-03 | 创建普通用户 | 默认授予业务页面权限,不自动授予组织管理和算力节点权限 |
|
||||
| UI-ORG-04 | 用户列表点击“权限” | 进入 `/user-settings/:id/permission`,显示用户角色、所属租户、状态和权限矩阵 |
|
||||
| UI-ORG-05 | 修改用户页面权限并保存 | 页面提示保存成功,刷新后权限保持一致 |
|
||||
| UI-ORG-06 | 将普通用户改为管理员 | 页面显示全部权限;保存时自动补齐全部权限码 |
|
||||
| UI-ORG-07 | 查看已软删除用户 | 显示“已删除”,权限页只读,不能重新激活 |
|
||||
| UI-ORG-08 | 普通用户访问组织与权限 | 路由跳转到无权访问页,菜单不显示管理员治理入口 |
|
||||
|
||||
### 4.2 租户与配额
|
||||
|
||||
页面入口:`/organization?tab=tenants`、`/tenants/:id`
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| UI-TEN-01 | 管理员创建租户并设置 GPU、存储配额 | 租户列表出现新租户,配额显示正确 |
|
||||
| UI-TEN-02 | 打开租户详情 | 显示租户信息、配额设置、GPU 预留量和成员列表 |
|
||||
| UI-TEN-03 | 邀请成员并设置角色、邀请有效期 | 页面提示邀请成功,成员状态为待接受,过期时间正确 |
|
||||
| UI-TEN-04 | 修改成员角色 | 成员列表角色更新,不能通过页面授予非法 owner 权限 |
|
||||
| UI-TEN-05 | 移除成员 | 成员状态/关系更新,后续资源访问按后端权限拒绝 |
|
||||
| UI-TEN-06 | 保存配额 | 配额配置更新,已预留 GPU 数量不超过新配额 |
|
||||
|
||||
### 4.3 我的申请与租户邀请
|
||||
|
||||
页面入口:`/approval-instances?tab=mine`、`/approval-instances?tab=access`、`/approval-instances?tab=invitations`
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| UI-SELF-01 | 普通用户打开审批中心 | 可进入,不再被管理员专属路由拦截 |
|
||||
| UI-SELF-02 | 打开“访问申请” | 可选择可见的数据集/训练模型,资源名称优先显示中文名称,同时保留 ID |
|
||||
| UI-SELF-03 | 提交 read/execute/download 申请 | 申请出现在“我的访问申请”,状态为审批中 |
|
||||
| UI-SELF-04 | 撤回待审批申请 | 二次确认后状态变为已撤回,不能再次撤回 |
|
||||
| UI-SELF-05 | 打开“租户邀请” | 显示租户、角色、邀请人、有效期和状态 |
|
||||
| UI-SELF-06 | 接受有效邀请 | 状态变为已加入,获得对应租户成员关系 |
|
||||
| UI-SELF-07 | 接受过期邀请 | 后端拒绝,页面显示失败原因,成员关系不产生 |
|
||||
|
||||
### 4.4 资源授权
|
||||
|
||||
页面入口:`/resource-acl`
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| UI-ACL-01 | 管理员选择数据集或训练模型 | 显示资源名称和资源 ID,不显示已软删除资源 |
|
||||
| UI-ACL-02 | 查看资源 ACL | 显示用户/租户角色、主体类型和权限标签 |
|
||||
| UI-ACL-03 | 增加用户 ACL | 可选择查看、编辑、使用、下载等权限并保存 |
|
||||
| UI-ACL-04 | 增加角色 ACL | 可选择租户管理员、成员、只读角色;后端校验最终结果 |
|
||||
| UI-ACL-05 | 移除全部 ACL | 页面二次确认后保存空 ACL,授权全部撤销 |
|
||||
| UI-ACL-06 | ACL 查询失败 | 页面显示明确错误提示,不把失败误显示为空授权 |
|
||||
| UI-ACL-07 | 普通用户打开资源授权页面 | 页面入口隐藏,直接访问接口返回 403 |
|
||||
|
||||
### 4.5 审批中心
|
||||
|
||||
页面入口:`/approval-instances`
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| UI-APP-01 | 管理员打开审批申请 | 显示资源类型、申请事项、申请人、状态和当前步骤的中文信息 |
|
||||
| UI-APP-02 | 管理员打开审批策略 | 可配置指定用户、租户管理员、平台管理员审批步骤,不需要输入 JSON |
|
||||
| UI-APP-03 | 指定审批人审批 | 只能由当前会话指定审批人执行,审批结果和意见可见 |
|
||||
| UI-APP-04 | 申请人查看自己的申请 | 只能看到自己的申请,不显示其他租户的审批数据 |
|
||||
| UI-APP-05 | 审批通过 | ACL、GPU 分配或成员关系等业务效果真正落地 |
|
||||
| UI-APP-06 | 审批拒绝/过期 | 状态明确显示,不能产生授权或资源占用 |
|
||||
|
||||
## 5. 后端接口与页面联动验收
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| API-AUTH-01 | 未登录访问任意受保护页面接口 | 返回 401,前端回到登录页 |
|
||||
| API-AUTH-02 | 普通用户直接调用管理员接口 | 返回 403,不能仅依赖前端隐藏按钮 |
|
||||
| API-AUTH-03 | 禁用用户使用旧 Token | 返回 401 或明确无效会话错误 |
|
||||
| API-AUTH-04 | 已删除用户登录 | 返回 401 |
|
||||
| API-TEN-01 | 用户访问其他租户资源详情 | 返回 403 或资源不存在,不泄露资源内容 |
|
||||
| API-TEN-02 | 过期成员访问租户资源 | 返回 403 |
|
||||
| API-ACL-01 | 没有 read 的用户读取资源 ACL | 返回 403 |
|
||||
| API-ACL-02 | 只有 read 的用户执行模型推理 | 返回 403 |
|
||||
| API-ACL-03 | 只有 execute 的用户下载模型 | 返回 403 |
|
||||
| API-ACL-04 | ACL 授权后重新访问 | 按授权动作成功 |
|
||||
| API-APP-01 | 申请人提交自己的审批决策 | 返回 403 |
|
||||
| API-APP-02 | 非指定审批人提交决策 | 返回 403 |
|
||||
| API-APP-03 | 重复提交相同资源访问申请 | 复用或拒绝重复待审批申请,不重复写 ACL |
|
||||
| API-LIFE-01 | 删除用户 | 会话、成员、ACL、GPU 分配、待审批项和用户资源状态同步处理 |
|
||||
| API-LIFE-02 | 执行存储清理 | 已删除 MinIO 对象进入清理,失败任务可重试 |
|
||||
|
||||
## 6. 训练、评测、推理权限验收
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| JOB-01 | 用户使用无权限数据集创建训练 | 预检失败,显示数据集无权限 |
|
||||
| JOB-02 | 用户使用授权数据集创建训练 | 预检通过,GPU 和租户配额原子预留 |
|
||||
| JOB-03 | 用户使用未授权训练模型推理 | 页面提示无权限,接口返回 403 |
|
||||
| JOB-04 | 用户使用已授权训练模型推理 | 可选择有权限的算力节点和 GPU 卡 |
|
||||
| JOB-05 | 用户没有 download 权限导出模型 | 操作按钮不显示,接口返回 403 |
|
||||
| JOB-06 | 评测任务结束 | GPU 预留和租户配额预留释放 |
|
||||
| JOB-07 | 推理任务删除 | 推理服务释放,任务软删除,ACL 状态撤销 |
|
||||
| JOB-08 | 节点不可达或 MinIO 暂时不可用 | 任务进入失败/重试状态,不留下永久 GPU 或配额占用 |
|
||||
|
||||
## 7. GPU、配额和多节点专项验收
|
||||
|
||||
以下用例需要第二个可达节点或一个包含多张可分配 GPU 卡的节点,当前单节点环境暂保留。
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| GPU-01 | 租户 GPU 配额设置为 1,同时提交两个 GPU 任务 | 第二个任务被拒绝,不能超配 |
|
||||
| GPU-02 | 同一节点同一张卡由两个用户申请 | 审批/分配阶段返回 409,不能重复占用 |
|
||||
| GPU-03 | 同一节点选择两张空闲卡 | 任务使用页面指定的两张卡,不使用其他卡 |
|
||||
| GPU-04 | 任务失败或取消 | GPU 分配和配额预留释放 |
|
||||
| GPU-05 | Backend 重启后恢复任务状态 | 已完成/失败任务不重复占用;运行任务保持可对账 |
|
||||
| GPU-06 | 模型训练、推理、评测选择不同节点 | 模型和数据从 MinIO 准备到指定节点,不错误派发到其他节点 |
|
||||
| GPU-07 | 节点失联 | 任务进入失败或待重试,资源占用在超时后回收 |
|
||||
|
||||
## 8. MinIO 故障专项验收
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| MINIO-01 | 暂停 MinIO 容器后上传数据集 | 页面显示明确存储不可用,不显示上传成功 |
|
||||
| MINIO-02 | MinIO 暂停期间预检训练 | 预检提示对象不可用,可重试 |
|
||||
| MINIO-03 | MinIO 恢复后重试任务 | 对象可重新准备,任务继续或重新提交成功 |
|
||||
| MINIO-04 | 删除用户后执行对象清理 | 用户资源对象标记 deleted,清理成功后标记 purged |
|
||||
| MINIO-05 | 清理时对象删除失败 | storage cleanup job 保留 failed 状态和错误原因,后续可重试 |
|
||||
|
||||
## 9. 离线部署验收
|
||||
|
||||
| 用例 | 操作步骤 | 预期结果 |
|
||||
|---|---|---|
|
||||
| OFFLINE-01 | 检查 `docker/offline/src/backend/app/db/sql` | 只存在完整的 `000_full_init.sql` |
|
||||
| OFFLINE-02 | 清空数据库并执行完整初始化 SQL | 不缺权限相关表和字段,Backend 可启动 |
|
||||
| OFFLINE-03 | 离线启动 Frontend | 不请求在线 CDN,页面可正常打开 |
|
||||
| OFFLINE-04 | 离线启动 Backend、Compute、MinIO | 各服务使用独立网络和配置,权限接口可用 |
|
||||
| OFFLINE-05 | 离线新库执行用户/租户/ACL/审批流程 | 与主工程行为一致 |
|
||||
|
||||
## 10. 问题记录规则
|
||||
|
||||
每条失败用例至少记录:
|
||||
|
||||
- 测试编号、执行时间、执行人和账号。
|
||||
- 页面 URL、接口 URL、请求方法和请求 ID。
|
||||
- 当前用户、租户、资源 ID、资源所属租户。
|
||||
- 实际 HTTP 状态码、页面提示、数据库状态和容器日志。
|
||||
- 是否产生了残留 ACL、GPU 分配、配额预留、MinIO 对象或审批记录。
|
||||
- 修复提交、回归结果和是否需要再次现场验证。
|
||||
|
||||
## 11. 当前验收结论
|
||||
|
||||
当前已自动验证:前端构建、后端权限安全测试、存储安全测试、数据库字段迁移、容器健康、用户软删除登录拦截和离线源码 SQL 目录结构。
|
||||
|
||||
当前前端权限页面已完成主要操作闭环:
|
||||
|
||||
- 用户页面权限设置。
|
||||
- 用户创建时的页面权限配置。
|
||||
- 租户成员邀请、角色、有效期和配额展示。
|
||||
- 普通用户访问申请、我的申请和租户邀请接受。
|
||||
- 资源用户/角色 ACL 管理和全部撤销。
|
||||
- 审批申请、审批策略可视化配置和中文状态展示。
|
||||
|
||||
仍需现场验证:双用户跨租户、多 GPU 并发、第二节点调度、节点失联回收、MinIO 故障注入和完整浏览器点击流。这些属于环境依赖型验收,不代表前端页面缺少入口。
|
||||
161
docs/模型评测优化设计方案.md
Normal file
161
docs/模型评测优化设计方案.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# 模型评测优化设计方案
|
||||
|
||||
## 1. 现状检查
|
||||
|
||||
当前模型评测菜单已经具备以下基础能力:
|
||||
|
||||
- 创建评测任务:选择训练模型、评测数据集、算力节点和 GPU。
|
||||
- 任务调度:后端将模型、适配器、数据集准备到目标算力节点,再提交 Compute API 任务。
|
||||
- 模型推理:Compute Agent 使用 LLaMA-Factory 推理会话逐条生成回答。
|
||||
- 结果落库:任务完成后读取 `eval_results.json`,写入任务详情、样本结果和指标摘要。
|
||||
- 报告归档:评测输出目录可以归档到 MinIO,并通过报告接口下载。
|
||||
- 前端详情:显示综合分、通过率、样本结果、指标摘要,并对运行中的任务进行轮询。
|
||||
|
||||
当前缺陷主要集中在评分和进度链路:
|
||||
|
||||
1. 创建页面的 BLEU、ROUGE、余弦指标默认全部关闭;未配置 LLM 评委时,样本没有确定性评分,容易得到 0 分。
|
||||
2. BLEU、ROUGE、余弦、LLM Judge 的返回范围和含义不统一,百分制、0-1、小量程评分混在一起。
|
||||
3. 评测模型地址直接拼接 `/v1/chat/completions`,当地址已经包含 `/v1` 时会出现 `/v1/v1`。
|
||||
4. LLM Judge 只解析少量文本格式,无法可靠解析 JSON、Markdown JSON 或 0-1 综合评价。
|
||||
5. ROUGE 对中文没有采用 `nlp-eval-demo` 的字符级中文分词策略,中文短文本容易得到失真的结果。
|
||||
6. 后端只在 Compute 任务完成后读取结果文件,运行时没有样本完成数、当前阶段和中间指标。
|
||||
7. 前端没有雷达图,用户无法直观看到 BLEU、ROUGE、语义相似度、精确匹配和 LLM Judge 等维度。
|
||||
|
||||
## 2. 目标
|
||||
|
||||
建立一条可解释、可持续轮询、兼容旧任务的评测闭环:
|
||||
|
||||
```text
|
||||
创建任务 -> 资源准备 -> 模型加载 -> 样本推理 -> 逐样本评分
|
||||
-> 中间进度文件 -> 后端同步 -> 页面进度与雷达图
|
||||
-> 完成报告 -> MinIO 归档 -> 详情与下载
|
||||
```
|
||||
|
||||
目标结果:
|
||||
|
||||
- 所有最终展示分数统一为 0-100,避免不同指标之间直接相加造成误解。
|
||||
- 没有 LLM 评委时,仍然使用确定性指标生成样本得分和综合分,不再因为“未配置评委”自动归零。
|
||||
- 有 LLM 评委时,保留原有自定义评分区间,同时将其归一化到 0-100 展示。
|
||||
- 每个评测任务都能看到阶段、总样本数、已完成样本数、百分比和当前指标状态。
|
||||
- 详情页展示指标雷达图;指标不可用时显示原因,不把“依赖未安装”伪装成 0 分。
|
||||
- 不新增必需数据库表,继续利用 `eval_tasks.payload` 保存评测结果和进度,兼容现有数据库及离线初始化 SQL。
|
||||
|
||||
## 3. 评分设计
|
||||
|
||||
### 3.1 指标契约
|
||||
|
||||
Compute Agent 内部统一使用以下结构:
|
||||
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"available": true,
|
||||
"score": 82.5,
|
||||
"max_score": 100,
|
||||
"unit": "percent",
|
||||
"sample_count": 3,
|
||||
"error": ""
|
||||
}
|
||||
```
|
||||
|
||||
`score` 永远是 0-100。指标不可用时 `available=false`,`score` 可以为 null,同时保留 `error`。旧报告中只有 `score` 的结构继续兼容,后端读取时按旧结构补齐默认字段。
|
||||
|
||||
### 3.2 确定性指标
|
||||
|
||||
参考 `nlp-eval-demo` 的实现,支持:
|
||||
|
||||
- BLEU:sacrebleu,结果由 0-100 转换为百分制。
|
||||
- ROUGE-1、ROUGE-2、ROUGE-L:中文按字符切分,英文按词切分,使用 F1 均值并转换为百分制。
|
||||
- 余弦相似度:TF-IDF 余弦相似度,转换为百分制。
|
||||
- 精确匹配:标准化空白和大小写后完全一致,百分制。
|
||||
- 文本相似度:SequenceMatcher,作为无外部模型时的稳定兜底指标。
|
||||
- BERTScore:仅在 `bert_score` 和模型可用时启用;下载/加载失败只标记不可用,不阻断整个评测任务。
|
||||
|
||||
精确匹配和文本相似度始终计算。用户在创建页面选择的 BLEU、ROUGE、余弦作为额外指标;如果没有选择额外指标,也用“文本相似度 + ROUGE-L(可用时)”生成确定性综合分。
|
||||
|
||||
### 3.3 无 LLM 评委时的样本分数
|
||||
|
||||
对每条样本使用可用确定性指标的平均值作为样本百分制得分:
|
||||
|
||||
```text
|
||||
sample_score = mean(exact_match, text_similarity, rougeL, cosine, bleu, bertscore)
|
||||
```
|
||||
|
||||
其中未启用或不可用的指标不参与平均。样本通过阈值默认 60 分;如果旧维度配置的 `pass_threshold <= score_max`,先按旧量程换算为百分制。
|
||||
|
||||
### 3.4 LLM Judge
|
||||
|
||||
- 兼容 OpenAI Chat Completions 接口。
|
||||
- 自动规范化 `api_url`,避免重复 `/v1`。
|
||||
- 优先解析 JSON 的 `score`、`综合评价`、`overall_score`、`dimensions` 字段,再解析 Markdown/自然语言中的评分。
|
||||
- 支持 0-1、0-5、0-100 三种返回量程;最终统一转换为 0-100。
|
||||
- API 调用失败时记录样本失败原因,不把失败当作正常 0 分;如果所有样本都调用失败,任务状态仍可完成但报告会明确提示评委不可用。
|
||||
|
||||
## 4. 进度设计
|
||||
|
||||
Compute Agent 在评测输出目录写入两个文件:
|
||||
|
||||
- `eval_progress.json`:轻量进度文件,每完成一条样本更新一次。
|
||||
- `eval_results.json`:运行中写入部分结果,完成后写入完整报告。
|
||||
|
||||
进度结构:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "running",
|
||||
"stage": "inference",
|
||||
"total": 20,
|
||||
"completed": 7,
|
||||
"percentage": 35,
|
||||
"current_index": 8,
|
||||
"message": "正在生成第 8 条样本",
|
||||
"updated_at": "2026-08-20T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
后端详情接口每次轮询 Compute Agent:
|
||||
|
||||
1. 任务运行中读取 `eval_progress.json`,写入 `eval_tasks.payload.progress_detail`。
|
||||
2. 读取到部分 `eval_results.json` 时同步已完成样本和基础指标,页面可以边运行边展示。
|
||||
3. Compute 任务完成后读取完整报告,再执行 MinIO 归档。
|
||||
4. Compute Agent 暂时不可达时保留最后一次进度,不因为一次轮询失败把评测任务误判为失败。
|
||||
|
||||
## 5. 前端设计
|
||||
|
||||
- 列表页增加进度列:运行中显示 `已完成/总数` 和百分比,完成后显示最终分数。
|
||||
- 详情页增加当前阶段、进度消息和进度条。
|
||||
- 详情页增加“指标雷达图”,雷达轴来自可用的 `dimension_summary` 指标,最大值统一 100。
|
||||
- 指标卡同时显示分数、通过率、样本数和不可用原因。
|
||||
- 样本结果在运行中支持逐步出现,保留现有搜索、筛选和分页。
|
||||
- 不改变已有任务创建、删除、报告下载和权限校验流程。
|
||||
|
||||
## 6. 数据库与兼容性
|
||||
|
||||
本次不新增数据库表和必需字段。评测结果继续存放在 `eval_tasks.payload` JSON 中,新增键包括:
|
||||
|
||||
- `progress_detail`
|
||||
- `basic_metrics` 的统一指标对象
|
||||
- `metric_summary_version`
|
||||
- 样本的 `raw_score`、`raw_max_score`、`score`、`max_score`
|
||||
|
||||
旧任务兼容规则:缺少进度时由 `progress` 和样本数量推导;旧的量程评分按 `score/max_score` 转换为百分制;没有基础指标时显示“历史任务未保存指标明细”。因此无需修改 `000_full_init.sql`。
|
||||
|
||||
## 7. 实施步骤
|
||||
|
||||
1. 重构 Compute Agent 评测指标、中文 ROUGE、LLM Judge 解析、评分归一化和中间结果写入。
|
||||
2. 增加 Compute Agent 进度文件读取能力,后端同步运行中进度和部分结果。
|
||||
3. 扩展后端评测任务结果兼容、失败信息和进度返回。
|
||||
4. 扩展前端类型、列表进度列、详情进度区和指标雷达图。
|
||||
5. 增加单元测试、前端构建测试和接口/运行时冒烟验证。
|
||||
6. 同步前后端、算力服务到 `docker/offline/src`,确认初始化 SQL 无需变更。
|
||||
|
||||
## 8. 验收标准
|
||||
|
||||
- 使用仅包含 `instruction/output` 的小型 JSONL 数据集,未配置 LLM Judge 时综合分不再固定为 0。
|
||||
- 中文答案能得到可解释的 ROUGE-1/2/L 分数。
|
||||
- LLM Judge 的地址为 `https://host/v1` 时请求路径仍正确。
|
||||
- 评测运行期间能看到 `completed/total` 和百分比变化。
|
||||
- 完成后详情页存在至少 3 个可用指标时显示雷达图,指标少于 3 个时显示明细降级视图。
|
||||
- 失败、依赖缺失、空答案等情况能在报告中区分,不以正常 0 分掩盖原因。
|
||||
- 现有权限、GPU 预约、MinIO 归档、报告下载和旧任务查看不受影响。
|
||||
|
||||
628
docs/租户与用户权限体系梳理及纠偏流程.md
Normal file
628
docs/租户与用户权限体系梳理及纠偏流程.md
Normal file
@@ -0,0 +1,628 @@
|
||||
# 租户与用户权限体系梳理及纠偏流程
|
||||
|
||||
> 版本:v1.0
|
||||
> 梳理日期:2026-08-20
|
||||
> 适用范围:YG_FT 平台后端、前端、Compute Agent、MinIO、PostgreSQL 及离线部署目录
|
||||
> 目的:明确租户、用户、角色、权限、资源和审批之间的层级关系,识别当前实现中的概念冲突,并为后续优化提供唯一设计口径。
|
||||
|
||||
## 一、结论摘要
|
||||
|
||||
当前系统已经具备用户登录、租户字段、租户成员、资源 ACL、审批、GPU 分配和资源级动作校验,但概念来源还没有完全收敛,主要表现为:
|
||||
|
||||
1. **用户和租户没有混为一个数据库对象,但业务流程中边界不清**:用户表保存 `tenant_id`,同时又通过 `tenant_members` 表表达租户关系,导致“主租户”和“成员关系”的判定规则并存。
|
||||
2. **平台角色、租户角色、页面权限码、资源动作权限同时存在,但职责没有彻底分离**:`users.role`、`users.permissions`、`tenant_members.role`、`roles.permissions` 可能产生不一致。
|
||||
3. **资源归属字段不统一**:部分资源使用独立的 `created_by`,部分任务把创建者放在 `payload.created_by`,部分资源的 `tenant_id` 允许为空,历史数据因此出现“ACL 已授权但列表不可见”的问题。
|
||||
4. **租户创建、用户创建、成员加入和资源授权是四条不同流程,目前在页面上有交叉**:创建用户时直接写入租户成员,租户的 `owner_user_id` 却没有同步建立 owner 成员关系。
|
||||
5. **项目表和项目字段仍在数据库及部分接口中保留**,但当前产品已经取消项目作为用户可见的业务隔离层,继续把 `project_id` 当权限条件会造成新的歧义。
|
||||
6. **正确的目标模型应当是**:平台管理员管理平台身份和租户;用户通过租户成员关系进入一个或多个租户;资源属于一个租户并有一个所有者;资源使用通过 ACL 动作权限;高风险动作通过审批;GPU 和配额是资源使用前的运行时约束。
|
||||
|
||||
本文件的纠偏原则是:**先统一口径,再做兼容迁移;先保证后端判定一致,再调整前端菜单和数据库约束;历史字段暂不删除,但不再新增新的业务依赖。**
|
||||
|
||||
## 二、目标层级模型
|
||||
|
||||
```text
|
||||
平台 Platform
|
||||
│
|
||||
├── 平台身份与平台角色
|
||||
│ ├── platform_admin:平台管理员,可管理租户、用户、策略和全部资源
|
||||
│ └── platform_user:普通平台用户,不因登录自动获得资源权限
|
||||
│
|
||||
├── 租户 Tenant
|
||||
│ ├── 租户基本信息、状态、配额、留存策略
|
||||
│ ├── 租户成员 TenantMember
|
||||
│ │ ├── owner:租户所有者
|
||||
│ │ ├── admin:租户管理员
|
||||
│ │ ├── member:普通成员
|
||||
│ │ └── viewer:只读成员
|
||||
│ └── 租户内资源
|
||||
│ ├── 数据集
|
||||
│ ├── 基座模型
|
||||
│ ├── 训练任务与训练模型
|
||||
│ ├── 评测任务
|
||||
│ ├── 推理任务
|
||||
│ └── 数据处理/转换任务
|
||||
│
|
||||
├── 资源授权 Resource ACL
|
||||
│ ├── principal:user 或 tenant role
|
||||
│ ├── read:查看
|
||||
│ ├── write:编辑
|
||||
│ ├── execute:训练、推理、评测等使用
|
||||
│ ├── download:下载或导出文件
|
||||
│ ├── delete:删除
|
||||
│ └── admin:资源授权和完整管理
|
||||
│
|
||||
├── 运行时资源
|
||||
│ ├── Compute Node
|
||||
│ ├── GPU
|
||||
│ ├── GPU assignment:用户获批可使用哪些 GPU
|
||||
│ ├── GPU reservation:任务当前占用哪些 GPU
|
||||
│ └── Tenant quota reservation:租户当前预留了多少运行资源
|
||||
│
|
||||
└── 审批与审计
|
||||
├── resource access:申请资源 ACL
|
||||
├── gpu.assign:申请算力卡
|
||||
├── tenant.quota.update:申请租户配额变更
|
||||
├── 高风险删除/导出/合并操作
|
||||
└── 全部结果写入审计日志
|
||||
```
|
||||
|
||||
### 2.1 四个必须分开的概念
|
||||
|
||||
| 概念 | 正确含义 | 不应承担的职责 |
|
||||
|---|---|---|
|
||||
| 用户 User | 可登录平台的人或服务账号 | 不代表租户,也不自动代表资源权限 |
|
||||
| 租户 Tenant | 资源、成员、配额和审计的隔离边界 | 不直接作为登录账号 |
|
||||
| 角色 Role | 某个范围内的一组职责 | 不应直接等同于某个用户的全部资源权限 |
|
||||
| 权限 Permission | 对页面或资源的具体操作能力 | 不应只靠前端按钮控制 |
|
||||
|
||||
## 三、当前实现盘点
|
||||
|
||||
### 3.1 用户身份层
|
||||
|
||||
当前主要实现位置:
|
||||
|
||||
- `users` 表:保存账号、密码哈希、平台角色、状态、页面权限 JSON、主租户字段。
|
||||
- `sessions` 表:保存登录会话、过期时间和注销时间。
|
||||
- `backend/app/core/auth.py`:解析 Token、校验用户状态、校验页面权限和租户上下文。
|
||||
- `/users` 接口:当前只有管理员可以创建、修改、禁用和删除用户。
|
||||
|
||||
当前用户对象包含:
|
||||
|
||||
```text
|
||||
id / username / display_name / status
|
||||
role / protected / permissions
|
||||
tenant_id
|
||||
```
|
||||
|
||||
存在的混淆:
|
||||
|
||||
- `role=operator/viewer/user` 是平台用户字段,但 `tenant_members.role` 还有 `owner/admin/member/viewer`,两套角色名称不在同一层级。
|
||||
- `role=user` 在创建接口中被接受,但设计文档主要定义的是 `admin/operator/viewer/guest`,前端又同时显示“普通用户”。
|
||||
- 创建用户时直接生成 `tenant_members` 活跃成员记录;这相当于“创建用户”和“加入租户”一次完成,没有邀请、待确认或成员审批边界。
|
||||
- `users.permissions` 是用户级 JSON,`roles` 表只提供查询接口,当前没有形成“角色变更自动计算权限”的唯一来源。
|
||||
- 非管理员创建/更新用户时会被剥离 `compute` 和 `user-settings`,但初始化 SQL 中的 `u_operator` 种子数据仍包含 `compute`,代码默认值和 SQL 种子不一致。
|
||||
|
||||
### 3.2 租户层
|
||||
|
||||
当前主要实现位置:
|
||||
|
||||
- `tenants` 表:保存租户名称、状态、owner_user_id、配额和留存策略。
|
||||
- `tenant_members` 表:保存租户与用户的多对多关系、租户角色、状态、邀请人和有效期。
|
||||
- `tenant_membership()`、`user_tenant_ids()`:判定当前用户的租户范围。
|
||||
- `/tenants/{tenant_id}/members`:管理员或租户 owner/admin 管理成员。
|
||||
|
||||
当前逻辑:
|
||||
|
||||
```text
|
||||
当前用户租户范围 = users.tenant_id + tenant_members 中 status=active 的 tenant_id
|
||||
当前请求租户 = X-Tenant-ID(仅在用户属于该租户时生效)
|
||||
资源租户 = 资源 tenant_id,部分任务还会从 payload 中读取 tenant_id
|
||||
```
|
||||
|
||||
主要问题:
|
||||
|
||||
1. `users.tenant_id` 和 `tenant_members` 都能表达租户关系,但没有明确谁是主数据、谁是兼容字段。
|
||||
2. `tenants.owner_user_id` 创建租户时写入,但创建租户流程没有自动写入对应的 `tenant_members(role='owner')`。
|
||||
3. 平台管理员创建普通用户时直接加入租户,租户管理员也可以直接添加成员,邀请/加入申请流程虽已具备接口,但不是主流程。
|
||||
4. `tenant_id` 在资源表中有的为 `NOT NULL`,有的允许 `NULL`;历史资源的 `NULL` 租户需要特殊兼容判断。
|
||||
5. 租户删除是状态删除,但成员、资源、ACL、审批、MinIO 对象和本地缓存的后续处理没有统一的生命周期编排入口。
|
||||
|
||||
### 3.3 页面权限层
|
||||
|
||||
页面权限由两部分组成:
|
||||
|
||||
```text
|
||||
前端:路由 meta.permission + 侧边栏过滤 + 按钮显示
|
||||
后端:MODULE_PERMISSIONS + get_current_user / require_admin
|
||||
```
|
||||
|
||||
页面权限码包括:
|
||||
|
||||
```text
|
||||
dashboard, fine-tune, model-eval, model-inference,
|
||||
model-manage, dataset, data-process, data-convert,
|
||||
compute, hardware, logs, user-settings
|
||||
```
|
||||
|
||||
问题:
|
||||
|
||||
- 页面权限码是“能否进入模块”,不是“能否使用某一条数据或 GPU”,但历史实现中一度把 `compute` 页面权限阻断了普通用户读取自己获批 GPU 的接口,造成“有 GPU 分配但训练页面看不到”的问题。
|
||||
- 普通用户的 `compute` 管理菜单应保持隐藏,但训练、推理、评测所需的个人节点/GPU查询应当是独立的自助只读接口。
|
||||
- 前端权限控制和后端权限控制分别维护,按钮隐藏不能作为安全边界。
|
||||
|
||||
### 3.4 资源权限层
|
||||
|
||||
当前资源权限主要由以下条件组合:
|
||||
|
||||
```text
|
||||
平台管理员旁路
|
||||
或
|
||||
资源属于当前租户
|
||||
且(资源所有者 == 当前用户
|
||||
或 ACL 明确授权
|
||||
或当前用户是租户 owner/admin)
|
||||
且满足具体动作 read/write/execute/download/delete/admin
|
||||
```
|
||||
|
||||
已接入资源类型包括:
|
||||
|
||||
```text
|
||||
dataset / model / trained_model / fine-tune / eval / inference
|
||||
data_process / data_convert / compare / project(历史兼容)
|
||||
```
|
||||
|
||||
当前差异:
|
||||
|
||||
| 资源 | 当前所有者来源 | 当前租户来源 | 主要风险 |
|
||||
|---|---|---|---|
|
||||
| datasets | `created_by` | `tenant_id`,部分历史为空 | 列表、详情、训练权限可能不一致 |
|
||||
| models | `created_by` | `tenant_id`,基座模型存在平台共享规则 | 基座模型共享与训练产物共享容易混淆 |
|
||||
| trained_models | `created_by` | `tenant_id` | 血缘来源、默认授权需统一 |
|
||||
| fine_tune_tasks | 多数在 `payload.created_by` | 多数在 payload 或派生字段 | 结构化查询和授权容易漏字段 |
|
||||
| eval_tasks | `created_by` | `tenant_id` | 与数据集/模型执行权限必须同时校验 |
|
||||
| compare_tasks | 表字段和 payload 并存 | 表字段和 payload 并存 | 推理任务与模型使用权限容易分裂 |
|
||||
| data_process_tasks | `created_by` | `tenant_id` | 处理结果派生数据集授权不明确 |
|
||||
| data_convert_tasks | `created_by` | `tenant_id` | 历史表结构和初始化脚本存在演进痕迹 |
|
||||
| projects | `create_by` 等历史字段 | `tenant_id` | 当前已取消项目业务层,但表和接口仍在 |
|
||||
|
||||
### 3.5 GPU 与运行时权限层
|
||||
|
||||
GPU 相关关系实际上有三层:
|
||||
|
||||
```text
|
||||
gpus
|
||||
└── gpu_assignments:管理员批准“用户可以使用哪张卡”
|
||||
└── gpu_allocations / gpu_reservations:任务运行时“当前占用了哪张卡”
|
||||
```
|
||||
|
||||
正确判定顺序应为:
|
||||
|
||||
1. 用户拥有租户成员资格且账号 active。
|
||||
2. 用户已经获得该 GPU 的分配或管理员旁路。
|
||||
3. 节点 online、enabled,GPU 存在且没有被其他任务占用。
|
||||
4. 租户配额可以完成原子预留。
|
||||
5. 训练、推理或评测任务提交到指定节点。
|
||||
|
||||
目前已经有分配申请、审批后写入 `gpu_assignments`、运行时预留和释放逻辑,但仍需把“审批结果、GPU 分配、配额预留、节点故障回收”统一成一个状态机。
|
||||
|
||||
## 四、当前数据库关系与问题
|
||||
|
||||
### 4.1 当前表的职责分组
|
||||
|
||||
```text
|
||||
身份
|
||||
├── users
|
||||
├── sessions
|
||||
└── roles
|
||||
|
||||
租户
|
||||
├── tenants
|
||||
├── tenant_members
|
||||
└── tenant_quota_reservations
|
||||
|
||||
资源权限
|
||||
├── acls
|
||||
├── resource_access_requests
|
||||
├── approval_templates
|
||||
├── approval_instances
|
||||
└── approval_steps
|
||||
|
||||
业务资源
|
||||
├── datasets / dataset_files / dataset_file_versions / dataset_records
|
||||
├── models / trained_models / model_lineage / model_artifacts
|
||||
├── fine_tune_tasks / eval_tasks / compare_tasks
|
||||
├── data_process_tasks / data_convert_tasks
|
||||
└── projects / project_members(历史兼容)
|
||||
|
||||
运行资源
|
||||
├── compute_nodes
|
||||
├── gpus
|
||||
├── gpu_assignments
|
||||
├── gpu_allocations
|
||||
├── gpu_reservations
|
||||
└── resource_replicas / storage_objects / storage_cache_jobs
|
||||
|
||||
审计
|
||||
└── audit_logs
|
||||
```
|
||||
|
||||
### 4.2 数据库设计中的主要问题
|
||||
|
||||
#### 问题 A:租户归属字段可空且没有统一外键
|
||||
|
||||
`models`、`trained_models`、`datasets`、`eval_tasks`、`compare_tasks`、数据处理相关表的 `tenant_id` 演进过程不同,部分字段仍允许空值。多数资源表也没有对 `tenants(id)` 的外键约束。
|
||||
|
||||
后果:
|
||||
|
||||
- 资源可能被创建但没有租户归属。
|
||||
- 列表接口和详情接口的可见性不同。
|
||||
- ACL 授权是否跨租户无法仅靠数据库判断。
|
||||
- 历史数据需要特殊分支,增加权限代码复杂度。
|
||||
|
||||
#### 问题 B:所有者字段不统一
|
||||
|
||||
当前同时存在 `created_by`、`owner_id`、`create_by` 和 `payload.created_by`。这会导致:
|
||||
|
||||
- 列表判断资源所有者时需要按资源类型写特殊逻辑。
|
||||
- 用户删除时无法保证所有资源都能被一致地软删除。
|
||||
- 审计目标和资源所有者可能不是同一个字段。
|
||||
|
||||
#### 问题 C:角色权限没有单一来源
|
||||
|
||||
当前存在以下可能来源:
|
||||
|
||||
```text
|
||||
users.role
|
||||
users.permissions(JSON)
|
||||
tenant_members.role
|
||||
roles.permissions(JSON)
|
||||
前端 PermissionCode
|
||||
后端 ALL_PERMISSIONS / MODULE_PERMISSIONS
|
||||
```
|
||||
|
||||
如果更新了角色但没有同步用户权限 JSON,页面和接口可能出现不同结果;如果只修改前端权限码,后端仍可能拒绝;如果只修改 `tenant_members.role`,并不会自动改变平台页面权限。
|
||||
|
||||
#### 问题 D:资源 ACL 不是所有资源的唯一授权来源
|
||||
|
||||
基座模型在当前设计中对租户用户默认共享 read/execute;资源所有者又有隐式权限;租户管理员又有管理旁路;ACL 只是其中一层。这个设计可以成立,但必须在文档和代码中严格区分:
|
||||
|
||||
```text
|
||||
平台共享规则 ≠ ACL 授权
|
||||
资源所有权 ≠ 租户管理员权限
|
||||
页面权限 ≠ 资源动作权限
|
||||
GPU 分配 ≠ 资源 ACL
|
||||
```
|
||||
|
||||
#### 问题 E:项目字段与当前产品边界不一致
|
||||
|
||||
`projects`、`project_members`、`project_id` 仍在数据库中存在,但当前产品已经决定不把项目作为用户可见的隔离层。它们应被标记为 legacy,不应再参与新资源的权限判定,也不应在新建页面继续要求填写。
|
||||
|
||||
## 五、目标唯一口径
|
||||
|
||||
### 5.1 用户与租户的最终关系
|
||||
|
||||
```text
|
||||
一个用户可以属于多个租户
|
||||
一个租户可以拥有多个用户
|
||||
用户在一次请求中只能选择一个 active_tenant
|
||||
资源必须归属于 active_tenant
|
||||
```
|
||||
|
||||
推荐保留:
|
||||
|
||||
- `users.tenant_id`:暂时保留为兼容字段,表示用户的 primary tenant,不再作为多租户关系的唯一来源。
|
||||
- `tenant_members`:升级为租户成员关系的唯一权威来源。
|
||||
- `X-Tenant-ID`:明确表达当前请求租户,必须来自 active membership。
|
||||
|
||||
最终判定:
|
||||
|
||||
```text
|
||||
有效租户 = tenant_members(status=active, 未过期)
|
||||
primary tenant = users.tenant_id(仅兼容和默认登录上下文)
|
||||
当前租户 = 请求 X-Tenant-ID,否则 primary tenant
|
||||
```
|
||||
|
||||
### 5.2 平台角色与租户角色
|
||||
|
||||
推荐收敛为两层:
|
||||
|
||||
| 层级 | 字段/表 | 允许的角色 | 作用 |
|
||||
|---|---|---|---|
|
||||
| 平台层 | `users.platform_role`,兼容当前 `users.role` | `platform_admin`、`platform_user` | 管理租户、平台配置、平台用户和全局策略 |
|
||||
| 租户层 | `tenant_members.role` | `owner`、`admin`、`member`、`viewer` | 管理本租户成员、资源和租户级审批 |
|
||||
|
||||
不建议继续把 `operator`、`user`、`member` 混在一个角色字段中。过渡期可以保留旧值,但新增代码只允许通过映射函数转换:
|
||||
|
||||
```text
|
||||
admin/protected -> platform_admin
|
||||
operator/user -> platform_user + tenant_members.member
|
||||
viewer -> platform_user + tenant_members.viewer
|
||||
```
|
||||
|
||||
### 5.3 页面权限与资源动作
|
||||
|
||||
页面权限只解决“能否进入模块”:
|
||||
|
||||
```text
|
||||
module permission: dataset / fine-tune / model-inference / ...
|
||||
```
|
||||
|
||||
资源动作解决“能否操作某个资源”:
|
||||
|
||||
```text
|
||||
read / write / execute / download / delete / admin
|
||||
```
|
||||
|
||||
统一授权函数输入应固定为:
|
||||
|
||||
```text
|
||||
authorize(
|
||||
actor_id,
|
||||
active_tenant_id,
|
||||
resource_type,
|
||||
resource_id,
|
||||
action,
|
||||
)
|
||||
```
|
||||
|
||||
推荐判定顺序:
|
||||
|
||||
1. 会话有效且用户 active。
|
||||
2. 当前租户 active,用户是该租户成员。
|
||||
3. 平台管理员旁路,或资源属于当前租户。
|
||||
4. 资源所有者拥有默认动作集合。
|
||||
5. 租户 owner/admin 按租户范围拥有管理动作。
|
||||
6. ACL 明确授予当前用户或租户角色对应动作。
|
||||
7. 对 download、delete、admin 等高风险动作执行额外审批检查。
|
||||
|
||||
### 5.4 资源标准字段
|
||||
|
||||
所有新资源应统一具备:
|
||||
|
||||
```text
|
||||
id
|
||||
tenant_id NOT NULL
|
||||
created_by NOT NULL
|
||||
created_at
|
||||
updated_at
|
||||
deleted_at
|
||||
deleted_by
|
||||
```
|
||||
|
||||
历史 `owner_id`、`create_by` 和 `payload.created_by` 只在迁移阶段读取,最终写入标准字段。任务配置 JSON 可以保留业务参数,但不再存放权限事实。
|
||||
|
||||
## 六、标准业务流程
|
||||
|
||||
### 6.1 创建租户流程
|
||||
|
||||
```text
|
||||
平台管理员
|
||||
│
|
||||
├─ 创建租户基本信息
|
||||
├─ 设置租户配额和状态=active
|
||||
├─ 指定或创建租户 owner
|
||||
├─ 写入 tenant_members(tenant_id, owner_user_id, owner)
|
||||
├─ 初始化审批策略
|
||||
└─ 记录 tenant.create / tenant.member.add 审计
|
||||
```
|
||||
|
||||
纠偏要求:`tenants.owner_user_id` 和 `tenant_members(role='owner')` 必须在同一事务中维护;不能只写一个。
|
||||
|
||||
### 6.2 创建用户与加入租户流程
|
||||
|
||||
#### 平台管理员创建用户
|
||||
|
||||
```text
|
||||
平台管理员
|
||||
│
|
||||
├─ 创建 users 记录
|
||||
├─ 选择初始平台角色:platform_user 或 platform_admin
|
||||
├─ 选择 primary tenant
|
||||
├─ 写入 tenant_members
|
||||
│ ├─ owner 仅平台管理员明确指定时允许
|
||||
│ └─ 普通用户默认 member 或 viewer
|
||||
├─ 生成页面权限快照(过渡期)
|
||||
└─ 记录 user.create / tenant.member.add 审计
|
||||
```
|
||||
|
||||
#### 已存在用户加入新租户
|
||||
|
||||
```text
|
||||
租户 owner/admin 或平台管理员
|
||||
│
|
||||
├─ 发出邀请或创建加入申请
|
||||
├─ tenant_members.status = pending
|
||||
├─ 被邀请用户接受
|
||||
├─ tenant_members.status = active
|
||||
└─ 用户选择 X-Tenant-ID 后访问该租户资源
|
||||
```
|
||||
|
||||
纠偏要求:不能把“创建登录用户”和“拥有某租户全部资源”理解为同一件事;新用户默认没有任何资源 ACL,也没有 GPU 分配。
|
||||
|
||||
### 6.3 创建业务资源流程
|
||||
|
||||
```text
|
||||
登录用户
|
||||
│
|
||||
├─ 会话校验
|
||||
├─ 确定 active_tenant
|
||||
├─ 校验租户 active 和用户成员状态
|
||||
├─ 写入资源 tenant_id + created_by
|
||||
├─ 写入资源业务表
|
||||
├─ 写入 MinIO 对象元数据(如有文件)
|
||||
├─ 生成资源血缘/版本快照
|
||||
└─ 记录资源创建审计
|
||||
```
|
||||
|
||||
数据处理结果生成数据集时,必须继承任务的租户和创建者;不能因为是系统生成就把 `tenant_id` 和 `created_by` 留空。
|
||||
|
||||
### 6.4 资源查看和授权流程
|
||||
|
||||
```text
|
||||
用户请求资源列表/详情
|
||||
│
|
||||
├─ 页面权限检查
|
||||
├─ active_tenant 检查
|
||||
├─ 资源 tenant_id 检查
|
||||
├─ 所有者 / 租户角色 / ACL 判定
|
||||
├─ 返回资源元数据
|
||||
└─ 文件、版本、MinIO 对象再次按同一资源动作校验
|
||||
```
|
||||
|
||||
资源授权:
|
||||
|
||||
```text
|
||||
资源所有者或租户管理员/平台管理员
|
||||
│
|
||||
├─ 选择用户或租户角色
|
||||
├─ 选择 read/write/execute/download 等动作
|
||||
├─ 设置有效期
|
||||
├─ 写入 ACL 或创建访问审批
|
||||
└─ 记录授权来源、授权人和审计
|
||||
```
|
||||
|
||||
### 6.5 训练、推理、评测使用资源流程
|
||||
|
||||
```text
|
||||
创建任务
|
||||
│
|
||||
├─ 页面权限:fine-tune / model-inference / model-eval
|
||||
├─ active_tenant 和任务资源归属校验
|
||||
├─ 基座模型:平台共享规则或 model.execute
|
||||
├─ 训练模型:trained_model.execute
|
||||
├─ 数据集:dataset.execute
|
||||
├─ GPU assignment:用户是否获批使用所选卡
|
||||
├─ 节点:GPU 所属节点是否 online/enabled
|
||||
├─ 原子预留 GPU 和租户配额
|
||||
├─ MinIO/节点缓存准备
|
||||
├─ 提交计算任务
|
||||
└─ 成功、失败、取消、超时、节点故障统一释放预留
|
||||
```
|
||||
|
||||
### 6.6 高风险操作审批流程
|
||||
|
||||
```text
|
||||
用户发起高风险操作
|
||||
│
|
||||
├─ 检查当前用户是否有基础资源权限
|
||||
├─ 检查是否为管理员旁路
|
||||
├─ 匹配 tenant + action + resource_type 审批策略
|
||||
├─ 创建 pending 审批实例
|
||||
├─ 审批人从当前会话确定
|
||||
├─ approved -> 幂等执行具体效果
|
||||
│ ├─ ACL 授权
|
||||
│ ├─ GPU 分配
|
||||
│ └─ 配额更新
|
||||
├─ rejected/cancelled/expired -> 不产生资源效果
|
||||
└─ 全流程记录审计
|
||||
```
|
||||
|
||||
## 七、纠偏开发计划
|
||||
|
||||
### 阶段 0:冻结口径
|
||||
|
||||
1. 书面确认:不再把项目作为新业务隔离层。
|
||||
2. 确认平台角色只有平台管理员和平台用户两类;租户职责由 `tenant_members.role` 表达。
|
||||
3. 确认 `tenant_members` 是租户关系权威表,`users.tenant_id` 仅作为 primary tenant 兼容字段。
|
||||
4. 确认所有资源必须有 `tenant_id`、`created_by`、生命周期字段。
|
||||
5. 确认基座模型共享不等于训练模型和数据集共享。
|
||||
|
||||
### 阶段 1:身份和租户纠偏
|
||||
|
||||
1. 为平台角色建立统一映射,停止新增 `role='user'` 的特殊逻辑。
|
||||
2. 用户创建、租户创建、成员邀请、成员接受、成员移除统一走成员服务。
|
||||
3. 创建租户时同步 owner 成员记录。
|
||||
4. 租户成员变更、用户禁用、用户软删除时统一撤销会话、GPU 分配、ACL、待审批流程。
|
||||
5. 新增当前租户查询和切换接口,前端显示“当前租户”,避免仅显示用户主租户。
|
||||
|
||||
### 阶段 2:资源数据纠偏
|
||||
|
||||
1. 对所有资源表补齐并回填 `tenant_id`、`created_by`、`created_at`、`updated_at`。
|
||||
2. 将任务 payload 中的创建者和租户迁移到结构化字段。
|
||||
3. 对历史 `tenant_id IS NULL` 数据按以下顺序处理:
|
||||
- 能从创建者找到租户的,回填创建者所属租户。
|
||||
- 系统生成数据集能从源任务找到租户的,继承源任务租户。
|
||||
- 仍无法确定归属的,进入待治理清单,不自动公开。
|
||||
- 管理员明确授权的历史资源可临时通过用户级 ACL 访问,直到完成归属迁移。
|
||||
4. 为资源和租户建立必要索引;在数据清洗完成后再逐步收紧 `NOT NULL` 和外键。
|
||||
|
||||
### 阶段 3:权限判定收敛
|
||||
|
||||
1. 建立统一 `authorize()` 服务,所有列表、详情、文件、版本、下载、MinIO、缓存和任务接口调用同一套判定。
|
||||
2. 页面权限只用于模块入口;资源动作必须在后端独立判断。
|
||||
3. 统一基座模型、训练模型、数据集和任务的血缘权限来源。
|
||||
4. 统一 GPU assignment、GPU reservation 和租户配额 reservation 的状态流转。
|
||||
5. 审批实例增加幂等键和过期处理任务,避免重复审批和重复执行。
|
||||
|
||||
### 阶段 4:数据库和初始化脚本
|
||||
|
||||
1. 将完整初始化 SQL 与迁移 SQL 的职责分开:新库只执行一份完整脚本,旧库执行版本化迁移。
|
||||
2. 初始化 SQL 中统一种子用户、种子角色、默认租户和租户成员关系,不能出现 operator 仍拥有普通用户不应有的 `compute` 权限而代码又剥离该权限的矛盾。
|
||||
3. 给所有需要的关联增加外键或由应用层统一保证引用完整性。
|
||||
4. 为 `tenant_id + status`、`created_by + deleted_at`、ACL 主体、审批状态和 GPU 状态建立索引。
|
||||
5. 主工程与 `docker/offline/src` 的完整 SQL、迁移、代码和部署文档做 SHA-256 一致性校验。
|
||||
|
||||
### 阶段 5:前端流程纠偏
|
||||
|
||||
1. 用户管理页面分别显示平台角色、所属租户、租户角色、页面权限和资源权限,不再把它们放在一个“权限”字段中。
|
||||
2. 租户详情页显示成员、租户角色、配额使用、审批策略和资源统计。
|
||||
3. 资源详情页显示资源所属租户、创建者、授权主体、动作、有效期和授权来源。
|
||||
4. 训练/推理/评测页面只显示当前用户有 `execute` 权限且已获批 GPU 的资源。
|
||||
5. 对“无权访问”“未授权”“审批中”“资源已删除”“租户已停用”分别展示原因,不统一显示为数据为空或 500。
|
||||
|
||||
## 八、建议的验收矩阵
|
||||
|
||||
| 场景 | 预期结果 |
|
||||
|---|---|
|
||||
| 用户未加入租户访问租户资源 | 403 |
|
||||
| 用户属于租户但没有资源 ACL | 资源列表不可见,详情 403 |
|
||||
| 用户获得 dataset.read | 数据集可见,可预览,但不能训练或上传 |
|
||||
| 用户获得 dataset.execute | 数据集可用于训练/评测,但不能编辑或下载 |
|
||||
| 用户获得 dataset.download | 可以下载文件,但不能训练 |
|
||||
| 用户获得 trained_model.execute | 可以推理/评测,不能导出 |
|
||||
| 用户获得 trained_model.download | 可以导出或下载,不能执行推理 |
|
||||
| 用户获批 GPU 但没有数据集 execute | 不能创建训练任务 |
|
||||
| 用户有数据集 execute 但没有 GPU assignment | 不能创建训练任务 |
|
||||
| 管理员撤销 ACL | 列表、详情、执行、下载均立即重新校验 |
|
||||
| 用户被禁用 | 会话失效,成员和 ACL 不能继续生效 |
|
||||
| 租户被停用 | 租户资源不可创建和执行,运行任务进入待处理/失败策略 |
|
||||
| 历史资源 tenant_id 为空且无 ACL | 普通用户不可见 |
|
||||
| 历史资源 tenant_id 为空且有管理员直接用户 ACL | 仅指定用户在有效期内可见和按动作使用 |
|
||||
| 资源删除 | 资源不可见,ACL、审批、对象清理流程被触发 |
|
||||
| MinIO 不可用 | 资源元数据权限仍可判断,涉及对象的操作返回明确存储故障 |
|
||||
|
||||
## 九、纠偏完成判定
|
||||
|
||||
满足以下条件,才认为租户与用户权限完成统一,而不是“接口能够调用”:
|
||||
|
||||
- `tenant_members` 成为租户关系唯一权威来源,`users.tenant_id` 只作为兼容主租户。
|
||||
- 平台角色和租户角色职责分离,角色权限不再通过多个 JSON/字段重复维护。
|
||||
- 新资源全部具备非空租户和创建者,历史资源有明确归属或进入治理清单。
|
||||
- 所有资源接口、文件接口、MinIO 接口和任务接口使用统一动作授权。
|
||||
- 数据集、基座模型、训练模型和任务之间的派生关系不会自动扩大访问范围。
|
||||
- 用户创建、成员邀请、资源授权、GPU 申请、配额申请和审批都能追溯到用户、租户、资源、动作和请求 ID。
|
||||
- 初始化 SQL、迁移 SQL、在线数据库和离线源码目录的表结构与权限逻辑一致。
|
||||
- 双用户、跨租户、ACL 撤销、权限过期、用户禁用、租户停用、GPU 冲突和 MinIO 故障场景全部通过验证。
|
||||
|
||||
## 十、2026-08-20 本轮改造结果
|
||||
|
||||
本轮已按目标层级模型完成一轮可运行的后端、数据库和前端收敛:
|
||||
|
||||
1. `users.platform_role` 已作为平台角色标准字段,值为 `platform_admin` 或 `platform_user`;历史 `users.role` 继续返回,供旧客户端兼容。
|
||||
2. `tenant_members` 已作为租户成员关系的权威来源。创建租户时会在同一事务中写入 `owner` 成员;创建用户时单独使用 `tenant_role` 写入成员角色,不再因为平台角色是管理员就自动成为租户 owner。
|
||||
3. 用户接口返回 `platform_role`、`tenant_memberships` 和 `tenant_count`,组织页面已区分平台身份与租户成员关系。
|
||||
4. `fine_tune_tasks` 已增加结构化 `tenant_id`、`created_by`、`deleted_at`、`deleted_by`;训练列表、详情和 owner 判定优先使用结构化字段,历史 payload 仅作回退。
|
||||
5. 新建数据集、训练、评测、推理任务会绑定当前认证租户;普通用户不能仅通过请求体伪造其他租户。平台管理员仍可为指定租户创建资源。
|
||||
6. 普通用户的资源列表继续通过租户成员、所有者和 ACL 统一过滤;项目不再出现在前端路由、组织页面和新权限判断中。
|
||||
7. 租户删除已补充 `deleted_at/deleted_by` 软删除,并同步禁用该租户的成员关系。
|
||||
8. `000_full_init.sql` 已包含本轮标准字段、索引、owner 成员修复和无项目业务依赖的种子数据;`docker/offline/src/backend/app/db/sql` 仅保留这一份完整初始化脚本。
|
||||
9. `docker/offline/src` 已同步当前 backend、frontend、compute 源码和构建后的 `frontend-dist`。
|
||||
|
||||
本轮已在线验证:数据库字段存在、普通用户身份返回、用户租户成员关系返回、租户 owner 自动建立、租户软删除、跨租户伪造创建被 403 拒绝;前端 `npm run build` 通过。项目表、项目字段及旧项目 API 仅保留历史兼容读取,不再作为新业务隔离条件。
|
||||
|
||||
## 十一、下一步开发计划
|
||||
|
||||
1. 为资源详情和资源授权页面补充租户、创建者、授权来源、有效期和动作权限的可视化信息。
|
||||
2. 将数据处理、数据转换等派生资源的租户和创建者继承改为统一服务,并清理历史 `tenant_id IS NULL` 待治理清单。
|
||||
3. 将 GPU assignment、GPU reservation、租户配额 reservation 和审批实例整理为同一状态机,补充节点故障回收验收。
|
||||
4. 执行双租户、双用户、ACL 过期/撤销、用户禁用、租户停用、MinIO 故障和多 GPU 冲突的完整回归测试。
|
||||
Reference in New Issue
Block a user