Phase 1b — Core Features: - Huawei ID Kit login (token exchange + user info) with guest mode - Quiz engine: randomized questions, distractor shuffling, answer verification - XP service with combo bonuses (3/5/10-hit streaks), daily reset - Streak service: >=3 correct/day, freeze, UTC date handling - Hearts service: 5/day, 30min auto-restore, Pro unlimited - 50 quiz questions across 3 categories (history/drama/crosstalk) - 13 skill tree chapters with linear progression - Idempotent seed import script (categories → skill tree → questions) - 7 admin CRUD services (questions, categories, knowledge cards, skill tree, users, stats, feedback) with Zod validation - All routes use Zod schema validation, /auth/me endpoint Phase 1c — Commercialization: - Leaderboard with live XP ranking, 10 tiers, weekly settlement - Achievement system with 15 seed achievements and condition checking - Huawei IAP receipt verification + subscription management - Differentiated rate limiting (auth 10/min, quiz 60/min) - Admin audit logging middleware Infrastructure: - Vitest test framework with DB mock utilities (19 tests passing) - 12 DB tables (5 new: question_ratings, user_feedback, achievements, user_achievements, leaderboard_snapshots, subscriptions, admin_audit_log) - TypeScript strict mode: zero errors
5.2 KiB
5.2 KiB
CLAUDE.md — duoqi-api
多奇服务端 API,基于 Fastify + TypeScript + Drizzle ORM + MySQL 8.0+ 包管理器:bun(禁止使用 npm)
项目概述
多奇(Duoqi)是游戏化知识闯关学习平台。duoqi-api 是三端(HarmonyOS / Flutter / Web)共享的后端服务,从 Phase 1 起即为 HarmonyOS 客户端提供 API 支持。
技术栈
| 层面 | 选型 | 说明 |
|---|---|---|
| 后端框架 | Fastify 5 | 高性能,内置 JSON Schema 验证,TypeScript 友好 |
| ORM | Drizzle ORM | 轻量、类型安全,src/db/schema.ts 为唯一真相源 |
| 数据库 | MySQL 8.0+ | 阿里云 RDS |
| 认证 | @fastify/jwt | 自建 JWT(华为 ID Kit + 游客模式) |
| 校验 | Zod | 环境变量校验;请求体校验待迁移至 Fastify JSON Schema |
| 运行时 | Node.js (ESM) | "type": "module",import 使用 .js 后缀 |
Quick Start
bun install # 安装依赖
cp .env.example .env # 复制环境变量模板,填入实际值
bun run dev # 启动开发服务器,默认端口 3000
必填环境变量:DATABASE_URL, JWT_SECRET, ADMIN_TOKEN
开发命令
bun run dev # 启动开发服务器(tsx watch 热重载)
bun run typecheck # 类型检查(tsc --noEmit)
bun run build # 编译到 dist/
bun run db:push # 推送 schema 到数据库(开发用)
bun run db:generate # 生成迁移文件
bun run db:migrate # 执行迁移
bun run db:seed # 导入种子数据
bun run db:studio # Drizzle Studio(数据库可视化浏览器)
bun run lint # ESLint 检查
项目结构
src/
├── index.ts # 入口:Fastify 实例 + 插件注册 + 路由挂载
├── db/
│ ├── client.ts # 数据库连接(mysql2 pool + drizzle)
│ └── schema.ts # 全部表定义(唯一真相源)
├── types/ # TypeScript 类型(auth, quiz, user, api)
├── utils/
│ ├── config.ts # 环境变量(Zod 校验,启动时 fail-fast)
│ └── errors.ts # AppError 层级 + 统一错误处理器
├── middleware/
│ ├── auth.ts # JWT 认证(排除公开路径和 admin 路径)
│ ├── admin-auth.ts # Admin token 认证(/v1/admin/* 路径)
│ └── request-logger.ts # 请求耗时日志
├── services/ # 业务逻辑(按领域分目录)
│ ├── auth/ # jwt, guest, huawei-id-kit, phone
│ ├── quiz/ # quiz-service(出题引擎)
│ ├── progress/ # progress, streak, xp, hearts
│ ├── gamification/ # leaderboard, achievement
│ └── payment/ # huawei-iap
└── routes/ # 路由(薄层,调 service)
├── health.ts, auth.ts, quiz.ts, progress.ts
├── gamification.ts, payment.ts
└── admin/ # 管理端路由(duoqi-admin 调用)
└── index, auth, questions, categories, knowledge-cards,
skill-tree, users, stats, feedback
编码约定
- 路由只做参数提取和响应格式化,业务逻辑在
services/ - 响应格式统一:
{ success: boolean, data: T | null, error: { code, message } | null } - 分页响应:额外包含
pagination: { total, page, limit } - 不可变数据:
Object.freeze()或返回新对象,不修改入参 - 错误处理:抛出
AppError子类(NotFoundError,ValidationError等),由errorHandler统一捕获 - 环境变量:所有配置通过
src/utils/config.ts读取(Zod 校验),禁止直接读process.env - 导入后缀:ESM 项目,本地导入必须带
.js后缀(import { x } from './foo.js')
API 约定
- Base URL:
/v1 - 认证:
Authorization: Bearer <jwt>(公开端点:/v1/auth/*,/v1/health) - Admin 认证:
Authorization: Bearer <admin_token>(/v1/admin/*) - JWT 有效期:access_token 1h, refresh_token 30d
数据库
- 7 张核心表:
users,categories,questions,knowledge_cards,user_progress,skill_tree,user_chapter_progress - Schema 定义在
src/db/schema.ts,迁移由drizzle-kit从 schema 自动生成 datetime列使用default(sql\CURRENT_TIMESTAMP`)(MySQL datetime 无defaultNow()`)
设计文档
| 文档 | 路径 | 说明 |
|---|---|---|
| 本库开发规格 | ./dev-spec.md | 工程实施主文档 |
| 产品总纲 | ../docs/product-overview.md | 产品定位、功能范围 |
| 技术选型 | ../docs/tech-stack.md | 全栈技术决策 |
| 共享设计文档 | ../docs/specs/shared/ | 题目格式、游戏化、吉祥物、推送、埋点 |
当前进度
- Phase 1a 骨架:已完成(项目结构、数据库 schema、路由框架、中间件)
- Phase 1b 核心功能:待实现(华为登录、出题引擎、XP/连胜/心、技能树)
- Phase 1c 商业化:待实现(排行榜、成就、华为 IAP、安全加固)