docs: 更新AI架构设计、后端待办清单,归档已完成文档
- 更新AI架构设计文档链接 - 整理后端待完成事项清单(12 Repository迁Prisma、AI架构、JwtAuthGuard等) - 归档已完成:AI架构决策清单 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
00b7b3613c
commit
69dbb72777
614
开发计划/api-server/[进行中]-后端待完成事项清单.md
Normal file
614
开发计划/api-server/[进行中]-后端待完成事项清单.md
Normal file
@ -0,0 +1,614 @@
|
|||||||
|
# 知习后端待完成事项清单
|
||||||
|
|
||||||
|
> 按业务开发顺序排列。**2026-05-16 更新:AI 基础设施完成,12 个 Repository 全部迁到 Prisma。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 登录 / 认证模块 Auth
|
||||||
|
|
||||||
|
这是第一优先级。因为后面所有数据都要绑定 `userId`。
|
||||||
|
|
||||||
|
### 要做的接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /api/auth/dev-login
|
||||||
|
POST /api/auth/apple
|
||||||
|
POST /api/auth/refresh
|
||||||
|
POST /api/auth/logout
|
||||||
|
GET /api/users/me
|
||||||
|
PATCH /api/users/me
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第一阶段先做
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /api/auth/dev-login
|
||||||
|
POST /api/auth/refresh
|
||||||
|
GET /api/users/me
|
||||||
|
```
|
||||||
|
|
||||||
|
Apple 登录可以随后接入,但后端结构要先预留。
|
||||||
|
|
||||||
|
### 需要的表
|
||||||
|
|
||||||
|
```text
|
||||||
|
users
|
||||||
|
auth_accounts
|
||||||
|
refresh_tokens
|
||||||
|
```
|
||||||
|
|
||||||
|
### 核心逻辑
|
||||||
|
|
||||||
|
```text
|
||||||
|
dev-login 创建 / 查找用户
|
||||||
|
生成 accessToken
|
||||||
|
生成 refreshToken
|
||||||
|
refreshToken hash 入库
|
||||||
|
/users/me 返回当前用户
|
||||||
|
refresh 接口刷新 token
|
||||||
|
logout 撤销 refreshToken
|
||||||
|
```
|
||||||
|
|
||||||
|
### Apple 登录需要什么
|
||||||
|
|
||||||
|
后端不需要 iOS 证书,只需要:
|
||||||
|
|
||||||
|
```text
|
||||||
|
APPLE_BUNDLE_ID=cloud.longde.AIStudyApp
|
||||||
|
APPLE_ISSUER=https://appleid.apple.com
|
||||||
|
APPLE_JWKS_URL=https://appleid.apple.com/auth/keys
|
||||||
|
```
|
||||||
|
|
||||||
|
Apple 登录接口核心参数:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"identityToken": "eyJ..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
可选参数:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"authorizationCode": "...",
|
||||||
|
"userIdentifier": "...",
|
||||||
|
"email": "...",
|
||||||
|
"fullName": {
|
||||||
|
"givenName": "...",
|
||||||
|
"familyName": "..."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 权限系统 Permission
|
||||||
|
|
||||||
|
登录后马上要做最小权限。
|
||||||
|
|
||||||
|
### 第一版权限规则
|
||||||
|
|
||||||
|
```text
|
||||||
|
普通用户只能访问自己的资源
|
||||||
|
所有用户资源必须校验 userId
|
||||||
|
普通用户不能访问 /api/admin/*
|
||||||
|
知识库默认 PRIVATE
|
||||||
|
创建知识库的人就是 owner
|
||||||
|
```
|
||||||
|
|
||||||
|
### 平台角色
|
||||||
|
|
||||||
|
```text
|
||||||
|
USER
|
||||||
|
ADMIN
|
||||||
|
SUPER_ADMIN
|
||||||
|
```
|
||||||
|
|
||||||
|
### 后期资源角色
|
||||||
|
|
||||||
|
```text
|
||||||
|
OWNER
|
||||||
|
EDITOR
|
||||||
|
VIEWER
|
||||||
|
```
|
||||||
|
|
||||||
|
第一版可以先不做协作者,只做:
|
||||||
|
|
||||||
|
```text
|
||||||
|
knowledgeBase.userId === currentUser.id
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 用户模块 Users
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/users/me
|
||||||
|
PATCH /api/users/me
|
||||||
|
DELETE /api/users/me
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段
|
||||||
|
|
||||||
|
```text
|
||||||
|
id
|
||||||
|
email
|
||||||
|
nickname
|
||||||
|
avatarUrl
|
||||||
|
role
|
||||||
|
status
|
||||||
|
onboardingCompleted
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
```
|
||||||
|
|
||||||
|
这个模块服务于:
|
||||||
|
|
||||||
|
```text
|
||||||
|
App 启动恢复登录态
|
||||||
|
我的页
|
||||||
|
会员权益
|
||||||
|
学习统计
|
||||||
|
后台用户管理
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 知识库模块 KnowledgeBase
|
||||||
|
|
||||||
|
登录通了以后做知识库。
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/knowledge-bases
|
||||||
|
POST /api/knowledge-bases
|
||||||
|
GET /api/knowledge-bases/:id
|
||||||
|
PATCH /api/knowledge-bases/:id
|
||||||
|
DELETE /api/knowledge-bases/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段
|
||||||
|
|
||||||
|
```text
|
||||||
|
id
|
||||||
|
userId
|
||||||
|
title
|
||||||
|
description
|
||||||
|
coverColor
|
||||||
|
visibility
|
||||||
|
status
|
||||||
|
itemCount
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
deletedAt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 第一版规则
|
||||||
|
|
||||||
|
```text
|
||||||
|
默认 PRIVATE
|
||||||
|
只允许用户操作自己的知识库
|
||||||
|
暂时不做公开、分享、协作者
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 知识点模块 KnowledgeItem
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/knowledge-bases/:knowledgeBaseId/items
|
||||||
|
POST /api/knowledge-bases/:knowledgeBaseId/items
|
||||||
|
GET /api/knowledge-items/:id
|
||||||
|
PATCH /api/knowledge-items/:id
|
||||||
|
DELETE /api/knowledge-items/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段
|
||||||
|
|
||||||
|
```text
|
||||||
|
id
|
||||||
|
userId
|
||||||
|
knowledgeBaseId
|
||||||
|
title
|
||||||
|
content
|
||||||
|
summary
|
||||||
|
tags
|
||||||
|
sourceType
|
||||||
|
masteryLevel
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
deletedAt
|
||||||
|
```
|
||||||
|
|
||||||
|
第一版先支持:
|
||||||
|
|
||||||
|
```text
|
||||||
|
手动创建知识点
|
||||||
|
手动编辑知识点
|
||||||
|
```
|
||||||
|
|
||||||
|
不要一开始做 PDF 解析和 AI 自动拆分。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 学习会话模块 LearningSession
|
||||||
|
|
||||||
|
表示一次学习过程。
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /api/learning-sessions
|
||||||
|
GET /api/learning-sessions/:id
|
||||||
|
POST /api/learning-sessions/:id/complete
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段
|
||||||
|
|
||||||
|
```text
|
||||||
|
id
|
||||||
|
userId
|
||||||
|
knowledgeBaseId
|
||||||
|
status
|
||||||
|
startedAt
|
||||||
|
completedAt
|
||||||
|
durationSeconds
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. 主动回忆模块 ActiveRecall
|
||||||
|
|
||||||
|
这是用户主动输出的核心。
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /api/active-recall/answers
|
||||||
|
GET /api/active-recall/answers/:id
|
||||||
|
GET /api/knowledge-items/:id/active-recall/answers
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段
|
||||||
|
|
||||||
|
```text
|
||||||
|
id
|
||||||
|
userId
|
||||||
|
knowledgeItemId
|
||||||
|
learningSessionId
|
||||||
|
mode
|
||||||
|
answerText
|
||||||
|
durationSeconds
|
||||||
|
createdAt
|
||||||
|
```
|
||||||
|
|
||||||
|
`mode` 预留:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ACTIVE_RECALL
|
||||||
|
FEYNMAN
|
||||||
|
RETRIEVAL_PRACTICE
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. AI 分析模块 AIAnalysis
|
||||||
|
|
||||||
|
这是知习核心差异化模块。
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
POST /api/ai-analysis/active-recall
|
||||||
|
GET /api/ai-analysis/:id
|
||||||
|
GET /api/active-recall/answers/:answerId/analysis
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段
|
||||||
|
|
||||||
|
```text
|
||||||
|
id
|
||||||
|
userId
|
||||||
|
knowledgeItemId
|
||||||
|
activeRecallAnswerId
|
||||||
|
score
|
||||||
|
masteryLevel
|
||||||
|
summary
|
||||||
|
strengths
|
||||||
|
weaknesses
|
||||||
|
missingKeyPoints
|
||||||
|
misconceptions
|
||||||
|
rawResult
|
||||||
|
promptVersion
|
||||||
|
model
|
||||||
|
createdAt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 输出结构示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"score": 72,
|
||||||
|
"masteryLevel": "partial",
|
||||||
|
"summary": "用户理解了核心定义,但缺少应用场景。",
|
||||||
|
"missingKeyPoints": [],
|
||||||
|
"misconceptions": [],
|
||||||
|
"focusItems": [],
|
||||||
|
"reviewSuggestion": {
|
||||||
|
"shouldReview": true,
|
||||||
|
"intervalDays": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 待巩固项模块 FocusItem
|
||||||
|
|
||||||
|
AI 分析后生成的薄弱点。
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/focus-items
|
||||||
|
GET /api/focus-items/today
|
||||||
|
GET /api/focus-items/:id
|
||||||
|
PATCH /api/focus-items/:id
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段
|
||||||
|
|
||||||
|
```text
|
||||||
|
id
|
||||||
|
userId
|
||||||
|
knowledgeBaseId
|
||||||
|
knowledgeItemId
|
||||||
|
aiAnalysisId
|
||||||
|
title
|
||||||
|
description
|
||||||
|
reason
|
||||||
|
priority
|
||||||
|
status
|
||||||
|
createdAt
|
||||||
|
resolvedAt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 状态
|
||||||
|
|
||||||
|
```text
|
||||||
|
OPEN
|
||||||
|
REVIEWING
|
||||||
|
RESOLVED
|
||||||
|
DISMISSED
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 复习模块 Review
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/reviews/due
|
||||||
|
GET /api/reviews/cards/:id
|
||||||
|
POST /api/reviews/cards/:id/answer
|
||||||
|
POST /api/reviews/cards/:id/skip
|
||||||
|
```
|
||||||
|
|
||||||
|
### 表
|
||||||
|
|
||||||
|
```text
|
||||||
|
review_cards
|
||||||
|
review_attempts
|
||||||
|
```
|
||||||
|
|
||||||
|
第一版复习算法可以简单:
|
||||||
|
|
||||||
|
```text
|
||||||
|
薄弱 → 1 天后
|
||||||
|
一般 → 3 天后
|
||||||
|
掌握 → 7 天后
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. 学习活跃模块 LearningActivity
|
||||||
|
|
||||||
|
### 接口
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/learning-activity/summary
|
||||||
|
GET /api/learning-activity/daily
|
||||||
|
POST /api/learning-activity/events
|
||||||
|
```
|
||||||
|
|
||||||
|
### 事件
|
||||||
|
|
||||||
|
```text
|
||||||
|
KNOWLEDGE_BASE_CREATED
|
||||||
|
KNOWLEDGE_ITEM_CREATED
|
||||||
|
LEARNING_SESSION_STARTED
|
||||||
|
ACTIVE_RECALL_SUBMITTED
|
||||||
|
AI_ANALYSIS_COMPLETED
|
||||||
|
FOCUS_ITEM_CREATED
|
||||||
|
REVIEW_CARD_CREATED
|
||||||
|
REVIEW_COMPLETED
|
||||||
|
LEARNING_SESSION_COMPLETED
|
||||||
|
```
|
||||||
|
|
||||||
|
用于:
|
||||||
|
|
||||||
|
```text
|
||||||
|
连续学习天数
|
||||||
|
最近 7 天学习趋势
|
||||||
|
分析首页
|
||||||
|
我的页统计
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. AI 基础设施模块 ✅ 已完成
|
||||||
|
|
||||||
|
包括:
|
||||||
|
|
||||||
|
```text
|
||||||
|
✅ AIGateway — AiGatewayService(统一入口、选模型、JSON容错、超时重试)
|
||||||
|
✅ PromptTemplate — PromptTemplateService(key + version 注册)
|
||||||
|
✅ AIUsageLog — AiUsageLogService + AiCostCalculatorService
|
||||||
|
✅ AIWorkflow — ActiveRecallAnalysisWorkflow(第一个 Workflow)
|
||||||
|
⏳ AIQuota — 待实现
|
||||||
|
```
|
||||||
|
|
||||||
|
### 已完成文件
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/modules/ai/
|
||||||
|
├── ai.module.ts
|
||||||
|
├── ai.controller.ts
|
||||||
|
├── model-router.ts
|
||||||
|
├── gateway/ai-gateway.service.ts
|
||||||
|
├── gateway/ai-gateway.types.ts
|
||||||
|
├── providers/ai-provider.interface.ts
|
||||||
|
├── providers/mock-ai.provider.ts
|
||||||
|
├── providers/deepseek.provider.ts
|
||||||
|
├── providers/minimax.provider.ts
|
||||||
|
├── prompts/prompt-template.service.ts
|
||||||
|
├── prompts/active-recall-analysis.prompt.ts
|
||||||
|
├── prompts/schemas/active-recall-analysis.schema.ts
|
||||||
|
├── usage/ai-cost-calculator.service.ts
|
||||||
|
├── usage/ai-usage-log.service.ts
|
||||||
|
└── workflows/active-recall-analysis.workflow.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数据库
|
||||||
|
|
||||||
|
```text
|
||||||
|
✅ AiUsageLog 模型已加入 prisma schema
|
||||||
|
⚠️ db push 待 SSH 隧道连通
|
||||||
|
```
|
||||||
|
|
||||||
|
### 旧代码已清理
|
||||||
|
|
||||||
|
```text
|
||||||
|
❌ src/infrastructure/ai/ 已删除
|
||||||
|
✅ ai-analysis 模块已改用新 AiGatewayService
|
||||||
|
✅ active-recall 模块提交答案自动触发分析
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. Repository 迁移 Map → Prisma ✅ 全部完成
|
||||||
|
|
||||||
|
> **2026-05-16**:12 个业务 repository 全部从 `Map<string, T>` / `Array<T>` 迁到 Prisma。
|
||||||
|
|
||||||
|
| 批次 | 模块 | Repository | 备注 |
|
||||||
|
|------|------|-----------|------|
|
||||||
|
| 第 1 批 | KnowledgeBase / KnowledgeItems | ✅ Prisma | 核心知识体系 |
|
||||||
|
| 第 2 批 | ActiveRecall / LearningSession / AiAnalysis / FocusItems | ✅ Prisma | 学习闭环主干 |
|
||||||
|
| 第 3 批 | Review / LearningActivity | ✅ Prisma | 复习和统计 |
|
||||||
|
| 第 4 批 | DocumentImport / Notifications / Waitlist / Feedback | ✅ Prisma | 辅助模块 |
|
||||||
|
|
||||||
|
### 改动范围
|
||||||
|
|
||||||
|
```text
|
||||||
|
12 个 repository 重写(注入 PrismaService、删除 Map/Array、删除 generateShortId)
|
||||||
|
5 个 service 微调(方法加 userId 参数)
|
||||||
|
4 个 controller 加 @CurrentUser()(FocusItems / Review / LearningActivity / Notifications)
|
||||||
|
1 个 Prisma schema 新增模型(WaitlistEntry)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 统一变更
|
||||||
|
|
||||||
|
```text
|
||||||
|
- 删除所有 generateShortId() 调用,改用 Prisma @default(cuid())
|
||||||
|
- 删除所有 OnModuleInit 种子假数据
|
||||||
|
- 所有查询方法加 userId 过滤
|
||||||
|
- 复杂字段(数组/对象)存 Prisma Json 字段
|
||||||
|
```
|
||||||
|
|
||||||
|
这个后面会支撑:
|
||||||
|
|
||||||
|
```text
|
||||||
|
AI 成本计算
|
||||||
|
会员额度
|
||||||
|
后台成本看板
|
||||||
|
模型切换
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 后端阶段顺序(已完成标记 ✅)
|
||||||
|
|
||||||
|
```text
|
||||||
|
✅ 阶段 1:登录和身份(已完成)
|
||||||
|
✅ Auth(dev-login / apple / refresh / logout)
|
||||||
|
✅ Users(/users/me + UsersRepository 唯一接 Prisma)
|
||||||
|
✅ Permission(JwtAuthGuard 已全局注册)
|
||||||
|
|
||||||
|
✅ 阶段 2:知识系统(数据库层已完成)
|
||||||
|
✅ KnowledgeBase → Prisma
|
||||||
|
✅ KnowledgeItem → Prisma
|
||||||
|
⏳ 知识导入 Workflow
|
||||||
|
|
||||||
|
✅ 阶段 3:学习闭环(数据库层已完成)
|
||||||
|
✅ LearningSession → Prisma
|
||||||
|
✅ ActiveRecall → Prisma(提交答案自动触发 AI 分析)
|
||||||
|
✅ AiAnalysis → Prisma(ActiveRecallAnalysisWorkflow)
|
||||||
|
✅ FocusItem → Prisma
|
||||||
|
✅ Review → Prisma
|
||||||
|
✅ LearningActivity → Prisma
|
||||||
|
|
||||||
|
✅ 阶段 4:AI 基础设施(已完成)
|
||||||
|
✅ AIGateway(三层容错 + 超时重试)
|
||||||
|
✅ PromptTemplate(key + version)
|
||||||
|
✅ AIUsageLog + CostCalculator
|
||||||
|
✅ ActiveRecallAnalysisWorkflow
|
||||||
|
✅ AiModule(15 文件三层架构)
|
||||||
|
⏳ AIQuota(待实现)
|
||||||
|
|
||||||
|
✅ 阶段 5:文件导入(数据库层已完成)
|
||||||
|
✅ DocumentImport → Prisma
|
||||||
|
⏳ Files / Storage 真实接入
|
||||||
|
⏳ KnowledgeGeneration Workflow
|
||||||
|
|
||||||
|
⏳ 阶段 6:商业化(未开始)
|
||||||
|
Plans / Membership / Subscription / UsageLimit
|
||||||
|
|
||||||
|
⏳ 阶段 7:后台和运营(部分完成)
|
||||||
|
✅ Feedback → Prisma
|
||||||
|
✅ Waitlist → Prisma
|
||||||
|
✅ Notifications → Prisma
|
||||||
|
⏳ Admin / AI Cost Dashboard / Audit Logs
|
||||||
|
|
||||||
|
⏳ 阶段 8:客服和帮助中心(未开始)
|
||||||
|
SupportTicket / Dify / HelpCenter
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 当前最应该推进的 TODO
|
||||||
|
|
||||||
|
```text
|
||||||
|
✅ 1. 建 users / auth_accounts / refresh_tokens 表
|
||||||
|
✅ 2. 做 POST /api/auth/dev-login
|
||||||
|
✅ 3. 做 TokenService:accessToken / refreshToken
|
||||||
|
✅ 4. 做 POST /api/auth/refresh
|
||||||
|
✅ 5. 做 JwtAuthGuard
|
||||||
|
✅ 6. 做 CurrentUser 装饰器
|
||||||
|
✅ 7. 做 GET /api/users/me
|
||||||
|
✅ 8. 12 个 Repository Map → Prisma
|
||||||
|
✅ 9. AI 三层架构落地(Provider → Gateway → Workflow)
|
||||||
|
✅ 10. 接 POST /api/auth/apple
|
||||||
|
✅ 11. 全局 JwtAuthGuard(所有 controller)
|
||||||
|
⏳ 12. 更多 AI Workflow(知识导入、费曼分析、复习卡片生成)
|
||||||
|
⏳ 13. AI 联调 + Prompt 调优
|
||||||
|
⏳ 14. iOS 集成
|
||||||
|
```
|
||||||
360
开发计划/api-server/已完成/[已完成]-当前状态与决策清单.md
Normal file
360
开发计划/api-server/已完成/[已完成]-当前状态与决策清单.md
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
# 知习后端:当前状态 & 需要你处理的决策和任务
|
||||||
|
|
||||||
|
> 基于代码审计生成。**2026-05-16 已确认所有决策,执行中。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 一、当前代码状态总览
|
||||||
|
|
||||||
|
## 已完成(真实可用的)
|
||||||
|
|
||||||
|
| 模块 | 状态 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| Auth 控制器 + 服务 | 真实 | dev-login / apple / refresh / logout 全部写好了 |
|
||||||
|
| TokenService | 真实 | JWT accessToken + crypto refreshToken + hash 入库 |
|
||||||
|
| JwtAuthGuard | 真实 | 可正常验证 Bearer token |
|
||||||
|
| CurrentUser 装饰器 | 真实 | 从 request.user 提取当前用户 |
|
||||||
|
| AppleAuthService | 真实+兜底 | BUNDLE_ID 有值就走真实 JWKS 验证,没值走 mock |
|
||||||
|
| UsersRepository | 真实 | **唯一接 Prisma 的 repository** |
|
||||||
|
| PrismaService | 真实 | 连接 MySQL |
|
||||||
|
| Prisma Schema | 完整 | 所有表都定义了(User, KnowledgeBase, KnowledgeItem, 等 30+ 个 model) |
|
||||||
|
| AppModule | 完整 | 所有模块都注册了 |
|
||||||
|
| 基础设施骨架 | 有 | Redis/Storage/Logger/Queue 模块都创建了 |
|
||||||
|
| 全局异常过滤器 | 有 | |
|
||||||
|
| 统一响应拦截器 | 有 | |
|
||||||
|
| DTO 校验管道 | 有 | |
|
||||||
|
|
||||||
|
| Apple 登录配置 | 有 | 但缺 `APPLE_BUNDLE_ID` |
|
||||||
|
|
||||||
|
## 仍在使用内存 Map(没有接数据库)
|
||||||
|
|
||||||
|
| 模块 | 存储方式 | 严重程度 |
|
||||||
|
|------|----------|----------|
|
||||||
|
| KnowledgeBaseRepository | `new Map()` | 高 |
|
||||||
|
| KnowledgeItemsRepository | `new Map()` | 高 |
|
||||||
|
| ActiveRecallRepository | `new Map()` × 2 | 高 |
|
||||||
|
| AiAnalysisRepository | `new Map()` × 2 | 高 |
|
||||||
|
| FocusItemsRepository | `new Map()` | 高 |
|
||||||
|
| ReviewRepository | `new Map()` × 2 | 高 |
|
||||||
|
| LearningSessionRepository | `new Map()` | 高 |
|
||||||
|
| LearningActivityRepository | `new Map()` | 中 |
|
||||||
|
| DocumentImportRepository | `new Map()` | 中 |
|
||||||
|
| QueueService | `new Map()` | 中 |
|
||||||
|
|
||||||
|
## AI 模块 ✅ 已升级为三层架构
|
||||||
|
|
||||||
|
| 组件 | 状态 |
|
||||||
|
|------|------|
|
||||||
|
| AiProvider 接口 | ✅ 统一 generate() + signal |
|
||||||
|
| MockAiProvider | ✅ 永久保留 |
|
||||||
|
| DeepSeekProvider | ✅ OpenAI 兼容协议 |
|
||||||
|
| MiniMaxProvider | ✅ OpenAI 兼容协议(Coding Plan) |
|
||||||
|
| ModelRouter | ✅ cheap / primary / strong 三档 |
|
||||||
|
| AiGatewayService | ✅ 统一入口 + JSON容错 + 超时重试 |
|
||||||
|
| PromptTemplateService | ✅ key + version 注册 |
|
||||||
|
| ActiveRecallAnalysisWorkflow | ✅ 第一个 Workflow |
|
||||||
|
| AiUsageLog + CostCalculator | ✅ 已加入 schema |
|
||||||
|
| 旧 infrastructure/ai | ❌ 已删除 |
|
||||||
|
| 新 AiModule | ✅ `src/modules/ai/` 14 个文件 |
|
||||||
|
|
||||||
|
详见 `startup-plan/技术设计/api-server/[已完成]-AI架构决策清单.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 二、需要你决策的事项
|
||||||
|
|
||||||
|
这些都是我无法替你决定的问题,每一个都会影响后续开发方向。
|
||||||
|
|
||||||
|
## 决策 1:MySQL 数据库 —— 当前什么状态?
|
||||||
|
|
||||||
|
`.env` 里配置了:
|
||||||
|
```
|
||||||
|
DATABASE_URL="mysql://zhixi_user:Zhixi@2026!App@localhost:3306/zhixi"
|
||||||
|
```
|
||||||
|
|
||||||
|
需要确认:
|
||||||
|
- [ ] MySQL 服务是否在运行?
|
||||||
|
- [ ] 数据库 `zhixi` 是否已创建?
|
||||||
|
- [ ] 数据库里是否已有数据?(如果之前跑过可能会有旧表)
|
||||||
|
- [ ] Prisma schema 和实际数据库是否一致?
|
||||||
|
|
||||||
|
**为什么重要**:Prisma schema 已定义 30+ 张表,但没有 migrations 目录。第一次 `prisma migrate dev` 会生成初始 migration。如果数据库已有表结构(非 Prisma 迁移创建的),需要额外处理。
|
||||||
|
|
||||||
|
**建议方案**:
|
||||||
|
- 如果是空库 → 直接 `prisma migrate dev` 生成初始迁移
|
||||||
|
- 如果已有 Prisma 创建的表 → 先 `prisma db pull` 拉取现有结构,再 `prisma migrate dev`
|
||||||
|
- 如果 MySQL 没启动 → 先解决 MySQL 启动问题
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 决策 2:BigInt ID 问题 —— 现在不改,后面全是雷
|
||||||
|
|
||||||
|
Prisma schema 所有主键都是 `BigInt @default(autoincrement())`。
|
||||||
|
|
||||||
|
但是:
|
||||||
|
- JavaScript/JSON 不支持 64 位整数
|
||||||
|
- Auth 模块里已经出现大量 `BigInt(userId)` / `String(user.id)` 的转换
|
||||||
|
- KnowledgeBase 的 in-memory 版本用的是 `string` ID
|
||||||
|
- JWT payload 里的 `sub` 是 `String(user.id)`
|
||||||
|
- 这意味着:**内存版本和数据库版本的 ID 类型不统一**
|
||||||
|
|
||||||
|
**问题场景**:
|
||||||
|
```
|
||||||
|
数据库返回: user.id = 9007199254740993n (BigInt, 超出 JS 安全范围)
|
||||||
|
JSON.stringify → "9007199254740992" (精度丢失!)
|
||||||
|
```
|
||||||
|
|
||||||
|
**选项**:
|
||||||
|
- A) 换 `String @id @default(cuid())` —— 最安全,推荐,但需要改 schema 和所有关联代码
|
||||||
|
- B) 换 `Int @default(autoincrement())` —— 简单但有上限(21 亿),够用但不够好看
|
||||||
|
- C) 保持 `BigInt` —— 不改,但要全局统一序列化(`JSON.stringify` 不能直接用),所有 repository 都要转 string
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 决策 3:AI Provider —— 第一个接哪个?
|
||||||
|
|
||||||
|
目前 AI 是纯 mock,返回固定 JSON。
|
||||||
|
|
||||||
|
**选项**:
|
||||||
|
- A) **DeepSeek** —— 便宜,中文强,适合预算有限的独立开发者
|
||||||
|
- B) **OpenAI (GPT-4o)** —— 贵但生态好,SDK 成熟
|
||||||
|
- C) **Anthropic Claude** —— 长上下文优秀,适合大段知识分析
|
||||||
|
- D) **MiniMax / 豆包 / 通义千问** —— 国内合规,需要 ICP 备案才能用
|
||||||
|
|
||||||
|
**连锁影响**:
|
||||||
|
- 决定了 AIGateway 第一个 provider 实现
|
||||||
|
- 决定了 Prompt 模板的调试环境
|
||||||
|
- 决定了成本(需要 API key 和充值)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 决策 4:Redis 状态 —— 需要现在启动吗?
|
||||||
|
|
||||||
|
`.env` 里配置了 Redis 连接,`AiAnalysisService` 里用了 Redis(限流、任务状态、锁)。
|
||||||
|
|
||||||
|
但是这些功能**不启动 Redis 也能绕过去**——限流可以先去掉,任务状态可以先放内存。
|
||||||
|
|
||||||
|
**建议**:先不管 Redis,集中精力把数据库层搞定。限流等功能后面补。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 决策 5:Prisma Schema 需要调整吗?
|
||||||
|
|
||||||
|
现在 schema 非常完整(30+ 张表),但很多是远期才用的表:
|
||||||
|
|
||||||
|
| 近期需要的表 | 远期才用的表 |
|
||||||
|
|-------------|-------------|
|
||||||
|
| users | UserProfile |
|
||||||
|
| auth_accounts | UserPreference |
|
||||||
|
| refresh_tokens | UserConsent |
|
||||||
|
| knowledge_bases | KnowledgeItemRelation |
|
||||||
|
| knowledge_items | Tag (如果第一版不做标签) |
|
||||||
|
| active_recall_questions | KnowledgeItemTag |
|
||||||
|
| active_recall_answers | UploadedFile |
|
||||||
|
| ai_analysis_jobs | DocumentImport |
|
||||||
|
| ai_analysis_results | LearningRecord |
|
||||||
|
| focus_items | ReviewPlan |
|
||||||
|
| review_cards | AppChangelog |
|
||||||
|
| review_logs | DailyLearningActivity |
|
||||||
|
| learning_sessions | Notification |
|
||||||
|
| feedback | ... |
|
||||||
|
|
||||||
|
**选项**:
|
||||||
|
- A) 保持全部 schema,一次迁移创建所有表(简单但有大量空表)
|
||||||
|
- B) 先只迁移近期需要的表(干净但需要改 schema 文件)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 决策 6:Apple 登录什么时候接?
|
||||||
|
|
||||||
|
代码已写好,AppleAuthService 带了 mock 兜底。
|
||||||
|
|
||||||
|
问题:
|
||||||
|
- `APPLE_BUNDLE_ID` 为空 → Apple 登录走 mock
|
||||||
|
- 真正的 Apple ID token 验证需要 Apple Developer 账号
|
||||||
|
- 这取决于你的 Apple Developer 审核进度
|
||||||
|
|
||||||
|
**当前行为**:即使 APPLE_BUNDLE_ID 为空,Apple 登录接口也能用,只是不走真实验证。这对开发阶段来说够了。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 三、当前无法处理的事情
|
||||||
|
|
||||||
|
这些事情需要外部条件满足才能推进:
|
||||||
|
|
||||||
|
| 阻塞项 | 原因 | 谁来解决 | 预计时间 |
|
||||||
|
|--------|------|----------|----------|
|
||||||
|
| 11 个 Repository 接 Prisma | 待逐一迁移 | 开发 | — |
|
||||||
|
| AiUsageLog 表建到服务器 | SSH 隧道未连通 | 你 | — |
|
||||||
|
| Apple 登录真实验证 | 需要 APPLE_BUNDLE_ID | Apple 审核 | 不确定 |
|
||||||
|
| BullMQ 队列 | 需要 Redis | 可推迟 | — |
|
||||||
|
| 文件上传 (COS/S3) | 需要选存储服务 | 可推迟 | — |
|
||||||
|
| iOS Keychain / AppSession | 前端配合 | iOS 开发时 | — |
|
||||||
|
|
||||||
|
## ✅ 已解决的阻塞项
|
||||||
|
|
||||||
|
| 阻塞项 | 状态 |
|
||||||
|
|--------|------|
|
||||||
|
| Prisma 首次迁移 | ✅ db push 完成,所有表已建 |
|
||||||
|
| 真实 AI 分析 | ✅ 三层架构已落地,Mock/DeepSeek/MiniMax 三 Provider |
|
||||||
|
| BigInt ID 方案 | ✅ 全部改为 String cuid() |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 四、分阶段可执行任务清单
|
||||||
|
|
||||||
|
## 阶段 1:地基打通(现在就要做)
|
||||||
|
|
||||||
|
这些是最紧迫的,必须在写新功能之前完成。
|
||||||
|
|
||||||
|
### 任务 1.1:确认数据库连接 + 跑通首次迁移
|
||||||
|
|
||||||
|
**前置条件**:决策 1
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 确认 MySQL 服务已启动
|
||||||
|
2. 确认 zhixi 数据库已创建(不存在则 CREATE DATABASE zhixi)
|
||||||
|
3. 根据决策 2 调整 Prisma schema 的 ID 类型
|
||||||
|
4. 运行 prisma migrate dev --name init
|
||||||
|
5. 验证生成的 migration SQL 无误
|
||||||
|
6. 运行 prisma generate
|
||||||
|
7. 启动服务,调 dev-login 验证 auth 模块正常工作
|
||||||
|
```
|
||||||
|
|
||||||
|
### 任务 1.2:解决 BigInt ID 方案
|
||||||
|
|
||||||
|
**前置条件**:决策 2
|
||||||
|
|
||||||
|
如果是方案 A(cuid),需要改:
|
||||||
|
- `schema.prisma` 所有 `BigInt @default(autoincrement())` → `String @id @default(cuid())`
|
||||||
|
- `AuthService` 里的 `BigInt(userId)` 转换去掉
|
||||||
|
- `UsersRepository` 里的 `BigInt(userId)` 转换去掉
|
||||||
|
- `JwtAuthGuard` 的 `request.user` 类型
|
||||||
|
|
||||||
|
### 任务 1.3:把所有 Repository 从 Map 迁到 Prisma
|
||||||
|
|
||||||
|
**前置条件**:任务 1.1 + 1.2
|
||||||
|
|
||||||
|
按优先级迁:
|
||||||
|
```text
|
||||||
|
第一批(核心业务):
|
||||||
|
KnowledgeBaseRepository → prisma
|
||||||
|
KnowledgeItemsRepository → prisma
|
||||||
|
ActiveRecallRepository → prisma
|
||||||
|
|
||||||
|
第二批(学习闭环):
|
||||||
|
LearningSessionRepository → prisma
|
||||||
|
AiAnalysisRepository → prisma
|
||||||
|
FocusItemsRepository → prisma
|
||||||
|
ReviewRepository → prisma
|
||||||
|
|
||||||
|
第三批(辅助):
|
||||||
|
LearningActivityRepository → prisma
|
||||||
|
DocumentImportRepository → prisma
|
||||||
|
```
|
||||||
|
|
||||||
|
每个 repository 改造模板:
|
||||||
|
```text
|
||||||
|
1. 注入 PrismaService
|
||||||
|
2. create → prisma.xxx.create()
|
||||||
|
3. findById → prisma.xxx.findUnique()
|
||||||
|
4. findAllByUserId → prisma.xxx.findMany({ where: { userId } })
|
||||||
|
5. update → prisma.xxx.update()
|
||||||
|
6. softDelete → prisma.xxx.update({ data: { deletedAt: new Date() } })
|
||||||
|
7. 删除 Map 相关代码
|
||||||
|
```
|
||||||
|
|
||||||
|
### 任务 1.4:给所有 Controller 统一加 JwtAuthGuard
|
||||||
|
|
||||||
|
当前问题:
|
||||||
|
- `KnowledgeBaseController` 的 `@CurrentUser()` 标记了 `| undefined`,实际允许未登录访问
|
||||||
|
- 部分 Controller 根本没加 guard
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. KnowledgeBaseController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
2. KnowledgeItemsController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
3. ActiveRecallController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
4. AiAnalysisController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
5. FocusItemsController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
6. ReviewController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
7. LearningSessionController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
8. LearningActivityController 加 @UseGuards(JwtAuthGuard)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 阶段 2:第一个真实 AI Provider
|
||||||
|
|
||||||
|
### 任务 2.1:选 provider + 获取 API Key
|
||||||
|
|
||||||
|
**前置条件**:决策 3
|
||||||
|
|
||||||
|
### 任务 2.2:实现第一个真实 AI Provider
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. 创建 DeepSeekProvider(或你选的 provider)
|
||||||
|
2. 实现 AiProvider 接口
|
||||||
|
3. 对接真实 API
|
||||||
|
4. 处理超时、重试、JSON 解析
|
||||||
|
5. 更新 AiModule 根据配置切换 provider
|
||||||
|
```
|
||||||
|
|
||||||
|
### 任务 2.3:实现第一个真实 Prompt 模板
|
||||||
|
|
||||||
|
硬编码在 MockAiProvider 里的静态 JSON 不能用了,需要:
|
||||||
|
```text
|
||||||
|
1. 编写主动回忆分析的 System Prompt
|
||||||
|
2. 设计输出 JSON Schema
|
||||||
|
3. 处理 AI 返回格式不稳定的情况(JSON 解析错误兜底)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 阶段 3:学习闭环联调
|
||||||
|
|
||||||
|
### 任务 3.1:验证端到端流程
|
||||||
|
|
||||||
|
```text
|
||||||
|
用户登录
|
||||||
|
→ 创建知识库
|
||||||
|
→ 创建知识点
|
||||||
|
→ 开始学习会话
|
||||||
|
→ 提交主动回忆
|
||||||
|
→ AI 分析
|
||||||
|
→ 生成 FocusItem
|
||||||
|
→ 生成复习卡
|
||||||
|
→ 完成复习
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 五、决策汇总表(已确认)
|
||||||
|
|
||||||
|
| 编号 | 问题 | 决策 | 状态 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| 决策 1 | MySQL 数据库当前状态? | URL-encode 密码 `@→%40, !→%21`,确认连接后 migrate | 已修复 DATABASE_URL |
|
||||||
|
| 决策 2 | BigInt vs cuid vs Int,用哪个 ID 方案? | **全部 String cuid()**,不用 BigInt | 已完成 |
|
||||||
|
| 决策 3 | 第一个 AI Provider 选谁? | DeepSeek,但先不接,等核心闭环跑通 | 已决策 |
|
||||||
|
| 决策 4 | Redis 现在启动还是先绕过? | 先绕过,不阻塞主线 | 已决策 |
|
||||||
|
| 决策 5 | Prisma Schema 全部迁移还是分批? | 保留完整 schema,一次迁移 | 已决策 |
|
||||||
|
| 决策 6 | Apple 登录什么时候接? | **现在接**,BUNDLE_ID=cloud.longde.AIStudyApp | 已配置 |
|
||||||
|
|
||||||
|
## 已完成的改动
|
||||||
|
|
||||||
|
- [x] `schema.prisma`:全部 27 个 model 的 BigInt → String cuid()
|
||||||
|
- [x] `auth.service.ts`:删除 BigInt() 转换、bigint 类型 → string
|
||||||
|
- [x] `token.service.ts`:bigint → string,删除 String(user.id) 转换
|
||||||
|
- [x] `users.repository.ts`:删除所有 BigInt() 转换
|
||||||
|
- [x] `security.util.ts`:number|bigint → string
|
||||||
|
- [x] `.env`:DATABASE_URL 密码 URL-encode,补 APPLE_BUNDLE_ID
|
||||||
|
- [x] `.env.example`:同步更新
|
||||||
|
|
||||||
|
## 待完成(需要 MySQL 环境)
|
||||||
|
|
||||||
|
- [ ] `prisma migrate dev --name init`
|
||||||
|
- [ ] `prisma generate`
|
||||||
|
- [ ] 启动服务,验证 dev-login、refresh、logout、users/me
|
||||||
|
- [ ] KnowledgeBaseRepository 接 Prisma(第一个业务 repository 迁移)
|
||||||
|
- [ ] KnowledgeItemsRepository 接 Prisma
|
||||||
|
- [ ] ActiveRecallRepository 接 Prisma
|
||||||
|
- [ ] 所有 Controller 加 JwtAuthGuard
|
||||||
@ -1,9 +1,11 @@
|
|||||||
下面这段可以直接写进你的项目文档里。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# 知习 AI 工作流与学习 Agent 设计总结
|
# 知习 AI 工作流与学习 Agent 设计总结
|
||||||
|
|
||||||
|
> **设计方向文档。**
|
||||||
|
>
|
||||||
|
> **实现状态**:阶段 0 全部完成,三层架构(Provider → Gateway → Workflow)已落地。详见 [[已完成]-AI架构决策清单.md](./[已完成]-AI架构决策清单.md)
|
||||||
|
>
|
||||||
|
> **最后更新**:2026-05-16
|
||||||
|
|
||||||
## 一、核心原则
|
## 一、核心原则
|
||||||
|
|
||||||
知习的 AI 能力不应该是一套通用聊天接口,也不应该所有业务都共用同一套 AI 工作流。
|
知习的 AI 能力不应该是一套通用聊天接口,也不应该所有业务都共用同一套 AI 工作流。
|
||||||
|
|||||||
213
技术设计/api-server/已完成/[已完成]-AI架构决策清单.md
Normal file
213
技术设计/api-server/已完成/[已完成]-AI架构决策清单.md
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
# 知习 AI 架构 V1:决策与执行清单
|
||||||
|
|
||||||
|
> **2026-05-16 已确认并完成**:三层架构(Provider → Gateway → Workflow),阶段 0 全部完成。
|
||||||
|
> 设计方向文档:[AI架构设计.md](./[设计中]-AI架构设计.md)
|
||||||
|
>
|
||||||
|
> **状态:✅ 阶段 0 完成 | 阶段 1 基本完成 | 阶段 2 待推进**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 一、架构原则
|
||||||
|
|
||||||
|
## 核心分层
|
||||||
|
|
||||||
|
```text
|
||||||
|
业务模块层(ActiveRecall / ai-analysis)
|
||||||
|
↓ 调用
|
||||||
|
AI Workflow 层(ActiveRecallAnalysisWorkflow)
|
||||||
|
↓ 调用
|
||||||
|
AI Gateway 层(AiGatewayService:选模型、记日志、解析 JSON、超时重试)
|
||||||
|
↓ 调用
|
||||||
|
AI Provider 层(DeepSeekProvider / MiniMaxProvider / MockAiProvider)
|
||||||
|
```
|
||||||
|
|
||||||
|
**每一层的职责边界**:
|
||||||
|
|
||||||
|
| 层 | 知道什么 | 不知道什么 |
|
||||||
|
|----|---------|-----------|
|
||||||
|
| Provider | messages, model, temperature, signal | 知识点、主动回忆、FocusItem |
|
||||||
|
| Gateway | feature, promptVersion, cost, retry | 业务 Workflow 细节 |
|
||||||
|
| Workflow | 知识点、回答、分析逻辑 | 模型 API 细节 |
|
||||||
|
| 业务模块 | 自己的 CRUD | AI 调用细节 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 二、已确认决策(全部实现)
|
||||||
|
|
||||||
|
| 编号 | 决策 | 结论 | 状态 |
|
||||||
|
|------|------|------|------|
|
||||||
|
| A | 架构分层 | Provider → Gateway → Workflow 三层 | ✅ |
|
||||||
|
| B | Mock 保留 | Mock 跑通闭环,永久保留 | ✅ |
|
||||||
|
| C | 第一个 Provider | DeepSeek(V4-Flash 便宜,V4-Pro 强推理) | ✅ |
|
||||||
|
| D | 第二个 Provider | MiniMax M2.7(Coding Plan 已付费,主力分析) | ✅ |
|
||||||
|
| E | Model Router | 三层:cheap / primary / strong,显式 fallback | ✅ |
|
||||||
|
| F | Gateway 超时 | AbortController 30s + 自动重试 + fallback | ✅ |
|
||||||
|
| G | Prompt 管理 | 代码文件 + promptKey / promptVersion 追踪 | ✅ |
|
||||||
|
| H | JSON 校验 | Zod Schema + 三层容错(parse → fence → extract) | ✅ |
|
||||||
|
| I | 成本控制 | AiUsageLog + AiCostCalculatorService | ✅ |
|
||||||
|
| J | 旧代码清理 | 删除 infrastructure/ai,ai-analysis 迁到新 gateway | ✅ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 三、当前文件结构
|
||||||
|
|
||||||
|
```
|
||||||
|
src/modules/ai/
|
||||||
|
├── ai.module.ts # NestJS DI:Map<string, AiProvider>
|
||||||
|
├── ai.controller.ts # POST /ai/analyze-recall · GET /ai/models
|
||||||
|
├── model-router.ts # cheap / primary / strong 三档路由
|
||||||
|
├── gateway/
|
||||||
|
│ ├── ai-gateway.types.ts # GatewayRequest / GatewayResponse / ModelTier
|
||||||
|
│ └── ai-gateway.service.ts # 统一入口:选模型、30s超时、重试、JSON三层容错、记日志
|
||||||
|
├── providers/
|
||||||
|
│ ├── ai-provider.interface.ts # AiGenerateInput(signal) / AiGenerateOutput
|
||||||
|
│ ├── mock-ai.provider.ts # 永久保留,返回 simulated 分析结果
|
||||||
|
│ ├── deepseek.provider.ts # DeepSeek API(OpenAI 兼容)
|
||||||
|
│ └── minimax.provider.ts # MiniMax M2.7(OpenAI 兼容)
|
||||||
|
├── prompts/
|
||||||
|
│ ├── prompt-template.service.ts # key + version 注册表
|
||||||
|
│ ├── active-recall-analysis.prompt.ts # System Prompt
|
||||||
|
│ └── schemas/
|
||||||
|
│ └── active-recall-analysis.schema.ts # Zod Schema + JSON 输出示例
|
||||||
|
├── usage/
|
||||||
|
│ ├── ai-cost-calculator.service.ts # 按模型计算费用
|
||||||
|
│ └── ai-usage-log.service.ts # 写 AiUsageLog
|
||||||
|
└── workflows/
|
||||||
|
└── active-recall-analysis.workflow.ts # 第一个 Workflow:主动回忆分析
|
||||||
|
```
|
||||||
|
|
||||||
|
## 关联模块
|
||||||
|
|
||||||
|
```
|
||||||
|
src/modules/ai-analysis/ # 导入 AiModule,用 ActiveRecallAnalysisWorkflow
|
||||||
|
├── ai-analysis.module.ts
|
||||||
|
├── ai-analysis.controller.ts # POST /ai-analysis · GET /ai-analysis/:id
|
||||||
|
├── ai-analysis.service.ts
|
||||||
|
└── ai-analysis.repository.ts
|
||||||
|
|
||||||
|
src/modules/active-recall/ # 导入 AiModule,提交答案异步触发分析
|
||||||
|
├── active-recall.module.ts
|
||||||
|
├── active-recall.controller.ts # POST /active-recalls/:id/submit
|
||||||
|
├── active-recall.service.ts
|
||||||
|
└── active-recall.repository.ts
|
||||||
|
|
||||||
|
src/infrastructure/ai/ # ❌ 已删除(旧 AiService + 旧 MockAiProvider)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 四、数据流(主动回忆分析)
|
||||||
|
|
||||||
|
```text
|
||||||
|
1. POST /active-recalls/:id/submit
|
||||||
|
↓
|
||||||
|
2. ActiveRecallService.submit() 保存回答 + 异步 analysisWorkflow.execute()
|
||||||
|
↓
|
||||||
|
3. ActiveRecallAnalysisWorkflow.execute({ userId, questionText, knowledgeItemContent, userAnswer })
|
||||||
|
↓
|
||||||
|
4. PromptTemplateService.get('active-recall-analysis', '1.0.0')
|
||||||
|
↓
|
||||||
|
5. AiGatewayService.generate({ feature, userId, tier:'primary', promptKey, messages, outputSchema })
|
||||||
|
↓
|
||||||
|
6. ModelRouter.resolve('primary') → minimax-m2.7(fallback: deepseek-v4-pro)
|
||||||
|
↓
|
||||||
|
7. Provider.generate() + AbortController(30s) → fetch()
|
||||||
|
↓
|
||||||
|
8. JSON 三层容错:直接 parse → 提取 markdown fence → 提取 { } 对象
|
||||||
|
↓
|
||||||
|
9. Zod Schema 校验 → ActiveRecallAnalysisResult
|
||||||
|
↓
|
||||||
|
10. AiUsageLogService.log() 记 tokens / cost / latency
|
||||||
|
↓
|
||||||
|
11. GatewayResponse { parsed, usage }
|
||||||
|
↓
|
||||||
|
12. Workflow 返回 ActiveRecallAnalysisResult
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 五、数据库
|
||||||
|
|
||||||
|
## AiUsageLog(已加入 schema,待 db push)
|
||||||
|
|
||||||
|
```prisma
|
||||||
|
model AiUsageLog {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
userId String
|
||||||
|
feature String @db.VarChar(64)
|
||||||
|
provider String @db.VarChar(32)
|
||||||
|
model String @db.VarChar(100)
|
||||||
|
tier String @db.VarChar(32)
|
||||||
|
promptKey String @db.VarChar(128)
|
||||||
|
promptVersion String @db.VarChar(32)
|
||||||
|
inputTokens Int @default(0)
|
||||||
|
outputTokens Int @default(0)
|
||||||
|
estimatedCost Float @default(0)
|
||||||
|
latencyMs Int @default(0)
|
||||||
|
success Boolean @default(true)
|
||||||
|
errorMessage String? @db.VarChar(500)
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
|
||||||
|
user User @relation(fields: [userId], references: [id])
|
||||||
|
|
||||||
|
@@index([userId])
|
||||||
|
@@index([feature])
|
||||||
|
@@index([createdAt])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ `prisma db push` 待 SSH 隧道连通后执行
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 六、可执行任务状态
|
||||||
|
|
||||||
|
## 阶段 0:AI 地基 ✅ 14/14
|
||||||
|
|
||||||
|
| # | 任务 | 状态 |
|
||||||
|
|---|------|------|
|
||||||
|
| 1 | AiUsageLog 表(prisma schema) | ✅ |
|
||||||
|
| 2 | 统一 AiProvider 接口(generate + signal) | ✅ |
|
||||||
|
| 3 | ModelRouter(cheap / primary / strong) | ✅ |
|
||||||
|
| 4 | AiGatewayService(统一入口 + JSON 容错 + 超时重试) | ✅ |
|
||||||
|
| 5 | PromptTemplateService(key + version) | ✅ |
|
||||||
|
| 6 | DeepSeekProvider | ✅ |
|
||||||
|
| 7 | MiniMaxProvider | ✅ |
|
||||||
|
| 8 | Zod Schema(ActiveRecallAnalysisResult) | ✅ |
|
||||||
|
| 9 | AiUsageLogService + AiCostCalculatorService | ✅ |
|
||||||
|
| 10 | ActiveRecallAnalysisWorkflow | ✅ |
|
||||||
|
| 11 | AiModule(DI 注入) | ✅ |
|
||||||
|
| 12 | AiController(analyze-recall / models) | ✅ |
|
||||||
|
| 13 | MockAiProvider(保留不动) | ✅ |
|
||||||
|
| 14 | 删除旧 infrastructure/ai | ✅ |
|
||||||
|
|
||||||
|
## 阶段 1:集成打通 ✅ 4/6
|
||||||
|
|
||||||
|
| # | 任务 | 状态 |
|
||||||
|
|---|------|------|
|
||||||
|
| 15 | ai-analysis 改用 ActiveRecallAnalysisWorkflow | ✅ |
|
||||||
|
| 16 | ai-analysis.module 导入 AiModule | ✅ |
|
||||||
|
| 17 | active-recall 提交答案触发分析 | ✅ |
|
||||||
|
| 18 | Gateway AbortController 30s 超时 | ✅ |
|
||||||
|
| 19 | prisma db push 建 AiUsageLog 表 | ⚠️ 等隧道 |
|
||||||
|
| 20 | 真实 AI 切换 + Prompt 调优 | ⏳ 后续 |
|
||||||
|
|
||||||
|
## 阶段 2:待推进
|
||||||
|
|
||||||
|
| # | 任务 |
|
||||||
|
|---|------|
|
||||||
|
| 21 | 11 个业务 Repository:in-memory Map → Prisma |
|
||||||
|
| 22 | 所有 Controller 加 JwtAuthGuard |
|
||||||
|
| 23 | 真实 AI 联调 + 样本测试 + Prompt 调优 |
|
||||||
|
| 24 | 更多 Workflow(知识导入、费曼分析、复习卡片、长期趋势) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# 七、一句话总结
|
||||||
|
|
||||||
|
```text
|
||||||
|
DeepSeek 只是第一个模型,不是 AI 架构本身。
|
||||||
|
知习现在有了「可替换模型、可追踪成本、可校验输出、可沉淀学习结果」的三层 AI 工作流架构:
|
||||||
|
Provider → Gateway → Workflow。
|
||||||
|
阶段 0 全部完成,阶段 1 基本完成。
|
||||||
|
```
|
||||||
Loading…
x
Reference in New Issue
Block a user