duoqi-api/CLAUDE.md
Wang Zhuoxuan b872b1cad9 feat: implement Phase 1b core features and Phase 1c commercialization
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
2026-04-09 00:12:12 +08:00

112 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```bash
bun install # 安装依赖
cp .env.example .env # 复制环境变量模板,填入实际值
bun run dev # 启动开发服务器,默认端口 3000
```
必填环境变量:`DATABASE_URL`, `JWT_SECRET`, `ADMIN_TOKEN`
## 开发命令
```bash
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](./dev-spec.md) | 工程实施主文档 |
| 产品总纲 | [../docs/product-overview.md](../docs/product-overview.md) | 产品定位、功能范围 |
| 技术选型 | [../docs/tech-stack.md](../docs/tech-stack.md) | 全栈技术决策 |
| 共享设计文档 | [../docs/specs/shared/](../docs/specs/shared/) | 题目格式、游戏化、吉祥物、推送、埋点 |
## 当前进度
- **Phase 1a 骨架**:已完成(项目结构、数据库 schema、路由框架、中间件
- **Phase 1b 核心功能**待实现华为登录、出题引擎、XP/连胜/心、技能树)
- **Phase 1c 商业化**:待实现(排行榜、成就、华为 IAP、安全加固