系统架构

架构概览

EduBuddy 采用经典的 前后端分离 架构,前端为 SPA(单页应用),后端提供 RESTful API,通过 JWT 进行无状态鉴权,AI 功能通过 OpenAI 兼容 SDK 集成。

整体架构图

┌─────────────────────────────────────────────────────────────────┐ │ 浏览器(用户) │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ React SPA(端口 5173/80) │ │ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │Dashboard │ │Questions │ │Progress │ │Learning │ │ │ │ │ │ Page │ │ Page │ │ Page │ │Paths Page│ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ ↕ Axios HTTP / JWT Bearer Token │ │ │ └─────────────────────────────────────────────────────────┘ │ └──────────────────────────┬──────────────────────────────────────┘ │ HTTP REST API ↓ ┌─────────────────────────────────────────────────────────────────┐ │ Node.js + Express 后端(端口 3001) │ │ │ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │ │ │Helmet │ │CORS │ │RateLimit │ │Compression │ │ │ │(安全头) │ │(跨域控制)│ │(速率限制)│ │(Gzip 压缩) │ │ │ └─────────┘ └──────────┘ └──────────┘ └────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ 路由层(Routes) │ │ │ │ /auth /questions /progress /learning-paths │ │ │ │ /upload /sharing │ │ │ └──────────────────────────────────────────────────────────┘ │ │ ↕ JWT 鉴权中间件 │ │ ┌──────────────────┐ ┌──────────────────────────────┐ │ │ │ AI Service 层 │ │ 数据库访问层 │ │ │ │ (aiService.ts) │ │ (better-sqlite3 同步 API) │ │ │ └──────────────────┘ └──────────────────────────────┘ │ │ ↕ ↕ │ └───────────┬──────────────────────────────┬──────────────────────┘ │ │ ↓ ↓ ┌─────────────────────┐ ┌──────────────────────────────────┐ │ OpenAI 兼容 API │ │ SQLite 数据库 │ │ (GPT-4o/DeepSeek │ │ (WAL 模式,12 张数据表) │ │ /通义千问 等) │ │ 本地文件:edubuddy.db │ └─────────────────────┘ └──────────────────────────────────┘

核心设计决策

1. 为什么选择 SQLite?

EduBuddy 选择 SQLite 作为嵌入式数据库,理由如下:

2. 无状态 JWT 鉴权

所有受保护 API 使用 JWT Bearer Token 鉴权:

3. AI 调用统一封装

所有 AI 功能通过 backend/src/services/aiService.ts 统一管理:

4. 速率限制分层

两层速率限制保护服务:

数据流示例:AI 生成题目

用户点击「AI 生成题目」 ↓ 前端 questionAPI.generate({ subject, topic, difficulty, ... }) ↓ POST /api/questions/generate [带 JWT Token] ↓ aiLimiter 速率检查 → authMiddleware 鉴权 ↓ questions.ts 路由处理器 ↓ 调用 aiService.generateQuestion(subject, topic, difficulty, type, count) ↓ 构造 Prompt → OpenAI SDK chat.completions.create() ↓ AI 返回 JSON 字符串 → 解析为对象数组 ↓ 循环插入 questions 表(UUID 主键) ↓ 返回 { success: true, data: { ids, questions } } ↓ 前端刷新题目列表并提示「成功生成 N 道题目」

模块依赖关系

模块依赖被依赖
server.ts所有路由、中间件、数据库—(入口)
routes/*database/db、services/aiService、middleware/authserver.ts
services/aiService.tsopenai、utils/loggerroutes/questions、routes/progress、routes/learningPaths、routes/upload
database/db.tsbetter-sqlite3、database/schema.sql几乎所有路由
middleware/auth.tsutils/jwt所有需鉴权的路由
utils/jwt.tsjsonwebtokenmiddleware/auth、routes/auth
utils/logger.tswinston全局