1198 lines
27 KiB
Markdown
Raw Normal View History

---
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.cloudNestJS + Prisma + MySQL + Docker + Nginx + SSL
**编译**`npx tsc --noEmit` 0 errors
**全局守卫**JwtAuthGuard → RolesGuardUSER/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
ORMPrisma
数据库PostgreSQL推荐MySQL 亦可
缓存/队列Redis
队列系统BullMQ
接口文档Swagger / OpenAPI
文件存储:本地开发先本地存,后期接对象存储
AIProvider 抽象 + 一个真实模型 + 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 核 4G40G 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 任务
### 里程碑 3TestFlight 前准备
- 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
```
这样就够开始开发。