Add AGENTS.md and ignore coverage
All checks were successful
CI/CD Pipeline / Code Quality (push) Successful in 18s
CI/CD Pipeline / Unit Tests (push) Successful in 14s
CI/CD Pipeline / Build & Deploy Test (push) Has been skipped
CI/CD Pipeline / Build & Deploy Production (push) Successful in 1m20s

This commit is contained in:
Wang Zhuoxuan 2026-05-04 22:02:01 +08:00
parent 3ea44189e8
commit b46b6c8ae0
2 changed files with 134 additions and 0 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@ dist/
# Claude Code
.claude/
coverage/

132
AGENTS.md Normal file
View File

@ -0,0 +1,132 @@
# AGENTS.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 | 环境变量 + 请求体校验(所有路由已接入 Zod |
| 测试 | Vitest | 单元测试框架19 个测试全部通过 |
| 运行时 | 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 test # 运行测试vitest run
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 # 全部 15 张表定义(唯一真相源)
├── 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/* 路径)
│ ├── audit-log.ts # 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, subscription-service
│ └── admin/ # 7 个管理端 CRUD 服务
│ └── question, category, knowledge-card, skill-tree,
│ user, stats, feedback
├── routes/ # 路由(薄层,调 service + Zod 校验)
│ ├── 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
└── __tests__/ # 测试Vitest + DB mock
├── setup.ts, smoke.test.ts
├── helpers/db-mock.ts
└── services/ # 单元测试auth, quiz, progress
content/ # 种子数据JSON
├── categories.json, skill-tree.json, achievements.json
├── history.json, drama.json, crosstalk.json
db/seeds/index.ts # 幂等种子导入脚本
```
## 编码约定
- **路由只做参数提取和响应格式化**,业务逻辑在 `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
## 数据库
- **15 张表**,定义在 `src/db/schema.ts`
- 核心7`users`, `categories`, `questions`, `knowledge_cards`, `user_progress`, `skill_tree`, `user_chapter_progress`
- 反馈2`question_ratings`, `user_feedback`
- 游戏化3`achievements`, `user_achievements`, `leaderboard_snapshots`
- 商业1`subscriptions`
- 管理员2`admin_users`, `admin_audit_log`
- Schema 定义在 `src/db/schema.ts`,迁移由 `drizzle-kit` 从 schema 自动生成
- `datetime` 列使用 `default(sql\`CURRENT_TIMESTAMP\`)`MySQL datetime 无 `defaultNow()`
## 设计文档
| 文档 | 路径 | 说明 |
|------|------|------|
| 实施计划 | [./docs/implementation-plan.md](./docs/implementation-plan.md) | Phase 1b/1c 实施进度42/44 步) |
| 本库开发规格 | [./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 骨架**:✅ 已完成
- **Phase 1b 核心功能**:✅ 已完成华为登录、出题引擎、XP/连胜/红心、技能树、Admin CRUD、路由验证
- **Phase 1c 商业化**:✅ 已完成(排行榜、成就系统、华为 IAP + 订阅、安全加固)
- **Phase 1c-5 集成部署**:⬜ 待完成E2E 测试、Dockerfile/CI