1186 lines
26 KiB
Markdown
1186 lines
26 KiB
Markdown
|
|
---
|
|||
|
|
source: startup-plan/个人开发者创业 v0.1 + 完全版 + AI回答.md 架构深化方案
|
|||
|
|
updated: 2026-05-09
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 知习 api-server 后端架构规划
|
|||
|
|
|
|||
|
|
> 「知习」是一款 AI-first 的系统化学习 App。后端需要同时服务 iOS App 和 Web 官网。
|
|||
|
|
> 核心功能包括知识库、主动回忆、AI 学习分析、间隔复习、待巩固项、学习活跃记录、消息通知和反馈。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 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
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这样就够开始开发。
|
|||
|
|
|
|||
|
|
|