From 69dbb72777280cc9d1b0082c1401e8f99818d11b Mon Sep 17 00:00:00 2001 From: WangDL Date: Sun, 17 May 2026 00:41:02 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0AI=E6=9E=B6=E6=9E=84?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E3=80=81=E5=90=8E=E7=AB=AF=E5=BE=85=E5=8A=9E?= =?UTF-8?q?=E6=B8=85=E5=8D=95=EF=BC=8C=E5=BD=92=E6=A1=A3=E5=B7=B2=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新AI架构设计文档链接 - 整理后端待完成事项清单(12 Repository迁Prisma、AI架构、JwtAuthGuard等) - 归档已完成:AI架构决策清单 Co-Authored-By: Claude Opus 4.7 --- .../api-server/[进行中]-后端待完成事项清单.md | 614 ++++++++++++++++++ .../已完成/[已完成]-当前状态与决策清单.md | 360 ++++++++++ 技术设计/api-server/[设计中]-AI架构设计.md | 10 +- .../api-server/已完成/[已完成]-AI架构决策清单.md | 213 ++++++ 4 files changed, 1193 insertions(+), 4 deletions(-) create mode 100644 开发计划/api-server/[进行中]-后端待完成事项清单.md create mode 100644 开发计划/api-server/已完成/[已完成]-当前状态与决策清单.md create mode 100644 技术设计/api-server/已完成/[已完成]-AI架构决策清单.md diff --git a/开发计划/api-server/[进行中]-后端待完成事项清单.md b/开发计划/api-server/[进行中]-后端待完成事项清单.md new file mode 100644 index 0000000..71728b2 --- /dev/null +++ b/开发计划/api-server/[进行中]-后端待完成事项清单.md @@ -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` / `Array` 迁到 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 集成 +``` diff --git a/开发计划/api-server/已完成/[已完成]-当前状态与决策清单.md b/开发计划/api-server/已完成/[已完成]-当前状态与决策清单.md new file mode 100644 index 0000000..01cc934 --- /dev/null +++ b/开发计划/api-server/已完成/[已完成]-当前状态与决策清单.md @@ -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 diff --git a/技术设计/api-server/[设计中]-AI架构设计.md b/技术设计/api-server/[设计中]-AI架构设计.md index 84caeab..69abf85 100644 --- a/技术设计/api-server/[设计中]-AI架构设计.md +++ b/技术设计/api-server/[设计中]-AI架构设计.md @@ -1,9 +1,11 @@ -下面这段可以直接写进你的项目文档里。 - ---- - # 知习 AI 工作流与学习 Agent 设计总结 +> **设计方向文档。** +> +> **实现状态**:阶段 0 全部完成,三层架构(Provider → Gateway → Workflow)已落地。详见 [[已完成]-AI架构决策清单.md](./[已完成]-AI架构决策清单.md) +> +> **最后更新**:2026-05-16 + ## 一、核心原则 知习的 AI 能力不应该是一套通用聊天接口,也不应该所有业务都共用同一套 AI 工作流。 diff --git a/技术设计/api-server/已完成/[已完成]-AI架构决策清单.md b/技术设计/api-server/已完成/[已完成]-AI架构决策清单.md new file mode 100644 index 0000000..4cc5e7e --- /dev/null +++ b/技术设计/api-server/已完成/[已完成]-AI架构决策清单.md @@ -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 +├── 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 基本完成。 +```