# ProteinPredict 数据库设计说明

## 1. 数据库概览

数据库名称：`proteinpredict`

字符集建议：`utf8mb4`

主要业务表：

- `auth_user`：Django 内置用户表，保存普通用户和管理员。
- `ai_service_predictiontask`：蛋白结构预测任务。
- `ai_service_sampleprotein`：内置测试蛋白样例。
- `ai_service_taskevent`：任务生命周期事件。
- `ai_service_aianalysis`：AI 解析记录。

系统采用 Django ORM 管理表结构，迁移文件位于：

```text
ai_service/migrations/
authentication/migrations/
```

## 2. 实体关系

```mermaid
erDiagram
    AUTH_USER ||--o{ PREDICTION_TASK : submits
    AUTH_USER ||--o{ TASK_EVENT : writes
    AUTH_USER ||--o{ AI_ANALYSIS : requests
    PREDICTION_TASK ||--o{ TASK_EVENT : has
    PREDICTION_TASK ||--o{ AI_ANALYSIS : explains
    SAMPLE_PROTEIN }o--o{ PREDICTION_TASK : "selected manually"

    AUTH_USER {
        bigint id PK
        varchar username
        varchar password
        bool is_superuser
        bool is_staff
        bool is_active
        datetime last_login
        datetime date_joined
    }

    PREDICTION_TASK {
        bigint id PK
        bigint user_id FK
        varchar sequence_name
        text sequence_data
        varchar status
        varchar requested_runtime_mode
        varchar runtime_mode
        varchar pdb_file
        varchar plddt_plot
        double avg_plddt
        json plddt_scores
        text error_message
        int worker_pid
        varchar gpu_id
        varchar device_info
        datetime created_at
        datetime started_at
        datetime completed_at
    }

    SAMPLE_PROTEIN {
        bigint id PK
        varchar name
        varchar accession
        varchar source_database
        varchar fasta_header
        text sequence
        varchar reference_pdb_id
        varchar reference_pdb_url
        varchar local_pdb_file
        text description
        json tags
        bool is_active
        datetime created_at
    }

    TASK_EVENT {
        bigint id PK
        bigint task_id FK
        bigint user_id FK
        varchar event_type
        varchar message
        json metadata
        datetime created_at
    }

    AI_ANALYSIS {
        bigint id PK
        bigint user_id FK
        bigint task_id FK
        varchar analysis_type
        text prompt
        varchar model
        text result_text
        varchar status
        json usage_json
        int elapsed_ms
        text error_message
        datetime created_at
        datetime updated_at
    }
```

## 3. 表结构说明

### 3.1 `auth_user`

Django 内置用户表，不重复造用户体系，降低认证和密码安全风险。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint | 主键 |
| `username` | varchar | 登录用户名，唯一 |
| `password` | varchar | Django 哈希密码 |
| `is_superuser` | bool | 是否管理员 |
| `is_staff` | bool | 是否可进入 Django Admin |
| `is_active` | bool | 是否启用 |
| `last_login` | datetime | 最近登录时间 |
| `date_joined` | datetime | 创建时间 |

权限约定：

- 普通用户：`is_superuser = false`。
- 管理员：`is_superuser = true` 且 `is_staff = true`。

### 3.2 `ai_service_predictiontask`

保存每一次蛋白结构预测任务。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint | 主键 |
| `user_id` | bigint | 提交用户 |
| `sequence_name` | varchar(100) | 任务名称 |
| `sequence_data` | text | 清洗后的标准 20 种氨基酸序列 |
| `status` | varchar(20) | `PENDING`、`PROCESSING`、`SUCCESS`、`FAILED` |
| `pdb_file` | file path | 预测 PDB 文件 |
| `plddt_plot` | image path | pLDDT 分布图 |
| `avg_plddt` | double | 平均 pLDDT |
| `plddt_scores` | json | 残基级 pLDDT 数组 |
| `requested_runtime_mode` | varchar(20) | 用户提交时选择的模式，默认 `real` |
| `runtime_mode` | varchar(20) | Worker 实际执行模式，`real` 或 `demo` |
| `error_message` | text | 失败原因或终止原因 |
| `worker_pid` | int | 处理任务的 Worker 进程 ID |
| `gpu_id` | varchar(32) | 使用设备，如 `cpu`、`cuda:0` |
| `device_info` | varchar(120) | 模型实际运行设备或演示回落原因 |
| `created_at` | datetime | 任务创建时间 |
| `updated_at` | datetime | 最近更新时间 |
| `started_at` | datetime | Worker 开始时间 |
| `completed_at` | datetime | 完成或失败时间 |

索引：

- `(user_id, created_at)`：加速个人历史查询。
- `(status, created_at)`：加速任务队列和管理员监控。

### 3.3 `ai_service_sampleprotein`

保存系统内置或管理员新增的测试蛋白。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint | 主键 |
| `name` | varchar(120) | 样例名称 |
| `accession` | varchar(60) | UniProt 或数据库编号 |
| `source_database` | varchar(60) | 数据来源 |
| `fasta_header` | varchar(200) | FASTA 标题 |
| `sequence` | text | 标准氨基酸序列 |
| `reference_pdb_id` | varchar(20) | 参考 PDB 编号 |
| `reference_pdb_url` | url | 参考结构链接 |
| `local_pdb_file` | file path | 本地参考 PDB，可选 |
| `description` | text | 用途说明 |
| `tags` | json | 标签，如 `demo`、`50-100aa` |
| `is_active` | bool | 是否在前端展示 |
| `created_at` | datetime | 创建时间 |

用途：

- 为答辩、演示和自动化截图提供稳定输入。
- 避免用户一开始就粘贴过长序列导致本机卡顿。

### 3.4 `ai_service_taskevent`

记录任务生命周期，便于管理员审计和结果页展示。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint | 主键 |
| `task_id` | bigint | 关联任务 |
| `user_id` | bigint | 触发用户，可为空 |
| `event_type` | varchar(40) | 事件类型 |
| `message` | varchar(255) | 可读事件说明 |
| `metadata` | json | 设备、长度、错误、pLDDT 等补充信息 |
| `created_at` | datetime | 事件时间 |

事件类型：

```text
submitted     用户提交
started       Worker 开始
completed     预测完成
failed        预测失败
terminated    管理员终止
downloaded    下载结果
viewed        查看结果
ai_analysis   AI 解析
```

### 3.5 `ai_service_aianalysis`

保存火山方舟 AI 解析记录。

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | bigint | 主键 |
| `user_id` | bigint | 发起用户 |
| `task_id` | bigint | 关联任务，全局助手可为空 |
| `analysis_type` | varchar(20) | `task` 或 `chat` |
| `prompt` | text | 后端组装后的提示词 |
| `model` | varchar(120) | 火山方舟接入点 |
| `result_text` | text | 完成后的完整结果 |
| `status` | varchar(20) | `pending`、`streaming`、`success`、`failed` |
| `usage_json` | json | token 用量等返回信息 |
| `elapsed_ms` | int | 耗时毫秒 |
| `error_message` | text | 失败原因 |
| `created_at` | datetime | 创建时间 |
| `updated_at` | datetime | 更新时间 |

API Key 不入库，不写入前端，只从服务端环境变量 `ARK_API_KEY` 读取。

## 4. 数据权限设计

| 功能 | 普通用户 | 管理员 |
| --- | --- | --- |
| 注册/登录/注销 | 支持 | 支持 |
| 提交预测任务 | 支持 | 支持 |
| 查看任务历史 | 只能查看个人任务 | 可查看全部任务 |
| 查看任务详情和下载 | 只能访问个人任务 | 可访问全部任务 |
| 查看任务事件 | 只能查看个人任务 | 可查看全部任务 |
| AI 解析 | 只能解析个人任务 | 可解析全部任务 |
| 样例数据查看 | 支持 | 支持 |
| 新增样例数据 | 不支持 | 支持 |
| 用户管理 | 不支持 | 支持 |
| 任务终止 | 不支持 | 支持 |
| 系统负载监控 | 不支持 | 支持 |

## 5. 初始化数据

执行：

```powershell
python manage.py seed_demo_data
```

会创建：

- 管理员：`admin / 123456`
- 普通用户：`researcher / 123456`
- 多条短序列样例蛋白
- 一条可用于立即查看结果页的演示预测任务

样例数据均用于系统测试、教学演示和截图，不代表真实科研结论。

## 6. 文件存储设计

预测结果不直接写入数据库大字段，而是存储在 `media/`：

```text
media/
├─ pdb_results/       # 预测 PDB
├─ plots/             # pLDDT 分布图
├─ downloads/         # 临时 ZIP
└─ sample_pdb/        # 样例参考 PDB，可选
```

数据库只保存文件路径，接口返回可访问 URL，便于前端 3Dmol.js 加载和下载。

## 7. 性能设计

1. Worker 启动时加载模型一次，避免每个任务重复加载 ESMFold。
2. 任务队列通过数据库状态流转，不阻塞 HTTP 请求。
3. 个人历史和管理员队列使用分页查询。
4. `plddt_scores` 使用 JSON 数组，详情页一次返回，列表页默认不携带完整数组。
5. 前端只在当前页面轮询，离开页面后清理 3Dmol viewer 和图表实例。
6. 演示模式生成轻量 PDB，保证无 GPU 环境也能完整演示。
