# 知习 API Server

AI-first 系统化学习平台后端，NestJS 11 + TypeScript。

## 架构

```
Nginx (:80/:443)
  └── /api/* → NestJS API (:3000)

┌─────────────────────────────────────┐
│  API 进程 (main.ts)                  │
│  - REST API (50+ 业务模块)            │
│  - Swagger (/api-docs)               │
│  - Admin API (/admin-api/*)          │
│  - Internal API (/internal/*)        │
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│  Worker 进程 (worker.main.ts)        │
│  - BullMQ 队列消费                    │
│  - AI 分析 / 文档导入 / 通知          │
└─────────────────────────────────────┘

┌──────────┬──────────┬──────────┬──────────┐
│  MySQL 8 │  Redis 7 │  Qdrant  │  COS     │
└──────────┴──────────┴──────────┴──────────┘
```

## 技术栈

| 类别 | 技术 |
|------|------|
| 框架 | NestJS 11 |
| 语言 | TypeScript |
| ORM | Prisma 5 |
| 数据库 | MySQL 8.0 |
| 缓存/队列 | Redis 7 + BullMQ |
| 向量库 | Qdrant |
| 对象存储 | 腾讯云 COS（支持 local 模式） |
| AI | DeepSeek API + SiliconFlow Embedding |
| 认证 | JWT (用户) + JWT (管理员) + Internal API Key + httpOnly Cookie (Admin) |
| 文档 | Swagger (开发默认开启，生产 Basic Auth) |

## 快速开始

```bash
# 1. 安装依赖
npm install

# 2. 启动基础设施（OrbStack Docker）
docker compose -f docker-compose.local.yml up -d

# 3. 初始化数据库
npx prisma migrate deploy

# 4. 配置环境变量
cp .env.example .env.local
# 编辑 .env.local

# 5. 启动 API（开发模式）
npm run start:dev          # → http://localhost:3000

# 6. 启动 Worker（另一个终端）
npm run start:worker
```

### 基础设施（docker-compose.local.yml）

| 服务 | 端口 | 说明 |
|------|------|------|
| MySQL 8.0 | 127.0.0.1:3306 | `zhixi_prod` 数据库 |
| Redis 7 | 127.0.0.1:6379 | BullMQ + 缓存 |
| Qdrant | 127.0.0.1:6333 | 向量检索 |

## 环境变量

| 变量 | 必需 | 说明 |
|------|------|------|
| `DATABASE_URL` | ✅ | MySQL 连接字符串 |
| `REDIS_HOST` | ✅ | Redis 地址 |
| `REDIS_PORT` | ✅ | Redis 端口 |
| `REDIS_PASSWORD` | 否 | Redis 密码 |
| `JWT_SECRET` | ✅ | 用户 JWT 密钥 |
| `ADMIN_JWT_ACCESS_SECRET` | ✅ | 管理员 JWT 密钥 |
| `ADMIN_JWT_REFRESH_SECRET` | 否 | 管理员刷新密钥 |
| `INTERNAL_API_KEY` | ✅ | Worker 内部调用密钥 |
| `CREDENTIAL_ENCRYPTION_KEY` | ✅ | 凭据加密密钥 |
| `DEEPSEEK_API_KEY` | 否 | DeepSeek API Key |
| `SILICONFLOW_API_KEY` | 否 | SiliconFlow Embedding Key |
| `QDRANT_URL` | 否 | Qdrant 地址 |
| `STORAGE_DRIVER` | 否 | `cos` 或 `local`（默认） |
| `COS_SECRET_ID` | 否 | 腾讯云 COS SecretId |
| `COS_SECRET_KEY` | 否 | 腾讯云 COS SecretKey |
| `COS_BUCKET` | 否 | COS Bucket 名称 |
| `COS_REGION` | 否 | COS 区域 |
| `ENABLE_SWAGGER` | 否 | 生产环境启用 Swagger |
| `SWAGGER_USER` | 否 | Swagger Basic Auth 用户名 |
| `SWAGGER_PASSWORD` | 否 | Swagger Basic Auth 密码 |

完整配置参考 `.env.example`。

## 模块清单（50+）

### 用户端 API

| 模块 | 路由前缀 | 说明 |
|------|---------|------|
| auth | `/api/auth` | 用户认证（登录/注册/刷新/登出/Apple） |
| users | `/api/users` | 用户管理 |
| knowledge-base | `/api/knowledge-bases` | 知识库 CRUD |
| ai | `/api/ai` | AI 对话/分析 |
| ai-analysis | `/api/ai-analysis` | AI 分析结果 |
| ai-job | — | AI 作业调度（Worker） |
| ai-runtime | — | AI 运行时（Worker） |
| active-recall | `/api/active-recall` | 主动回忆 |
| review | `/api/review` | 间隔重复复习 |
| quiz | `/api/quiz` | 测验 |
| focus-items | `/api/focus-items` | 待巩固项 |
| learning-session | `/api/learning-session` | 学习会话 |
| learning-activity | `/api/learning-activity` | 学习活跃统计 |
| document-import | `/api/document-import` | 文档导入 |
| rag-chat | `/api/rag/chat` | RAG 知识库对话 |
| notifications | `/api/notifications` | 通知 |
| feedback | `/api/feedback` | 用户反馈 |
| waitlist | `/api/waitlist` | 等待名单 |
| membership | `/api/membership` | 会员/订阅 |
| files | `/api/files` | 文件管理 |
| workspace | `/api/workspace` | 工作区 |
| content-safety | — | 内容安全检测 |
| secrets | — | 密钥管理 |

### 管理端 API

| 模块 | 路由前缀 | 说明 |
|------|---------|------|
| admin-auth | `/admin-api/auth` | 管理员认证（登录/刷新/登出） |
| admin-users | `/admin-api/admin-users` | 管理员 CRUD |
| dashboard | `/admin-api/dashboard` | 数据看板 |
| audit | `/admin-api/audit` | 审计日志 |
| billing | `/admin-api/billing` | API 用量/成本 |
| config | `/admin-api/config` | 系统配置 |
| servers | `/admin-api/servers` | 服务器监控 |
| ai-gateway | `/admin-api/ai-gateway` | AI 网关路由 |
| compliance | `/admin-api/compliance` | 合规安全 |
| release | `/admin-api/release` | 发布决策 |
| learning | `/admin-api/learning` | 学习数据总览 |
| imports | `/admin-api/imports` | 文档导入监控 |
| notifications-admin | `/admin-api/notifications` | 通知管理 |
| backup | `/admin-api/backup` | 备份清理 |
| vector | `/admin-api/vector` | 向量检索 |
| metrics | `/admin-api/metrics` | 接口监控 |
| throttle | `/admin-api/throttle` | 限流管理 |

### 内部 API（Worker 调用）

| 路由 | 说明 |
|------|------|
| `POST /internal/rag/jobs/next` | 获取下一个导入任务 |
| `POST /internal/rag/jobs/:id/claim` | 认领任务 |
| `POST /internal/rag/jobs/:id/heartbeat` | 心跳 |
| `POST /internal/rag/jobs/:id/status` | 更新状态 |
| `POST /internal/rag/chunks` | 批量保存 Chunk |
| `POST /internal/rag/candidates` | 保存候选知识点 |

## 目录结构

```
src/
├── main.ts                   # API 进程入口
├── worker.main.ts            # Worker 进程入口
├── app.module.ts             # 根模块
├── modules/                  # 50+ 业务模块
│   ├── auth/
│   ├── admin-auth/
│   ├── ai/
│   ├── knowledge-base/
│   ├── rag-chat/
│   ├── quiz/
│   ├── membership/
│   ├── files/
│   └── ...
├── common/                   # 公共
│   ├── guards/               # Auth Guards (JWT, Admin, Roles, Internal)
│   ├── decorators/           # @AdminPublic, @AdminRoles, @InternalApiKey
│   ├── filters/              # 异常过滤器
│   ├── interceptors/         # 拦截器 (HTTP 日志等)
│   └── utils/                # 工具函数
├── infrastructure/           # 基础设施层
│   ├── database/             # Prisma Service
│   ├── redis/                # Redis Service
│   ├── queue/                # BullMQ 注册
│   ├── storage/              # 存储 (local/COS)
│   └── outbox/               # Outbox 模式
├── workers/                  # Worker 处理器
├── config/                   # 配置
└── test/                     # 测试
```

## 接口文档

- **本地**：http://localhost:3000/api-docs（无需认证）
- **生产**：https://api.longde.cloud/api-docs（Basic Auth）
- **Apifox 导入**：`https://admin:password@api.longde.cloud/api-docs-json`

## 认证体系

```
用户端：
  JWT Bearer token (Authorization: Bearer <jwt>)
  Refresh token 存储在 RefreshToken 表

管理员：
  httpOnly Cookie (admin_access_token) — Web Admin
  Authorization: Bearer <jwt> — API 调用（兼容 iOS）
  x-api-key — 自动化

Worker：
  x-internal-api-key header
```

## 部署

### CI/CD（Gitea Actions）

推送 `main` → 构建 → 集成测试 → 向后兼容测试 → 部署

```
rsync dist/ + node_modules/ → /opt/zhixi/backend/
systemctl restart zhixi-api + zhixi-nest-worker
```

### 生产服务器

| 组件 | 运行方式 | 位置 |
|------|---------|------|
| NestJS API | systemd (`zhixi-api`) | `/opt/zhixi/backend/` |
| NestJS Worker | systemd (`zhixi-nest-worker`) | `/opt/zhixi/backend/` |
| MySQL 8.0 | Docker | `/data/mysql/` |
| Redis 7 | Docker | `/data/redis/` |
| Qdrant | Docker | `/data/qdrant/` |
| RAG Worker | systemd (`zhixi-worker`) | `/opt/zhixi/rag-worker/` |

### 手动部署

```bash
npm run build
rsync -av --delete dist/ node_modules/ prisma/ package.json ubuntu@120.53.227.155:/opt/zhixi/backend/
ssh ubuntu@120.53.227.155 'cd /opt/zhixi/backend && npx prisma generate && sudo systemctl restart zhixi-api zhixi-nest-worker'
```

### 常用运维命令

```bash
# 服务状态
systemctl status zhixi-api zhixi-nest-worker

# 查看日志
journalctl -u zhixi-api -f
journalctl -u zhixi-nest-worker -f

# 数据库迁移
cd /opt/zhixi/backend && npx prisma migrate deploy

# 健康检查
curl http://127.0.0.1:3000/health
```
