startup-plan/技术设计/api-server/服务器与数据库部署方案.MD

861 lines
26 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 知习数据库与服务器部署方案(最终版)
> 定版日期2026-05-18 | 状态:已拍板,按此执行 | 最后检查2026-05-20 14:00
>
> 完成度标记:✅ 已完成 | 🔶 部分完成 | ⏳ 待完成 | ❌ 未开始
---
## 一、存储架构总览 ✅ 已完成
知识库不需要 MongoDB。最终存储分成四类
```text
MySQL :权威业务数据(用户、知识库、学习记录、额度、审计)
Qdrant 向量索引chunk embedding、语义检索
COS :对象存储(原始文件、解析结果、备份快照)
Redis :队列 / 缓存 / 限流 / 锁
```
不引入的组件:
```text
MongoDB → 不需要(没有文档型存储场景)
Elasticsearch → 第一阶段不需要Qdrant + rerank 够用)
ClickHouse → 第一阶段不需要OLAP 后续再说)
```
---
## 二、MySQL唯一权威业务数据库 ✅ 已完成
### 存放内容
```text
# 用户与认证
users
auth_accounts
refresh_tokens
memberships
membership_plans
# 知识库核心
files
knowledge_bases
knowledge_sources
document_imports
knowledge_chunks
import_candidates
knowledge_items
# 学习引擎
active_recall_answers
ai_analysis_results
focus_items
review_cards
learning_activities
chat_sessions
chat_messages
# 运营与审计
ai_usage_logs
quota_usage
admin_audit_logs
backup_jobs
feedback
notifications
```
### ID 类型(重要)✅ 已改为 String(cuid)
当前 Prisma schema 主键是 `BigInt @default(autoincrement())`JavaScript/JSON 对 64 位整数有精度问题。
**现在数据库空,必须立即改:**
```prisma
id String @id @default(cuid())
```
推荐 `cuid/cuid2`:适合业务 ID前端、后端、日志、JWT、API 都好处理。以后数据多了再改会很痛苦。
### 生产配置 ✅ 已应用
文件:`/etc/mysql/conf.d/zhixi.cnf`
```ini
[mysqld]
# InnoDB
innodb_buffer_pool_size = 8G
innodb_buffer_pool_instances = 4
innodb_log_file_size = 1G
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
# Connections
max_connections = 100
wait_timeout = 300
interactive_timeout = 300
# Charset
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# Slow query
slow_query_log = 1
long_query_time = 1
log_queries_not_using_indexes = 0
# Binlog无主从复制时可关
skip-log-bin
```
### 32G 内存分配 ✅ 按方案执行
```text
MySQL buffer pool 8G
Qdrant 8G12G动态
Redis 1G 内
RAG Worker / 解析 4G8G
系统 + Docker + 缓存 4G+
预留安全空间 4G+
```
后续调整规则:
```text
MySQL 慢查询多 + 内存充足 → buffer pool 调到 10G12G
Qdrant / Worker 内存吃紧 → 不再加 MySQL 内存
Too many connections → max_connections 调到 150
---
## 三、Qdrant向量数据库 ✅ 已完成
### 存放内容
```text
Collectionzhixi_chunks
├─ chunk embedding 向量1024dCosine
├─ userId / knowledgeBaseId / sourceId / chunkIdpayload 索引)
├─ pageNumber / sectionTitle元数据
└─ deletedbool软删除标记
```
### 负责的能力
```text
语义检索ANN Top-50 → rerank Top-5~8
知识库问答召回
相似知识点查找
学习内容推荐
```
### 不负责
```text
用户体系
会员额度
知识点管理
学习记录
订单支付
```
Qdrant 是 MySQL 的补充,不是替代。
### 安全策略(已拍板)
```text
第一阶段:不公网暴露 Qdrant
优先方案:不映射端口,只在 Docker internal network 用容器名访问
调试方案:仅绑定 127.0.0.1:6333
暂不启用 API Key但预留 QDRANT_API_KEY 环境变量
未来跨服务器访问时 → 必须启用 API Key
```
### Docker Compose 推荐写法(不映射端口)
```yaml
services:
qdrant:
image: qdrant/qdrant:latest
restart: unless-stopped
volumes:
- /data/qdrant:/qdrant/storage
networks:
- zhixi_internal
# 不写 ports公网访问不到
backend:
image: zhixi-backend:latest
restart: unless-stopped
environment:
QDRANT_URL: http://qdrant:6333
networks:
- zhixi_internal
- zhixi_public
networks:
zhixi_internal:
internal: true # 不对外暴露
zhixi_public:
```
### 如需宿主机调试(仅绑定 localhost
```yaml
services:
qdrant:
ports:
- "127.0.0.1:6333:6333"
- "127.0.0.1:6334:6334"
```
### 不要这样写
```yaml
ports:
- "6333:6333" # 暴露公网!没有 API Key 时非常危险
```
---
## 四、COS对象存储 ✅ 凭据已配置Bucket 已验证
### 存放内容
```text
zhixi-prod/
├─ users/{userId}/knowledge-bases/... ← 原始文件 + 解析结果
├─ users/{userId}/profile/avatar/... ← 头像
├─ users/{userId}/feedback/... ← 反馈截图
├─ system/knowledge-bases/... ← 系统内置知识库
├─ system/backups/qdrant/{date}/... ← Qdrant 快照
├─ system/backups/mysql/{date}/... ← MySQL 备份
├─ exports/users/{userId}/... ← 用户导出
└─ public/app-assets/... ← 公共资源
```
### 原则
```text
数据库是主关系COS 是文件仓库
权限、归属、状态永远以数据库为准
处理文件时从 COS 临时拉取,处理完删除本地临时文件
```
---
## 五、Redis队列与缓存 ✅ 已完成BullMQ document-import 队列已运行)
### 负责
```text
BullMQ 任务队列文档导入、AI 分析、通知发送)
API 限流
分布式锁(防止重复导入、重复扣额度)
用户 session备选也可用 MySQL
临时状态缓存
```
### 不负责
```text
长期业务数据
向量索引
文件存储
```
---
## 六、服务器分工(已拍板)✅ 按方案执行
### 总原则
现在数据库基本空,**不要再把新表建到旧服务器上**。唯一权威 MySQL 放 8核32G。
### 8核32G CVM正式生产主服务器
**部署清单:**
```text
/opt/zhixi/backend ← NestJS 主后端
/opt/zhixi/rag-worker ← Python RAG Worker
/opt/zhixi/deploy ← docker-compose.yml + 脚本
/data/docker ← Docker data-root
/data/mysql ← MySQL 数据文件
/data/redis ← Redis 数据文件
/data/qdrant ← Qdrant 存储
/data/tmp/imports ← 临时下载/解析工作区
/data/logs ← 统一日志
/data/worker-cache ← llama-index 缓存
/data/backups/mysql ← MySQL 每日备份
/data/backups/qdrant ← Qdrant 每日快照
```
**运行服务:**
```text
Nginx可选
NestJS APINode
MySQL 8.0
Redis 7
QdrantDocker
RAG WorkerPython
AI Gateway WorkerNode
Backup WorkerCron
Cron Jobs定时清理、stale job recovery
```
**负责的业务:**
```text
全部用户数据、认证、会员
全部知识库数据(表 + 向量)
全部学习引擎主动回忆、AI 诊断、复习)
全部 AI 调用与成本记录
全部后台管理与审计
```
### 4核4G 轻量云:工具服务器 / 辅助服务器
**定位:** 继续当工具服务器,不承载生产核心数据。
**已运行服务(保留):**
```text
Web 产品页 / landing page
Gitea
```
**适合新增的服务:**
```text
n8n ← 营销自动化、流程编排、Webhook
轻量 agent runner ← CI/CD 辅助、定时调研、通知
Uptime Kuma ← 服务监控
跳板机 ← SSH 入口
测试 / staging 环境 ← 预发布验证
Gitea Webhook 自动化 ← CI/CD 触发
营销自动化脚本 ← 定时任务
轻量后台工具 ← 不操作生产库的管理工具
```
**不建议放 4核4G 的服务:**
```text
正式 MySQL / Redis / Qdrant ← 生产核心数据
RAG Worker / 文档解析 ← 重型 CPU/内存任务
Dify 生产环境 ← 最低 4G 但跑不稳(后面细说)
本地大模型 / 多模态模型 ← GPU/内存不够
重型爬虫 / 大量自动化任务 ← 吃满 CPU
```
---
## 6.5、两服务器内网互联 ✅ 已验证
| 项目 | 值 |
|------|-----|
| 8核32G 内网 IP | 172.21.0.4 |
| 4核4G 内网 IP | 10.2.0.7 |
| 延迟 | ~1.9ms(双向 ping |
| 通信原则 | **所有服务器间通信均走内网,不走公网** |
### 已验证的通信路径
| 路径 | 内网地址 | 验证结果 |
|------|---------|---------|
| 8核32G → 4核4G Gitea | `http://10.2.0.7:3000` | ✅ HTTP 200, 6.5ms |
| 4核4G → 8核32G API | `http://172.21.0.4:3000` | ✅ 正常响应 |
| 8核32G Runner 注册 | `http://10.2.0.7:3000` | ✅ 已切换restart 正常 |
### 对内网通信的服务
| 服务 | 原地址 | 切换后 |
|------|--------|--------|
| zhixi-prod-runner → Gitea | `81.70.187.179`(公网) | `10.2.0.7`(内网) |
| 4核4G CI/CD → 8核32G API | `api.longde.cloud` | 可切 `172.21.0.4`(待优化) |
| COS 上传/下载 | `cos.ap-beijing.myqcloud.com`(内网) | 同区 VPC 内网,免流量费 |
---
## 七、4核4G 上各服务决策 ✅ 已定案
### 1. n8n可以放
n8n 适合放 4核4G用来做
```text
营销自动化
内容生产流程编排
Gitea Webhook 触发
定时任务
数据同步
通知提醒
AI API 调用编排
运营脚本
```
部署方式:
```text
Docker Compose
nginx/caddy 反代 → https://n8n.yourdomain.com
```
安全要求:
```text
强密码
HTTPS
禁止公开注册
后台路径不裸奔
定期备份 n8n 数据目录
```
**核心规则n8n 不直接操作生产数据库。**
正确方式:
```text
n8n / agent
→ 调用 8核32G 的受控内部 API
→ 8核32G 做权限、额度、日志、落库
```
不要让 n8n 或 agent 变成"野生后台"。
### 2. Dify第一阶段不部署
Dify 最低要求 CPU ≥ 2 Core、RAM ≥ 4 GiB官方推荐 8 GiB 更稳。4核4G 已有 Web 产品页 + Gitea + n8n + agent再放 Dify 容易"能启动但卡、能用但不稳、一跑 workflow 就吃满"。
而且 Dify 和你自己的 AI Gateway / RAG Worker 有功能重叠,知习核心知识库才是优先事项。
**决策:**
```text
第一阶段不部署 Dify。
后续如需实验,放 8核32G sandbox profile不连生产库
```
```bash
# 以后如需实验:
docker compose --profile dify up -d # 用完关掉
```
### 3. 轻量 agent可以放
适合放 4核4G 的 agent 类型:
```text
营销内容生成 agent
定时调研 agent
Gitea issue 分析 agent
自动发布提醒 agent
数据采集辅助 agent
n8n workflow agent
小型 webhook agent
```
规则和 n8n 一样:**agent 可以调用知习 API但不可直接连生产 MySQL、操作 Qdrant、拿 COS 主密钥。**
---
## 八、最终部署架构图 ✅ 已落实
```text
iOS / Web
┌───────────────┴───────────────┐
│ │
┌───────┴──────────┐ ┌───────┴──────────┐
│ 8核32G CVM │ │ 4核4G 轻量云 │
│ (生产核心服务器) │ │ (工具/辅助服务器) │
│ │ │ │
│ ┌──────────────┐ │ │ ┌───────────────┐ │
│ │ gitea-runner │ │ CI/CD │ │ gitea-runner │ │
│ │ -prod │ │ │ │ -web │ │
│ └──────────────┘ │ │ └───────────────┘ │
│ ┌──────────────┐ │ │ ┌───────────────┐ │
│ │ NestJS API │ │ │ │ Web 产品页 │ │
│ └──────┬───────┘ │ │ │ (landing) │ │
│ │ │ │ └───────────────┘ │
│ ┌──────┴───────┐ │ │ ┌───────────────┐ │
│ │ MySQL │ │ 权威业务库 │ │ Gitea │ │
│ └──────────────┘ │ │ │ (主服务) │ │
│ ┌──────────────┐ │ │ └───────────────┘ │
│ │ Redis │ │ 队列/缓存 │ ┌───────────────┐ │
│ └──────────────┘ │ │ │ n8n │ │
│ ┌──────────────┐ │ │ └───────────────┘ │
│ │ Qdrant │ │ 向量索引 │ ┌───────────────┐ │
│ └──────────────┘ │ │ │ agent runner │ │
│ ┌──────────────┐ │ │ └───────────────┘ │
│ │ RAG Worker │ │ 解析/切片 │ ┌───────────────┐ │
│ └──────────────┘ │ │ │ Uptime Kuma │ │
│ ┌──────────────┐ │ │ └───────────────┘ │
│ │ AI Gateway │ │ AI 调度 │ │
│ └──────────────┘ │ │ (不承载正式 │
│ ┌──────────────┐ │ │ 业务数据) │
│ │ Backup+Cron │ │ 备份/清理 └───────────────────┘
│ └──────────────┘ │
│ │
│ /data (70G) │
└────────┬─────────┘
┌───────┴───────┐
│ 腾讯云 COS │
│ │
│ 原始文件 │
│ parsed.md │
│ OCR/Vision │
│ 备份快照 │
│ 用户头像 │
│ 导出文件 │
└───────────────┘
```
---
## 九、CI/CD 部署流水线 ✅ api-server + web-projects 均已配置
### 1. 总原则
```text
Gitea 本体只放 4核4GRunner 两台都装
服务跑在哪台服务器Runner 就装在哪台服务器
每台 Runner 本地构建、本地部署,不跨服务器传输构建产物
```
不要搞成"4核 Runner 构建后端 → 传到 8核部署",多一层 SSH + 传输 + 1Mbps 带宽瓶颈。
### 2. Runner 分工
**4核4Ggitea-runner-web**
```text
标签web, tools, staging, docker
负责:
Web 产品页部署
Gitea Webhook 自动化
n8n / 工具服务部署
轻量 agent 更新
```
**8核32Ggitea-runner-prod**
```text
标签prod, backend, rag, docker
负责:
NestJS 后端部署
Prisma migration
MySQL / Redis / Qdrant docker compose 更新
RAG Worker 部署
AI Gateway 部署
备份脚本部署
```
### 3. Runner 安装 ✅ 已完成
- ✅ 8核32G: `gitea-runner` systemd 自启
- ✅ 4核4G: `gitea-runner` systemd 自启(单一 runner 同时处理 api-server 和 web-projects
```bash
sudo useradd -m -s /bin/bash deploy
sudo usermod -aG docker deploy
```
8核上注册 runner 到 4核 Gitea
```bash
# 在 8核32G 上执行
./gitea-actions-runner register \
--name zhixi-prod-runner \
--labels prod,backend,rag,docker \
--instance https://gitea.yourdomain.com \
--token <从 Gitea Admin 获取>
```
### 4. Workflow 实际部署 ✅ 已落地
**后端部署4核4G runner 执行):**
- 实际文件:`/home/ubuntu/api-server/.gitea/workflows/deploy.yml`
- 流程git pull → Docker build → 处理迁移卡死 → 启动 zhixi-api 容器 → 健康检查
**Web 部署4核4G runner 执行):**
- 实际文件:`/tmp/web-projects/.gitea/workflows/deploy.yml`
- 流程git clone/pull → Astro build (Docker node:22) → Nginx 配置 → 部署到 /var/www/longde.cloud → 确保后端运行 → Nginx reload
- 最后部署2026-05-20 13:38 ✅
### 5. 密钥管理 ✅ 已配置
生产密钥已放在服务器本地:
```text
8核32G: /opt/zhixi/env/.env.production ✅ 全部必需密钥已配置
4核4G: /etc/zhixi/.env.production ✅(含 COS/DEEPSEEK/SILICONFLOW/JWT
rag-worker: /opt/zhixi/backend/rag-worker/.env ✅
已配置:
DATABASE_URL ✅
REDIS_HOST/REDIS_PORT/REDIS_PASSWORD ✅
QDRANT_URL ✅
COS_SECRET_ID / COS_SECRET_KEY ✅
DEEPSEEK_API_KEY ✅
SILICONFLOW_API_KEY ✅
JWT_SECRET ✅
RAG_WORKER_SECRET ✅
BAIDU_OCR_KEY ❌ 待开通
```
### 6. Gitea 挂了不影响生产 ✅ 已验证
```text
Gitea 只影响代码仓库和部署流水线
8核上的后端、MySQL、Redis、Qdrant 继续运行
最多暂时不能自动部署新版本
```
---
## 十、迁移执行计划 🔶 部分完成
因为现在数据库基本空,迁移很简单,按此顺序推进:
### 第一步8核32G 基础环境 ✅ 已完成
```text
1. 挂载 /data 数据盘 ✅
2. 安装 Docker / Docker Compose ✅
3. 配置 Docker data-root → /data/docker ✅
4. 创建所有 /data 子目录 ✅
5. 创建 deploy 用户(用于 Runner 和部署)✅
```
### 第二步:部署核心服务 ✅ 已完成
```text
6. 部署 MySQL → /data/mysql创建数据库 zhixi_prod ✅
7. 部署 Redis → /data/redis ✅
8. 部署 Qdrant → /data/qdrant创建 collection zhixi_chunks ✅
9. 配置数据库连接DATABASE_URL / REDIS_URL / QDRANT_URL ✅
```
### 第三步:数据库迁移 ✅ 已完成
```text
9. 修改 Prisma schemaBigInt → String(cuid) ✅
10. 初始化空库 migration ✅ (3 个 migration 执行)
11. 4核4G mysqldump → 导入 8核32G ✅
12. 配置备份脚本MySQL + Qdrant + 同步 COS🔶 本地完成COS 同步待配
```
### 第四步CI/CD 搭建 ✅ 已完成
```text
14. 8核32G 安装 gitea-runner-prod ✅
15. 4核4G 安装 gitea-runner-web ✅ (单一 runner 覆盖两端)
16. 配置 Gitea Secrets ✅
17. 编写 deploy-backend.yml / deploy-web.yml ✅
18. 测试 push → 自动构建 → 自动部署流水线 ✅ (web 今日 13:38 部署成功)
```
### 第五步DNS 与后端切换 ✅ 已完成
```text
19. 确认 8核32G 上 NestJS 正常运行 ✅
20. DNS api.longde.cloud 切换到 8核32G ✅
21. Nginx 配置 SSL 证书 ✅ (Let's Encrypt)
22. 修改 DATABASE_URL 指向新 MySQL ✅
23. 测试 iOS 登录功能(通过域名 + HTTPS
```
> **当前状态DNS 已切换到 8核32G。✅**
### 第六步:知识库开发 ✅ 核心已通
```text
23. 在 8核32G 上按知识库设计文档建表 ✅ (35 张表)
24. 实现文件上传 → COS 🔶 (COS 凭据已配API 已就,待 iOS 真文件测试)
25. 部署 RAG Worker ✅ (systemd zhixi-worker 已启动)
26. 打通索引流程 → 学习流程 ✅
- raw text 导入全链路 ✅ (chunk→embed→Qdrant→candidate)
- RAG 对话 ✅ (检索→rerank→DeepSeek+citations)
- 多轮对话 ✅ (history 参数)
- 级联删除 ✅
- 备份 ✅ (本地 cronCOS 同步待配)
- 学习引擎ActiveRecall/AIAnalysis/FocusItem/Review模块已建待端到端对接测试
```
---
## 十一、最终拍板清单(执行状态)
```text
# 存储架构
1. ✅ 唯一权威 MySQL 放 8核32G4核4G 不再建新表
2. ✅ ID 类型立即从 BigInt 改为 String(cuid),趁库空
3. ✅ Redis 放 8核32G队列 / 缓存 / 限流 / 锁)
4. ✅ Qdrant 放 8核32G向量索引
5. ✅ COS 继续作为文件 + 备份存储
6. ✅ 不引入 MongoDB / Elasticsearch / ClickHouse
# 8核32G生产核心服务器
7. ✅ 全量承载 NestJS + MySQL + Redis + Qdrant + RAG Worker + AI Gateway
8. ✅ 负责全部用户数据、知识库、学习引擎、成本记录、后台审计
9. ✅ 安装 gitea-runner-prod负责后端/知识库/RAG 部署)
# 4核4G工具服务器 / 辅助服务器
10. ✅ 保留 Gitea 主服务 + Web 产品页
11. ✅ 安装 gitea-runner-web单一 runner 覆盖 web + api-server 两端)
12. ⏳ 可以加 n8n营销自动化、Webhook、流程编排
13. ⏳ 可以加轻量 agent runner不直接操作生产库
14. ⏳ 可以加 Uptime Kuma 监控
15. ✅ Dify 第一阶段不部署
16. ✅ 不承载正式 MySQL / Qdrant / Redis / RAG Worker
# CI/CD
17. ✅ Gitea 本体只放 4核4GRunner 两台都装
18. ✅ 服务跑在哪台服务器Runner 就装在哪台服务器
19. ✅ 生产密钥放服务器本地 .env不写入仓库
20. ✅ Runner 使用 ubuntu 用户
# 安全边界
21. ⏳ n8n / agent 调用知习受控 API不直连生产库n8n 未部署)
22. ✅ 迁移完成后 4核4G 旧 API 容器已移除
23. ✅ UFW 防火墙两台均已启用22/80/443 + 4核4G 2222
24. ✅ Fail2ban 4核4G 已安装sshd jail
```
后续不会再有一次大的数据库迁移。
---
## 十二、仍存缺陷与待决策项(状态更新)
以下是当前方案中尚未覆盖或需要你拍板的点,按风险等级排序。
### 🔴 高风险(上线前必须定)
| # | 问题 | 现状 | 建议 |
|---|------|------|------|
| 1 | **3Mbps 公网带宽** | ✅ 已处理 | 日常增量文件(单文件 ≤20MB影响可控。大文件下载 COS + 备份上传走后台队列异步处理,不阻塞 API。 |
| 2 | **Qdrant 无内置认证** | ✅ 已定 | 仅绑定 `127.0.0.1:6333`,不公网暴露。 |
| 3 | **HTTPS 证书** | ✅ 已配置 | Let's Encrypt 已生效api.longde.cloud + longde.cloud + git.longde.cloud |
| 4 | **MySQL 配置调优** | ✅ 已应用 | `innodb_buffer_pool_size=8G``max_connections=100` |
### 🟡 中风险(迁移前应定)
| # | 问题 | 现状 | 建议 |
|---|------|------|------|
| 5 | **Redis 持久化** | ✅ 已配置 | AOF everysec + RDB 双开 |
| 6 | **Docker 容器网络规划** | ✅ 已配置 | `zhixi-net` bridge 网络MySQL/Redis 绑定 localhost |
| 7 | **日志轮转与保留** | 🔶 /data/logs 目录已建 | logrotate 待确认 |
| 8 | **健康检查端点** | ✅ 已实现 | `/api` 返回 `{"status":"ok"}`,被 CI/CD 使用 |
| 9 | **两服务器间通信** | ✅ 内网直连 | 双向 ~1.9msRunner/API 互调均走内网 |
| 10 | **COS 带宽成本** | ✅ 已验证 | Bucket `zhixi-1259685406`,同区 VPC 内网免流量费 |
### 🟢 低风险(后续迭代时再定)
| # | 问题 | 现状 |
|---|------|------|
| 11 | **API 版本管理** | ⏳ 无 /api/v1/ 前缀 |
| 12 | **灰度/蓝绿部署** | ⏳ 后续 |
| 13 | **数据库读写分离** | ⏳ 后续 |
| 14 | **异地备份COS 同步)** | ⏳ 本地备份已有COS 上传待配 |
| 15 | **4核4G 最终去留** | ✅ 保留作为工具服务器 |
| 16 | **Docker Compose 统一** | 🔶 当前独立 docker run未统一 compose |
| 17 | **logrotate** | ⏳ 待确认 |
| 18 | **BAIDU_OCR_KEY** | ✅ 已开通AppID 7767914 |
---
## 十三、当前工作流总览2026-05-20 终态)
### 已实现并验证的流程
**流程一文档导入NestJS BullMQ Worker**
```
POST /api/imports {rawText, knowledgeBaseId}
→ DocumentImportWorker:
→ ChunkingService512t/64overlap按标题/段落/句子分割)
→ VectorServicebge-m3 batch 50 → Qdrant UUID upsert → MySQL chunk 写入)
→ KnowledgeImportWorkflowDeepSeek 提取知识点)
→ ImportCandidate 写入
→ KB.itemCount 更新
→ COMPLETED
```
**流程二RAG 对话**
```
POST /api/rag/chat {knowledgeBaseId, query, history?}
→ RagChatService:
→ embed querybge-m3
→ Qdrant 向量搜索(按 kbId/deleted 过滤)
→ rerankbge-reranker-v2-m3
→ DeepSeek 回答 + citations
→ 支持多轮history 参数,最近 10 条上下文注入)
```
**流程三:知识库管理**
```
POST /api/knowledge-bases 创建
GET /api/knowledge-bases 列表
GET /api/knowledge-bases/:id 详情
PATCH /api/knowledge-bases/:id 更新
DELETE /api/knowledge-bases/:id 级联删除items/chunks/candidates/imports/sources/Qdrant
```
**流程四:备份**
```
cron 0 3 * * * /opt/zhixi/backup/backup.sh
→ MySQL dump + Qdrant snapshot → /data/backups/
→ 本地保留 7 天 + 物理清理cron 0 4
```
### 已建但未端到端对接的模块
| 模块 | 状态 | 缺什么 |
|------|------|--------|
| ActiveRecall | controller + worker | 与学习 session 的串联未测试 |
| AIAnalysis | controller + AiAnalysisWorker + 2 workflows | 同上 |
| FocusItem | controller + service | 依赖 AIAnalysis 输出 |
| ReviewCard | controller + workflow | 依赖 FocusItem 触发 |
| LearningSession | controller + service | 独立可用,缺学习引擎串联 |
| LearningActivity | heatmap/summary/trend | 数据写入了但从未被查询展示 |
| Files/COS 上传 | controller + COS SDK | 待 iOS 端真文件触发测试 |
### 待完成(代码级)
| # | 事项 | 说明 |
|---|------|------|
| 1 | COS 备份同步 | 每日备份后上传到 COS |
| 2 | COS 生命周期 | 7 天物理删除策略 |
| 3 | MySQL 物理清理 | 30 天 deletedAt 清理脚本 |
| 4 | Docker Compose 统一 | 整理 docker run 为 compose |
| 5 | logrotate 确认 | 检查轮转配置 |
### 待完成(产品/策略级)
| # | 事项 | 说明 |
|---|------|------|
| 6 | 学习引擎串联测试 | ActiveRecall→AIAnalysis→FocusItem→ReviewCard |
| 7 | iOS 文件上传测试 | COS 真文件上传 + Python Worker 解析 |
| 8 | Chat session 持久化 | 服务端存储 session + messages |
| 9 | 知识库设计文档决策表 21/23/24 | COS 同步 + 物理清理 |
---
## 十三、文档关联索引
本文档应与其他设计文档配合使用:
```text
知识库设计.MD → 数据模型、API 设计、RAG 流程、额度系统
服务器与数据库部署方案.MD → 本文档服务器分工、存储架构、CI/CD
后续Prisma Schema → 具体表结构实现
后续docker-compose.yml → 容器编排配置
```