---
source: startup-plan/个人开发者创业 v0.1 + 完全版 + AI回答.md 架构深化方案
updated: 2026-05-17
---

# 知习 api-server 后端架构规划

> 「知习」是一款 AI-first 的系统化学习 App。后端需要同时服务 iOS App 和 Web 官网。
> 核心功能包括知识库、主动回忆、AI 学习分析、间隔复习、待巩固项、学习活跃记录、消息通知和反馈。

## 当前状态

> 详细实现进度见 [`已完成/[已完成]-已实现功能汇总.md`](./已完成/[已完成]-已实现功能汇总.md) 和 [`已完成/[已完成]-后端实现状态.md`](./已完成/[已完成]-后端实现状态.md)

**已部署**：api.longde.cloud（NestJS + Prisma + MySQL + Docker + Nginx + SSL）  
**编译**：`npx tsc --noEmit` 0 errors  
**全局守卫**：JwtAuthGuard → RolesGuard（USER/ADMIN/SUPER_ADMIN）  
**业务模块**：14/14 完成（Auth → System）  
**AI**：三层架构落地，1/5 Workflow 完成

**待推进**：AI Workflows（费曼/导入/复习卡片/趋势）、BullMQ/Redis 异步化、iOS 对接、Admin 后台

---

## 1. 架构总览：模块化单体 + Redis + Worker

**不要微服务。** 当前最适合的是：

> **模块化单体架构 Monolithic Modular Architecture**
>
> 一个后端项目，内部按业务模块拆清楚。

```text
iOS App
Web 官网
   ↓
统一 API 后端（NestJS 模块化单体）
   ↓
数据库 / Redis / 文件存储 / AI 服务
   ↓
Worker 异步任务
```

---

## 2. 最终技术栈

```text
后端框架：NestJS + TypeScript
ORM：Prisma
数据库：PostgreSQL（推荐），MySQL 亦可
缓存/队列：Redis
队列系统：BullMQ
接口文档：Swagger / OpenAPI
文件存储：本地开发先本地存，后期接对象存储
AI：Provider 抽象 + 一个真实模型 + MockProvider
部署：Docker Compose
反向代理：Nginx
域名：api.longde.cloud
```

Docker Compose 项目服务规划：

```text
api-server   — NestJS 后端
postgres     — 主数据库
redis        — 缓存 + 队列
worker       — 异步任务处理
nginx        — 反向代理 + HTTPS
```

---

## 3. 为什么选这个技术栈

### NestJS

项目会越来越模块化。NestJS 的模块结构适合长期维护：

```text
用户 / 知识库 / 学习记录 / AI 分析 / 复习计划 / 待巩固项 / 通知 / 反馈 / 订阅
```

Express 也能做，但后期容易自己手写一堆规范，最后变乱。

### Prisma

- 类型安全的 ORM，自动生成 TypeScript 类型
- 迁移管理清晰
- 与 NestJS 集成良好
- AI Agent 按 schema 生成代码能力好

### PostgreSQL（优于 MySQL）

- 更适合 JSON 数据（AI 分析结果）
- 支持全文检索
- 后续可扩展 pgvector 做向量检索
- 如果更熟悉 MySQL，也可以先用 MySQL

### Redis + BullMQ

Redis 不只是缓存，在知习系统里做四件事：

```text
缓存 → 短期数据加速
队列 → AI 分析 / 资料导入 / 通知任务
限流 → AI 调用频控 / 用户请求限流
临时状态 → 任务处理中状态 / 防重复提交锁
```

---

## 4. 前后端职责分离

| 端 | 职责 |
|---|------|
| iOS 客户端 | 页面展示、用户交互、本地状态、登录入口、学习流程体验 |
| 后端 API | 用户身份、AI API 代理、学习记录、AI 分析、学习画像、复习计划、待巩固项、通知、反馈 |
| Worker | AI 分析任务异步处理、资料导入异步处理、通知分发 |
| AI 模型 | 分析用户输入、生成学习反馈、识别薄弱点、生成复习建议、辅助学习对话 |
| 官网 | 产品介绍、SEO、隐私政策、用户协议、支持页面、等待名单 |

---

## 5. 数据库和 Redis 的分工

```
PostgreSQL / MySQL：长期真实数据
Redis：短期状态、缓存、队列、限流
文件存储：PDF、图片、附件
AI 服务：分析、总结、生成复习题
```

一句话：

> **数据库存事实，Redis 管状态。**

### Redis 适合做

- AI 分析任务队列
- 资料导入任务队列
- 通知任务队列
- 用户请求限流
- AI 调用次数计数
- 任务处理中状态
- 防重复提交锁
- 短期缓存

### Redis 不适合做主数据

这些必须进数据库：

- 用户资料
- 知识库
- 学习记录
- AI 分析结果
- 待巩固项
- 复习计划
- 学习活跃记录
- 通知记录

---

## 6. 后端目录结构

```text
api-server/
├── src/
│   ├── main.ts
│   ├── app.module.ts
│   │
│   ├── config/
│   │   ├── app.config.ts
│   │   ├── database.config.ts
│   │   ├── redis.config.ts
│   │   ├── jwt.config.ts
│   │   ├── ai.config.ts
│   │   └── storage.config.ts
│   │
│   ├── common/
│   │   ├── constants/
│   │   ├── decorators/
│   │   ├── guards/
│   │   ├── interceptors/
│   │   ├── filters/
│   │   ├── pipes/
│   │   ├── dto/
│   │   ├── types/
│   │   └── utils/
│   │
│   ├── infrastructure/
│   │   ├── database/
│   │   ├── redis/
│   │   ├── queue/
│   │   ├── ai/
│   │   │   ├── prompts/
│   │   │   └── providers/
│   │   ├── storage/
│   │   └── logger/
│   │
│   ├── modules/
│   │   ├── auth/
│   │   ├── users/
│   │   ├── knowledge-base/
│   │   ├── knowledge-items/
│   │   ├── document-import/
│   │   ├── learning-session/
│   │   ├── active-recall/
│   │   ├── ai-analysis/
│   │   ├── review/
│   │   ├── focus-items/
│   │   ├── learning-activity/
│   │   ├── notifications/
│   │   ├── feedback/
│   │   └── system/
│   │
│   └── workers/
│       ├── ai-analysis.worker.ts
│       ├── document-import.worker.ts
│       └── notification.worker.ts
│
├── prisma/
│   ├── schema.prisma
│   └── migrations/
│
├── docker-compose.yml
├── Dockerfile
├── .env.example
└── package.json
```

---

## 7. 各模块职责

### 7.1 Auth 模块

负责 Apple 登录、JWT、刷新 Token、退出登录、账号注销。

App Store 上架要求 Sign in with Apple，这是必须做的。

### 7.2 Users 模块

负责用户资料、头像、昵称、学习身份、学习方向、学习偏好。

### 7.3 Knowledge Base 模块

负责知识库创建、列表、详情、编辑、删除、标签。

### 7.4 Knowledge Items 模块

负责具体知识点、章节、内容段落、关键概念、标签、关联关系。

### 7.5 Document Import 模块

负责上传文件、粘贴文本、链接导入、导入状态、解析进度、导入成功/失败。

这里非常适合用 Redis Queue 做异步处理。

### 7.6 Learning Session 模块

负责一次学习过程：开始学习、结束学习、学习时长、学习内容、学习模式、完成状态。

这是学习活跃图的数据来源之一。

### 7.7 Active Recall 模块

负责主动回忆：回忆问题、用户回答、语音回答、回答提交、回答历史。

### 7.8 AI Analysis 模块

负责提交分析任务、分析状态、AI 分析结果、掌握度、薄弱点、改进建议、下一步建议。

**必须走 Redis Queue 异步处理。**

### 7.9 Focus Items 模块

「待巩固项」——类似 GitHub Issue，但在知习里叫待巩固项。

负责：AI 自动生成待巩固项、用户手动添加、状态（待处理/已加入复习/已完成）、关联知识点、关联学习记录。

### 7.10 Review 模块

负责复习卡片、到期复习、间隔复习计划、复习结果、掌握程度选择、下次复习时间。

### 7.11 Learning Activity 模块

负责学习活跃图：每日学习时长、主动回忆次数、复习次数、AI 分析次数、完成学习闭环次数、学习活跃度等级。

活跃图数据最终写入数据库，Redis 可做临时累计。

### 7.12 Notifications 模块

负责复习提醒、AI 分析完成提醒、学习建议、系统通知、已读/未读。

### 7.13 Feedback 模块

负责 Web 和 App 反馈：用户反馈、问题类型、邮箱、设备、处理状态。

### 7.14 System 模块

健康检查、应用状态、基础运维接口。

---

## 8. 模块优先级

### v0.1 必须实现

```text
auth
users
knowledge-base
knowledge-items
learning-session
active-recall
ai-analysis
focus-items
review
learning-activity
feedback
system
```

### v0.1 暂缓

```text
document-import    — 先手动录入内容
notifications      — 先不做推送
billing            — 暂无付费
subscription       — 暂无订阅
admin-dashboard    — 暂无管理后台
team               — 单人使用
```

---

## 9. API 路由规划

```text
GET    /api/health

POST   /api/auth/apple
POST   /api/auth/refresh
POST   /api/auth/logout

GET    /api/users/me
PATCH  /api/users/me
PATCH  /api/users/me/preferences

GET    /api/knowledge-bases
POST   /api/knowledge-bases
GET    /api/knowledge-bases/:id
PATCH  /api/knowledge-bases/:id
DELETE /api/knowledge-bases/:id
GET    /api/knowledge-bases/:id/items

GET    /api/knowledge-items/:id
POST   /api/knowledge-items

POST   /api/imports
GET    /api/imports/:id/status

POST   /api/learning-sessions
POST   /api/learning-sessions/:id/end

GET    /api/active-recalls
POST   /api/active-recalls/:id/submit

POST   /api/ai-analysis
GET    /api/ai-analysis/:id
GET    /api/ai-analysis/jobs/:jobId/status

GET    /api/focus-items
POST   /api/focus-items
PATCH  /api/focus-items/:id
POST   /api/focus-items/:id/complete

GET    /api/reviews/due
POST   /api/reviews/:id/submit

GET    /api/activity/heatmap
GET    /api/activity/summary

GET    /api/notifications
POST   /api/notifications/:id/read

POST   /api/feedback
```

---

## 10. 关键请求流程

核心异步流程详见 [23. 异步模块额外文件 - AI 分析模块完整流程](#23-异步模块额外文件queue--processor)。

---

## 11. 核心 AI 接口

### POST /api/ai-analysis（提交异步任务）

输入：
```json
{
  "sessionId": "session_001",
  "lessonId": "lesson_001",
  "userInput": "用户写下的答案或笔记",
  "context": {
    "lessonTitle": "材料阅读方法",
    "objectives": ["理解材料结构", "提取关键要点"],
    "keyPoints": ["问题", "原因", "影响", "对策"]
  }
}
```

返回：
```json
{
  "jobId": "job_abc123",
  "status": "pending"
}
```

### GET /api/ai-analysis/jobs/:jobId/status（查询状态）

```json
{
  "jobId": "job_abc123",
  "status": "completed",
  "result": {
    "masteryScore": 3,
    "understandingLevel": "基本理解",
    "summary": "用户能理解主要内容，但要点不完整。",
    "strengths": ["表达清楚"],
    "weakPoints": ["遗漏关键要点", "逻辑层次不足"],
    "suggestions": ["补充第二个要点", "先概括再展开"],
    "reviewNeeded": true,
    "nextAction": "明天重新回答本节主动回忆问题。"
  }
}
```

---

## 12. AI Provider 层设计

```text
AIService
  ├── MiniMaxProvider
  ├── DeepSeekProvider
  ├── OpenAIProvider
  └── MockProvider
```

### MockProvider

v0.1 强烈建议做 MockProvider：
- 没有 API Key 时也能开发
- AI 服务出问题时能测试流程
- 降低开发成本
- 方便录 Demo

### 候选模型

MiniMax / DeepSeek / 通义千问 / OpenAI / Claude / Gemini

### 模型选择原则

1. 中文能力好
2. 成本可控
3. API 稳定
4. 支持结构化输出
5. 速度可以接受
6. 容易接入
7. 可替换

---

## 13. 核心实体/数据模型

```text
User
├── id
├── appleUserId
├── displayName
├── email
├── preferredLanguage
├── learningDirection
├── createdAt
├── lastLoginAt
└── status

KnowledgeBase
├── id
├── userId
├── title
├── description
├── language
├── tags
├── createdAt
└── updatedAt

KnowledgeItem
├── id
├── knowledgeBaseId
├── parentId
├── title
├── content
├── type (chapter/section/concept)
├── objectives
├── keyPoints
├── recallQuestions
├── order
└── estimatedMinutes

DocumentImport
├── id
├── userId
├── knowledgeBaseId
├── sourceType (file/text/link)
├── status (pending/processing/completed/failed)
├── result
├── createdAt
└── completedAt

LearningSession
├── id
├── userId
├── knowledgeItemId
├── startedAt
├── endedAt
├── durationSeconds
├── mode (reading/recall/review)
└── completedAt

ActiveRecall
├── id
├── sessionId
├── question
├── userAnswer
├── answerType (text/voice)
├── submittedAt

AIAnalysis
├── id
├── jobId
├── userId
├── sessionId
├── inputText
├── outputJson
├── masteryScore
├── weakPoints
├── suggestions
├── modelName
├── costEstimate
├── status (pending/processing/completed/failed)
├── createdAt
└── completedAt

FocusItem
├── id
├── userId
├── knowledgeItemId
├── aiAnalysisId
├── title
├── description
├── status (pending/in_review/completed)
├── createdAt
└── completedAt

ReviewTask
├── id
├── userId
├── knowledgeItemId
├── focusItemId
├── reviewType
├── scheduledAt
├── completedAt
├── masteryChoice
├── nextReviewAt
└── status

LearningActivity
├── id
├── userId
├── date
├── durationSeconds
├── recallCount
├── reviewCount
├── analysisCount
├── closedLoopCount
├── activityLevel
└── updatedAt

Notification
├── id
├── userId
├── type
├── title
├── body
├── data (JSON)
├── isRead
└── createdAt

Feedback
├── id
├── userId
├── type
├── content
├── email
├── device
├── status
└── createdAt
```

---

## 14. 掌握度评分（0-5分）

```text
0 = 没有作答 / 无法判断
1 = 基本没理解
2 = 理解较弱
3 = 基本理解
4 = 理解较好
5 = 掌握很好
```

这不是考试分数，是产品内部用于安排复习和学习建议的参考值。

---

## 15. 账号体系

### 第一版登录方式

```text
Sign in with Apple
```

暂不做：微信登录、手机号登录、邮箱密码登录、Google 登录。

### 账号边界

第一版账号只解决：登录、识别用户、保存学习记录、保存 AI 分析结果、保存基础偏好。

暂不做：好友系统、用户主页、头像上传、多登录方式绑定、复杂权限系统。

---

## 16. 部署方案

### 当前服务器

- IP: 81.70.187.179
- 配置: 4 核 4G，40G SSD
- 当前运行: Gitea（端口 3000）+ Nginx
- SSH: ubuntu 用户 + WangDL.pem 密钥

### 推荐部署方式

```text
Nginx                     — 反向代理，已有
api-server (NestJS)       — 端口 3001
postgres / mysql          — 端口 5432 / 3306
redis                     — 端口 6379
worker (BullMQ)           — 同代码仓库，独立进程
gitea                     — 端口 3000，继续保留
```

建议新增 Nginx 配置 `api.longde.cloud` → 反向代理到 NestJS 端口。

### 资源评估

Gitea 当前资源占用很低（内存 ~500MB），剩余 ~3GB 内存、33GB 磁盘足够跑 api-server + PostgreSQL + Redis。

---

## 17. 域名与 Nginx 规划

```text
longde.cloud           官网首页
api.longde.cloud       后端 API（需新增 Nginx 配置）
git.longde.cloud       Gitea 代码仓库（已有）
```

### 待新增 Nginx 配置（api.longde.cloud）

```nginx
server {
    server_name api.longde.cloud;
    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/api.longde.cloud/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.longde.cloud/privkey.pem;
}
```

---

## 18. 技术里程碑

### 里程碑 1：最小后端

- NestJS 项目初始化
- Prisma schema 定义
- PostgreSQL/MySQL 连接
- 用户表、知识库表
- AI MockProvider
- Swagger 文档

### 里程碑 2：真实 AI 接入

- Redis + BullMQ 接入
- AI Provider 抽象
- 接入一个真实模型
- AI 分析异步流程
- Worker 处理 AI 任务

### 里程碑 3：TestFlight 前准备

- Sign in with Apple
- 后端用户身份记录
- 基础错误处理
- Docker Compose 一键部署
- Nginx 反向代理配置

---

## 19. 商业化与支付（未来）

### 支付流程

```text
用户在 iOS App 内付款 → Apple IAP 完成交易 → 后端记录用户权益 → 用户获得权益
```

### 核心

不要让 Apple IAP 成为整个商业系统。真正核心的是：

```text
用户系统 + 订单系统 + 权益系统
```

### 当前暂缓

Apple IAP / 月订阅 / 年订阅 / 免费试用 / 订阅权益系统 / AI 成本精算

---

## 20. 当前技术不做清单

- 微服务 / Kubernetes / 多云部署
- 完整后台管理系统 / CMS
- 完整 RAG / 向量数据库（第一版）
- 多模型自动路由
- AI Agent 工具调用系统
- 支付系统
- 复杂数据分析平台
- Android / Web 学习端

---

## 21. 四层代码分层原则

整体分四层，每一层有明确的职责边界：

```text
Controller 层：接收请求，处理参数，返回响应
Service 层：业务逻辑
Repository 层：数据库读写
Infrastructure 层：Redis、Queue、AI、Storage 等基础设施
```

简单理解：

```text
Controller 不写业务
Service 不直接写复杂 SQL
Repository 不写业务判断
Infrastructure 不知道具体业务，只提供能力
```

一句话纪律：

```text
Controller = 接口    Service = 业务    Repository = 数据库
Infrastructure = 外部能力    Queue/Processor = 异步任务    DTO = 请求/响应结构
```

第一版不要追求所有业务一次写完，但**架构模板必须先统一**。

---

## 22. 模块内部统一模板

每个业务模块都按这个结构来。以 `knowledge-base` 为例：

```text
modules/knowledge-base/
├── knowledge-base.module.ts
├── knowledge-base.controller.ts
├── knowledge-base.service.ts
├── knowledge-base.repository.ts
├── dto/
│   ├── create-knowledge-base.dto.ts
│   ├── update-knowledge-base.dto.ts
│   ├── query-knowledge-base.dto.ts
│   └── knowledge-base-response.dto.ts
├── types/
│   └── knowledge-base.types.ts
└── constants/
    └── knowledge-base.constants.ts
```

### 22.1 xxx.module.ts

```text
作用：
- 注册 controller
- 注册 service
- 注册 repository
- 引入依赖模块
- 导出给其他模块使用
```

```ts
@Module({
  controllers: [KnowledgeBaseController],
  providers: [KnowledgeBaseService, KnowledgeBaseRepository],
  exports: [KnowledgeBaseService],
})
export class KnowledgeBaseModule {}
```

### 22.2 xxx.controller.ts

**只做这些事：**
1. 定义路由
2. 接收参数
3. 调用 service
4. 返回结果

**不要在 Controller 里写业务判断。**

```ts
@Controller('knowledge-bases')
export class KnowledgeBaseController {
  constructor(private readonly service: KnowledgeBaseService) {}

  @Post()
  create(@Body() dto: CreateKnowledgeBaseDto, @CurrentUser() user: UserPayload) {
    return this.service.create(user.id, dto);
  }

  @Get()
  findAll(@CurrentUser() user: UserPayload, @Query() query: QueryKnowledgeBaseDto) {
    return this.service.findAll(user.id, query);
  }

  @Get(':id')
  findOne(@Param('id') id: string, @CurrentUser() user: UserPayload) {
    return this.service.findOne(user.id, id);
  }
}
```

### 22.3 xxx.service.ts

**这里写：**
1. 权限判断
2. 业务规则
3. 调用 repository
4. 调用其他模块 service
5. 调用 queue / AI / Redis
6. 组织返回结果

```ts
@Injectable()
export class KnowledgeBaseService {
  constructor(
    private readonly repository: KnowledgeBaseRepository,
  ) {}

  async create(userId: string, dto: CreateKnowledgeBaseDto) {
    const count = await this.repository.countByUserId(userId);
    if (count >= MAX_KNOWLEDGE_BASE_COUNT) {
      throw new BadRequestException('知识库数量已达到上限');
    }
    return this.repository.create(userId, dto);
  }

  async findOne(userId: string, id: string) {
    const knowledgeBase = await this.repository.findById(id);
    if (!knowledgeBase || knowledgeBase.userId !== userId) {
      throw new NotFoundException('知识库不存在');
    }
    return knowledgeBase;
  }
}
```

### 22.4 xxx.repository.ts

**只写数据库操作，不写复杂业务。**

```ts
@Injectable()
export class KnowledgeBaseRepository {
  constructor(private readonly prisma: PrismaService) {}

  create(userId: string, dto: CreateKnowledgeBaseDto) {
    return this.prisma.knowledgeBase.create({
      data: { userId, name: dto.name, description: dto.description },
    });
  }

  findById(id: string) {
    return this.prisma.knowledgeBase.findUnique({ where: { id } });
  }

  countByUserId(userId: string) {
    return this.prisma.knowledgeBase.count({ where: { userId } });
  }
}
```

### 22.5 dto/

DTO 就是接口输入输出的数据结构。

用途：
1. 校验请求参数
2. 生成 Swagger 文档
3. 让接口结构清楚

```ts
export class CreateKnowledgeBaseDto {
  @ApiProperty({ example: '认知心理学' })
  @IsString()
  @IsNotEmpty()
  name: string;

  @ApiProperty({ example: '系统学习认知心理学基础概念', required: false })
  @IsOptional()
  @IsString()
  description?: string;
}
```

### 22.6 types/

放模块内部类型。如果是数据库模型，不放这里，放 Prisma。

```ts
export type KnowledgeBaseStatus = 'active' | 'archived';

export interface KnowledgeBaseStats {
  itemCount: number;
  completedCount: number;
  reviewDueCount: number;
}
```

### 22.7 constants/

放模块常量。

```ts
export const MAX_KNOWLEDGE_BASE_COUNT = 20;
export const DEFAULT_KNOWLEDGE_BASE_COVER = 'default-blue';
```

---

## 23. 异步模块额外文件（Queue + Processor）

涉及异步任务的模块，需要在标准模板上加 `queue`、`processor`、`jobs`。

以 `ai-analysis` 为例：

```text
modules/ai-analysis/
├── ai-analysis.module.ts
├── ai-analysis.controller.ts
├── ai-analysis.service.ts
├── ai-analysis.repository.ts
├── ai-analysis.queue.ts          ← 封装 BullMQ 队列
├── ai-analysis.processor.ts      ← 消费任务，调用大模型
├── dto/
│   ├── create-ai-analysis.dto.ts
│   ├── query-ai-analysis.dto.ts
│   └── ai-analysis-response.dto.ts
├── jobs/
│   └── ai-analysis.job.ts        ← 队列任务数据结构
├── types/
│   └── ai-analysis.types.ts
└── constants/
    └── ai-analysis.constants.ts
```

### 文件职责

| 文件 | 职责 |
|------|------|
| `controller` | 接收创建分析任务、查询分析结果的接口 |
| `service` | 创建任务、查询状态、组织业务流程 |
| `repository` | 读写 AI 分析任务和分析结果 |
| `queue` | 封装 BullMQ 队列添加任务 |
| `processor` | 真正消费任务，调用大模型 |
| `jobs/xxx.job.ts` | 定义队列任务的数据结构 |

### AI 分析模块完整流程

```text
App 提交回答
  ↓
Controller 接收请求
  ↓
Service 创建分析任务
  ↓
Repository 写入数据库 job 记录
  ↓
Queue 加入 Redis 队列
  ↓
Processor 后台消费任务
  ↓
AI Service 调用大模型
  ↓
Repository 写入分析结果
  ↓
生成待巩固项
  ↓
生成复习计划
  ↓
通知用户
```

---

## 24. AI 层设计：不允许业务模块直接调大模型 SDK

### 原则

后面肯定会换模型、换供应商，所以 AI 不要写死在业务模块里。

**不推荐：**
```ts
// 不要直接在业务 service 里写
await openai.chat.completions.create(...)
```

**应该：**
```text
业务模块 → AiService → 具体 Provider
```

```ts
@Injectable()
export class AiService {
  constructor(private readonly provider: AiProvider) {}

  analyzeActiveRecall(input: ActiveRecallAnalysisInput) {
    return this.provider.generateActiveRecallAnalysis(input);
  }
}
```

这样从 OpenAI 换 DeepSeek、Gemini、Claude，都不用改业务代码。

---

## 25. Infrastructure 层详细拆解

`infrastructure` 是所有模块共用的底层能力。

```text
infrastructure/
├── database/
│   ├── prisma.module.ts
│   └── prisma.service.ts
│
├── redis/
│   ├── redis.module.ts
│   ├── redis.service.ts
│   └── redis.constants.ts
│
├── queue/
│   ├── queue.module.ts
│   ├── queue.constants.ts
│   └── queue.service.ts
│
├── ai/
│   ├── ai.module.ts
│   ├── ai.service.ts
│   ├── ai-provider.interface.ts
│   ├── providers/
│   │   ├── openai.provider.ts
│   │   ├── deepseek.provider.ts
│   │   └── mock-ai.provider.ts
│   └── prompts/
│       ├── active-recall-analysis.prompt.ts
│       └── focus-item-generation.prompt.ts
│
├── storage/
│   ├── storage.module.ts
│   ├── storage.service.ts
│   └── local-storage.provider.ts
│
└── logger/
    ├── logger.module.ts
    └── app-logger.service.ts
```

---

## 26. Common 层详细拆解

```text
common/
├── decorators/
│   └── current-user.decorator.ts
├── guards/
│   ├── jwt-auth.guard.ts
│   └── optional-auth.guard.ts
├── interceptors/
│   └── response.interceptor.ts
├── filters/
│   └── http-exception.filter.ts
├── pipes/
│   └── validation.pipe.ts
├── dto/
│   ├── pagination.dto.ts
│   └── api-response.dto.ts
├── types/
│   ├── user-payload.type.ts
│   └── pagination.type.ts
├── constants/
│   └── app.constants.ts
└── utils/
    ├── date.util.ts
    ├── hash.util.ts
    └── id.util.ts
```

---

## 27. 模块复杂度分级

### 简单模块

结构 `module + controller + service + repository + dto`

适用于：`feedback`、`system`、`notifications`（初版）

### 中等模块

结构 `module + controller + service + repository + dto + types + constants`

适用于：`users`、`knowledge-base`、`knowledge-items`、`learning-session`、`review`、`focus-items`

### 复杂模块

结构 `module + controller + service + repository + queue + processor + jobs + dto + types + constants`

适用于：`ai-analysis`、`document-import`、`notifications`（后期）

---

## 28. 初始化顺序

第一版不要所有业务都写完。先搭基础设施骨架：

```text
 1. infrastructure/database
 2. infrastructure/redis
 3. infrastructure/queue
 4. infrastructure/ai
 5. common
 6. system/health
 7. auth skeleton
 8. users skeleton
 9. knowledge-base skeleton
10. ai-analysis skeleton
```

这样就够开始开发。


