nex_docus/docs/database.md

416 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 数据库设计
> 权威来源是 `backend/app/models/`:本文是它的可读镜像,两者冲突时**以模型为准并回改本文**。
> 结构变更流程见 [quickstart.md §9](quickstart.md#9-数据库结构与迁移)。
- 引擎:MySQL 8.0 / InnoDB / `utf8mb4` / `utf8mb4_unicode_ci`
- 表数量:**18**
- 时间列:`created_at` / `updated_at` 由各模型的 `default=now` / `onupdate=now` 维护(DATETIME,无时区,容器时区固定 `Asia/Shanghai`)
- 主键:除 `llm_model_config.config_id` 外,其余表主键均为自增 `id`
- ⚠️ **文档正文不在数据库里**:Markdown 正文存在文件系统(`STORAGE_ROOT/projects/<storage_key>/…`),数据库只存权限、元数据与索引(见 [sdd ADR-0001](sdd/architecture/decisions/ADR-0001-hybrid-storage.md)、[ADR-0002](sdd/architecture/decisions/ADR-0002-uuid-storage-key.md))
## 表清单
| 分组 | 表 | 用途 | 主要写入方 |
| --- | --- | --- | --- |
| 身份权限 | `users` | 账号、状态、超管标记、登录痕迹 | 注册、用户管理、登录 |
| 身份权限 | `roles` | 角色(super_admin / admin / user + 自定义) | 角色管理、`init_db.py` 种子 |
| 身份权限 | `user_roles` | 用户 ↔ 角色 | 用户管理 |
| 身份权限 | `system_menus` | 菜单 **与** 按钮级权限点(`menu_type` 区分) | `init_db.py` 种子、权限管理 |
| 身份权限 | `role_menus` | 角色 ↔ 菜单/权限点 | 权限管理 |
| 项目文档 | `projects` | 项目主表,`storage_key` 是磁盘目录名 | 项目管理 |
| 项目文档 | `project_members` | 项目成员与项目内角色 | 成员管理 |
| 项目文档 | `document_meta` | 文档标题/标签/字数/浏览与编辑痕迹(可选表,正文仍在文件) | 保存文件、浏览统计 |
| 项目文档 | `project_git_repos` | 项目绑定的 Git 仓库(含令牌) | Git 同步设置 |
| 项目文档 | `share_links` | 项目/文件分享码与访问密码 | 分享管理 |
| AI 知识库 | `llm_model_config` | Chat / Embedding 模型配置 | 模型配置 |
| AI 知识库 | `chat_session` | 对话会话(按项目 + 用户 + 模型) | 对话 |
| AI 知识库 | `chat_message` | 消息、状态、耗时、思考过程、引用文件 | 对话 |
| AI 知识库 | `document_vector` | 文档分块 → 向量库映射(ZVec) | 向量化 |
| AI 知识库 | `project_vectorization_task` | 全量/增量向量化任务与进度 | 向量化 |
| 通知审计 | `notifications` | 站内通知 | 通知服务 |
| 通知审计 | `operation_logs` | 操作审计(谁、何时、对什么、结果) | `log_service`(各 API 埋点) |
| 通知审计 | `mcp_bots` | MCP Bot 的 `bot_id/secret` 凭证 | MCP 凭证管理 |
## 关系(逻辑外键)
数据库只在 `notifications.user_id` 与 `project_git_repos.project_id` 上声明了真正的 FOREIGN KEY,其余是**逻辑外键**(不建约束,便于分库与批量清理):
```
users 1─N user_roles N─1 roles 1─N role_menus N─1 system_menus
users 1─N projects(owner_id) 1─N project_members N─1 users
projects 1─N document_meta / share_links / project_git_repos
/ document_vector / project_vectorization_task / chat_session
chat_session 1─N chat_message
projects 1─N chat_session(同时 chat_session.user_id → users)
```
删除项目时由服务层负责级联清理文件目录与相关索引行;不要指望数据库级联。
## 初始化与迁移
| 阶段 | 代码 | 行为 |
| --- | --- | --- |
| 建表 | `backend/scripts/init_db.py` → `Base.metadata.create_all` | 只创建缺失表;表结构来自 `app/models/`。**模型必须在 `app/models/__init__.py` 中注册**,否则该表不会出现在新库里 |
| 种子 | 同上 | 角色(super_admin/admin/user)、系统菜单与权限点、管理员账号;按 id 与 `(parent_id, menu_name)` 去重,幂等增量 |
| 补列 | `app/core/migrations.py::migrate_schema()` | 幂等 `ALTER TABLE ADD COLUMN`(先查 `information_schema`)。当前覆盖:`chat_message.status/duration_ms/thinking_log`、`project_git_repos.sync_path` |
| 未使用 | Alembic | 依赖里有 `alembic`,但项目未启用版本化迁移脚本 |
Docker 部署时后端容器启动命令是 `python scripts/init_db.py && uvicorn main:app …`,因此**新环境无需手工执行 SQL**。
## 已知数据差异与运维建议
1. **`project_members.role` 大小写混杂**:历史数据(早期 `init_database.sql` 建的库)多为 `ADMIN/EDITOR/VIEWER`,新写入是 `admin/editor/viewer`。读取路径统一经过 `app/services/project_service.normalize_project_role()` 归一化,因此行为正确;如需彻底清洗,可执行:
```sql
UPDATE project_members SET role = LOWER(role) WHERE BINARY role <> LOWER(role);
```
2. **`share_links.access_pass` / `project_git_repos.token` 为明文存储**:属已知技术债(见发布报告 P2)。上线前应限制库账号的远程访问并纳入备份加密范围。
3. **`document_vector` 无数据库唯一约束**:靠 `idx_project_file_chunk(project_id, file_path, chunk_index)` 普通索引查询,重复向量化由服务层用 `content_hash` 判定,不在库里去重。
4. **`llm_model_config.api_key` 明文**:同上,接口返回时会脱敏,但库里是原文。
5. **备份**:文件系统(`STORAGE_PATH`)与数据库必须一起备份,缺一个都无法还原,命令见 [deploy/README.md](deploy/README.md)。
```sql
-- 常用排查
SELECT id, name, storage_key, owner_id, is_public FROM projects WHERE id = ?; -- storage_key 即磁盘目录名
SELECT status, COUNT(*) FROM document_vector WHERE project_id = ? GROUP BY status;
SELECT task_id, task_type, status, total, processed, failed FROM project_vectorization_task
WHERE project_id = ? ORDER BY created_at DESC LIMIT 5;
SELECT role, COUNT(*) FROM project_members WHERE project_id = ? GROUP BY role;
```
---
## 身份与权限
### `users` — 用户
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 用户ID |
| `username` | VARCHAR(50) | UNIQUE · NOT NULL | 用户名 |
| `password_hash` | VARCHAR(255) | NOT NULL | 密码哈希 |
| `nickname` | VARCHAR(50) | — | 昵称 |
| `email` | VARCHAR(100) | — | 邮箱 |
| `phone` | VARCHAR(20) | — | 手机号 |
| `avatar` | VARCHAR(255) | — | 头像URL |
| `status` | SMALLINT | 默认 `1` | 状态:0-禁用 1-启用 |
| `is_superuser` | SMALLINT | 默认 `0` | 是否超级管理员:0-否 1-是 |
| `last_login_at` | DATETIME | — | 最后登录时间 |
| `last_login_ip` | VARCHAR(50) | — | 最后登录IP |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_users_email`(email);`ix_users_status`(status);`ix_users_username`(username) UNIQUE
### `roles` — 角色
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 角色ID |
| `role_name` | VARCHAR(50) | UNIQUE · NOT NULL | 角色名称 |
| `role_code` | VARCHAR(50) | UNIQUE · NOT NULL | 角色编码 |
| `description` | VARCHAR(255) | — | 角色描述 |
| `status` | SMALLINT | 默认 `1` | 状态:0-禁用 1-启用 |
| `is_system` | SMALLINT | 默认 `0` | 是否系统角色:0-否 1-是 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_roles_role_code`(role_code) UNIQUE;`ix_roles_status`(status)
### `user_roles` — 用户-角色关联
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 关联ID |
| `user_id` | BIGINT | NOT NULL | 用户ID |
| `role_id` | BIGINT | NOT NULL | 角色ID |
| `created_at` | DATETIME | — | 创建时间 |
索引:`ix_user_roles_role_id`(role_id);`ix_user_roles_user_id`(user_id)
### `system_menus` — 系统菜单/权限点
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 菜单ID |
| `parent_id` | BIGINT | 默认 `0` | 父菜单ID(0表示根菜单) |
| `menu_name` | VARCHAR(50) | NOT NULL | 菜单名称 |
| `menu_code` | VARCHAR(50) | UNIQUE · NOT NULL | 菜单编码 |
| `menu_type` | SMALLINT | NOT NULL | 菜单类型:1-目录 2-菜单 3-按钮/权限点 |
| `path` | VARCHAR(255) | — | 路由路径 |
| `component` | VARCHAR(255) | — | 组件路径 |
| `icon` | VARCHAR(100) | — | 图标 |
| `sort_order` | INTEGER | 默认 `0` | 排序号 |
| `visible` | SMALLINT | 默认 `1` | 是否可见:0-隐藏 1-显示 |
| `status` | SMALLINT | 默认 `1` | 状态:0-禁用 1-启用 |
| `permission` | VARCHAR(100) | — | 权限字符串 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_system_menus_menu_code`(menu_code) UNIQUE;`ix_system_menus_status`(status)
### `role_menus` — 角色-菜单授权
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 关联ID |
| `role_id` | BIGINT | NOT NULL | 角色ID |
| `menu_id` | BIGINT | NOT NULL | 菜单ID |
| `created_at` | DATETIME | — | 创建时间 |
索引:`ix_role_menus_menu_id`(menu_id);`ix_role_menus_role_id`(role_id)
## 项目与文档
### `projects` — 项目
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 项目ID |
| `name` | VARCHAR(100) | NOT NULL | 项目名称 |
| `description` | VARCHAR(500) | — | 项目描述 |
| `storage_key` | VARCHAR(36) | UNIQUE · NOT NULL | 磁盘存储UUID |
| `owner_id` | BIGINT | NOT NULL | 项目所有者ID |
| `is_public` | SMALLINT | 默认 `0` | 是否公开:0-私有 1-公开 |
| `is_template` | SMALLINT | 默认 `0` | 是否模板项目:0-否 1-是 |
| `status` | SMALLINT | 默认 `1` | 状态:0-归档 1-活跃 |
| `cover_image` | VARCHAR(255) | — | 封面图 |
| `sort_order` | INTEGER | 默认 `0` | 排序号 |
| `visit_count` | INTEGER | 默认 `0` | 访问次数 |
| `access_pass` | VARCHAR(100) | — | 访问密码(用于分享链接) |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_projects_created_at`(created_at);`ix_projects_name`(name);`ix_projects_owner_id`(owner_id);`ix_projects_status`(status)
### `project_members` — 项目成员
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 成员ID |
| `project_id` | BIGINT | NOT NULL | 项目ID |
| `user_id` | BIGINT | NOT NULL | 用户ID |
| `role` | VARCHAR(20) | 默认 `viewer` | 项目角色: admin/editor/viewer |
| `invited_by` | BIGINT | — | 邀请人ID |
| `joined_at` | DATETIME | — | 加入时间 |
索引:`ix_project_members_project_id`(project_id);`ix_project_members_role`(role);`ix_project_members_user_id`(user_id)
### `document_meta` — 文档元数据
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 元数据ID |
| `project_id` | BIGINT | NOT NULL | 项目ID |
| `file_path` | VARCHAR(500) | NOT NULL | 文件相对路径 |
| `title` | VARCHAR(200) | — | 文档标题 |
| `tags` | VARCHAR(500) | — | 标签(JSON数组) |
| `author_id` | BIGINT | — | 作者ID |
| `word_count` | INTEGER | 默认 `0` | 字数统计 |
| `view_count` | INTEGER | 默认 `0` | 浏览次数 |
| `last_editor_id` | BIGINT | — | 最后编辑者ID |
| `last_edited_at` | DATETIME | — | 最后编辑时间 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_document_meta_author_id`(author_id);`ix_document_meta_project_id`(project_id)
### `project_git_repos` — 项目绑定的 Git 仓库
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | ID |
| `project_id` | BIGINT | FK → projects.id · NOT NULL | 项目ID |
| `name` | VARCHAR(50) | NOT NULL | 仓库别名 |
| `repo_url` | VARCHAR(255) | NOT NULL | Git仓库地址 |
| `branch` | VARCHAR(50) | 默认 `main` | Git分支 |
| `username` | VARCHAR(100) | — | Git用户名 |
| `token` | VARCHAR(255) | — | Git访问令牌/密码 |
| `is_default` | SMALLINT | 默认 `0` | 是否默认仓库 |
| `sync_path` | VARCHAR(255) | — | 同步目录(空=整个仓库) |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_project_git_repos_project_id`(project_id)
### `share_links` — 分享链接
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 分享ID |
| `project_id` | BIGINT | NOT NULL | 项目ID |
| `share_type` | VARCHAR(20) | NOT NULL | 分享类型: project/file |
| `share_code` | VARCHAR(64) | UNIQUE · NOT NULL | 公开分享码 |
| `file_path` | VARCHAR(500) | — | 文件路径,仅文件分享使用 |
| `access_pass` | VARCHAR(100) | — | 访问密码 |
| `created_by` | BIGINT | — | 创建人ID |
| `status` | SMALLINT | 默认 `1` | 状态:0-禁用 1-启用 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_share_links_created_by`(created_by);`ix_share_links_project_id`(project_id);`ix_share_links_share_code`(share_code) UNIQUE;`ix_share_links_share_type`(share_type);`ix_share_links_status`(status)
## AI 知识库
### `llm_model_config` — LLM 模型配置
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `config_id` | BIGINT | PK | 配置ID |
| `model_code` | VARCHAR(128) | UNIQUE · NOT NULL | 模型编码 |
| `model_name` | VARCHAR(255) | NOT NULL | 模型名称 |
| `model_type` | VARCHAR(32) | NOT NULL · 默认 `chat` | 模型类型: chat/embedding |
| `provider` | VARCHAR(64) | — | 模型提供方 |
| `endpoint_url` | VARCHAR(512) | — | 接口地址 |
| `api_key` | VARCHAR(512) | — | API Key |
| `llm_model_name` | VARCHAR(128) | NOT NULL | 模型名称/部署名 |
| `llm_timeout` | INTEGER | NOT NULL · 默认 `120` | 超时时间(秒) |
| `type_config` | JSON | NOT NULL · 默认 `服务端函数` | 模型类型差异参数 |
| `description` | VARCHAR(500) | — | 描述 |
| `is_active` | BOOLEAN | NOT NULL · 默认 `True` | 是否启用 |
| `is_default` | BOOLEAN | NOT NULL · 默认 `False` | 是否默认 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_llm_model_config_is_active`(is_active);`ix_llm_model_config_model_code`(model_code) UNIQUE;`ix_llm_model_config_model_type`(model_type)
### `chat_session` — 对话会话
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 会话ID |
| `project_id` | BIGINT | NOT NULL | 项目ID |
| `user_id` | BIGINT | NOT NULL | 用户ID |
| `llm_config_id` | BIGINT | NOT NULL | LLM配置ID |
| `title` | VARCHAR(255) | NOT NULL | 会话标题 |
| `description` | TEXT | — | 会话描述 |
| `is_active` | BOOLEAN | NOT NULL · 默认 `True` | 是否激活 |
| `message_count` | INTEGER | NOT NULL · 默认 `0` | 消息数 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`ix_chat_session_project_id`(project_id);`ix_chat_session_user_id`(user_id)
### `chat_message` — 对话消息
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 消息ID |
| `session_id` | BIGINT | NOT NULL | 会话ID |
| `role` | VARCHAR(32) | NOT NULL | 角色(user/assistant) |
| `content` | TEXT | NOT NULL | 消息内容 |
| `status` | VARCHAR(32) | NOT NULL · 默认 `pending` | 消息状态: pending/completed/interrupted/error |
| `duration_ms` | INTEGER | — | 生成耗时(毫秒) |
| `thinking_log` | TEXT | — | 思考过程(JSON数组) |
| `referenced_files` | TEXT | — | 参考文件(JSON数组) |
| `tokens_used` | INTEGER | — | 消耗的token数 |
| `is_deleted` | BOOLEAN | NOT NULL · 默认 `False` | 是否已删除 |
| `created_at` | DATETIME | — | 创建时间 |
索引:`ix_chat_message_session_id`(session_id)
### `document_vector` — 文档向量分块
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 向量ID |
| `project_id` | BIGINT | NOT NULL | 项目ID |
| `file_path` | VARCHAR(500) | NOT NULL | 文件相对路径 |
| `chunk_index` | INTEGER | NOT NULL · 默认 `0` | 分块序号(0起),同一文件可有多个分块 |
| `chunk_text` | TEXT | — | 分块首段文本,作为点击引用时的定位锚点 |
| `content_hash` | VARCHAR(64) | — | 整个文件内容哈希值,用于判断文件是否变更 |
| `zvec_id` | VARCHAR(256) | — | ZVec返回的向量ID(每个分块独立) |
| `zvec_response` | TEXT | — | ZVec完整响应JSON |
| `status` | VARCHAR(32) | NOT NULL · 默认 `success` | 向量化状态:success/failed/pending |
| `error_message` | VARCHAR(500) | — | 错误信息 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`idx_project_file_chunk`(project_id, file_path, chunk_index);`idx_project_file`(project_id, file_path);`ix_document_vector_project_id`(project_id)
### `project_vectorization_task` — 项目向量化任务
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 任务ID |
| `task_id` | VARCHAR(64) | UNIQUE · NOT NULL | 任务唯一标识 |
| `project_id` | BIGINT | NOT NULL | 项目ID |
| `user_id` | BIGINT | NOT NULL | 触发用户ID |
| `task_type` | VARCHAR(32) | NOT NULL | 任务类型:incremental/full |
| `status` | VARCHAR(32) | NOT NULL · 默认 `pending` | 任务状态:pending/running/success/failed |
| `total` | INTEGER | NOT NULL · 默认 `0` | 文件总数 |
| `processed` | INTEGER | NOT NULL · 默认 `0` | 处理成功数 |
| `skipped` | INTEGER | NOT NULL · 默认 `0` | 跳过数 |
| `failed` | INTEGER | NOT NULL · 默认 `0` | 失败数 |
| `error_message` | TEXT | — | 错误信息 |
| `started_at` | DATETIME | — | 开始时间 |
| `finished_at` | DATETIME | — | 完成时间 |
| `created_at` | DATETIME | — | 创建时间 |
| `updated_at` | DATETIME | — | 更新时间 |
索引:`idx_vector_task_created_at`(created_at);`idx_vector_task_project_status`(project_id, status);`ix_project_vectorization_task_project_id`(project_id);`ix_project_vectorization_task_status`(status);`ix_project_vectorization_task_task_id`(task_id) UNIQUE;`ix_project_vectorization_task_user_id`(user_id)
## 通知与审计
### `notifications` — 站内通知
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 通知ID |
| `user_id` | BIGINT | FK → users.id · NOT NULL | 接收用户ID |
| `type` | VARCHAR(20) | 默认 `info` | 类型:info, success, warning, error |
| `category` | VARCHAR(50) | 默认 `system` | 分类:system, project, collaboration |
| `title` | VARCHAR(200) | NOT NULL | 标题 |
| `content` | TEXT | — | 内容 |
| `link` | VARCHAR(255) | — | 跳转链接 |
| `is_read` | SMALLINT | 默认 `0` | 是否已读:0-未读 1-已读 |
| `created_at` | DATETIME | — | 创建时间 |
| `read_at` | DATETIME | — | 阅读时间 |
索引:`ix_notifications_user_id`(user_id)
### `operation_logs` — 操作日志
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | 日志ID |
| `user_id` | BIGINT | — | 操作用户ID |
| `username` | VARCHAR(50) | — | 用户名 |
| `operation_type` | VARCHAR(50) | NOT NULL | 操作类型 |
| `resource_type` | VARCHAR(50) | NOT NULL | 资源类型 |
| `resource_id` | BIGINT | — | 资源ID |
| `detail` | TEXT | — | 操作详情(JSON) |
| `ip_address` | VARCHAR(50) | — | IP地址 |
| `user_agent` | VARCHAR(500) | — | 用户代理 |
| `status` | SMALLINT | 默认 `1` | 状态:0-失败 1-成功 |
| `error_message` | TEXT | — | 错误信息 |
| `created_at` | DATETIME | — | 操作时间 |
索引:`ix_operation_logs_created_at`(created_at);`ix_operation_logs_resource_id`(resource_id);`ix_operation_logs_resource_type`(resource_type);`ix_operation_logs_user_id`(user_id)
### `mcp_bots` — MCP Bot 凭证
| 字段 | 类型 | 约束/默认 | 说明 |
| --- | --- | --- | --- |
| `id` | BIGINT | PK | Bot credential ID |
| `user_id` | BIGINT | UNIQUE · NOT NULL | Owner user ID |
| `bot_id` | VARCHAR(64) | UNIQUE · NOT NULL | External MCP bot id |
| `bot_secret` | VARCHAR(255) | NOT NULL | External MCP bot secret |
| `status` | SMALLINT | 默认 `1` | Status: 0-disabled 1-enabled |
| `last_used_at` | DATETIME | — | Last successful MCP access time |
| `created_at` | DATETIME | — | Created at |
| `updated_at` | DATETIME | — | Updated at |
索引:`ix_mcp_bots_bot_id`(bot_id) UNIQUE;`ix_mcp_bots_status`(status);`ix_mcp_bots_user_id`(user_id) UNIQUE
---
## 变更记录
| 日期 | 变更 |
| --- | --- |
| 2026-09-30 | 按 v1.0.0 代码重写:补齐 `notifications`、`mcp_bots`、`project_git_repos`、`chat_*`、`document_vector`、`project_vectorization_task` 等 10 张此前未记录的表;删除已废弃的 `init_database.sql` 相关描述 |