- 更新AI架构设计文档链接 - 整理后端待完成事项清单(12 Repository迁Prisma、AI架构、JwtAuthGuard等) - 归档已完成:AI架构决策清单 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
12 KiB
知习后端:当前状态 & 需要你处理的决策和任务
基于代码审计生成。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 版本用的是
stringID - 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
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
按优先级迁:
第一批(核心业务):
KnowledgeBaseRepository → prisma
KnowledgeItemsRepository → prisma
ActiveRecallRepository → prisma
第二批(学习闭环):
LearningSessionRepository → prisma
AiAnalysisRepository → prisma
FocusItemsRepository → prisma
ReviewRepository → prisma
第三批(辅助):
LearningActivityRepository → prisma
DocumentImportRepository → prisma
每个 repository 改造模板:
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
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
1. 创建 DeepSeekProvider(或你选的 provider)
2. 实现 AiProvider 接口
3. 对接真实 API
4. 处理超时、重试、JSON 解析
5. 更新 AiModule 根据配置切换 provider
任务 2.3:实现第一个真实 Prompt 模板
硬编码在 MockAiProvider 里的静态 JSON 不能用了,需要:
1. 编写主动回忆分析的 System Prompt
2. 设计输出 JSON Schema
3. 处理 AI 返回格式不稳定的情况(JSON 解析错误兜底)
阶段 3:学习闭环联调
任务 3.1:验证端到端流程
用户登录
→ 创建知识库
→ 创建知识点
→ 开始学习会话
→ 提交主动回忆
→ 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 | 已配置 |
已完成的改动
schema.prisma:全部 27 个 model 的 BigInt → String cuid()auth.service.ts:删除 BigInt() 转换、bigint 类型 → stringtoken.service.ts:bigint → string,删除 String(user.id) 转换users.repository.ts:删除所有 BigInt() 转换security.util.ts:number|bigint → string.env:DATABASE_URL 密码 URL-encode,补 APPLE_BUNDLE_ID.env.example:同步更新
待完成(需要 MySQL 环境)
prisma migrate dev --name initprisma generate- 启动服务,验证 dev-login、refresh、logout、users/me
- KnowledgeBaseRepository 接 Prisma(第一个业务 repository 迁移)
- KnowledgeItemsRepository 接 Prisma
- ActiveRecallRepository 接 Prisma
- 所有 Controller 加 JwtAuthGuard