100 lines
4.4 KiB
Markdown
100 lines
4.4 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## 项目概述
|
||
|
||
普拉提工作室预约与会员管理的微信小程序。TypeScript monorepo,包含三个包:
|
||
|
||
- **packages/server** — NestJS 后端(REST API、Prisma ORM、PostgreSQL)
|
||
- **packages/app** — Vue 3 + Pinia 前端,基于 Uni-app(目标平台 mp-weixin)
|
||
- **packages/shared** — 前后端共用的 TypeScript 类型、枚举和常量
|
||
|
||
## 常用命令
|
||
|
||
### 开发
|
||
```bash
|
||
pnpm dev:server # NestJS watch 模式 (localhost:3000)
|
||
pnpm dev:app # 微信小程序开发服务器
|
||
pnpm build:shared # 必须先构建 shared,再构建 server/app
|
||
```
|
||
|
||
### 测试(仅 server)
|
||
```bash
|
||
cd packages/server
|
||
pnpm test # 运行全部测试
|
||
pnpm test -- auth.service.spec # 运行单个测试文件
|
||
pnpm test:watch # watch 模式
|
||
pnpm test:cov # 覆盖率报告
|
||
```
|
||
|
||
Jest 配置内联在 `packages/server/package.json`。测试文件位于 `__tests__/` 子目录(如 `src/auth/__tests__/auth.service.spec.ts`),匹配模式:`*.spec.ts`。
|
||
|
||
### 数据库
|
||
```bash
|
||
cd packages/server
|
||
pnpm prisma:generate # schema 变更后重新生成 Prisma Client
|
||
pnpm prisma:migrate # 运行迁移(交互式)
|
||
pnpm prisma:seed # 填充种子数据
|
||
```
|
||
|
||
### 代码检查
|
||
```bash
|
||
pnpm lint # 所有包的 ESLint 检查
|
||
```
|
||
|
||
## 架构
|
||
|
||
### 数据流
|
||
```
|
||
微信小程序 → Uni-app (Vue 3) → REST API (NestJS) → Prisma → PostgreSQL
|
||
↕ ↕
|
||
Pinia stores @nestjs/schedule (定时任务)
|
||
```
|
||
|
||
### 后端模块结构
|
||
每个功能是一个 NestJS 模块,遵循 controller → service → Prisma 模式。核心模块:
|
||
- **auth** — 微信 OAuth 登录(code2Session)、JWT 令牌、手机号绑定
|
||
- **booking** — 创建/取消预约,含会员卡验证和容量检查
|
||
- **time-slot** — 课程时段管理;`SlotGeneratorService` 根据 `WeekTemplate` 自动生成
|
||
- **membership** — 基于卡的会员制(TIMES 次卡、DURATION 时效卡、TRIAL 体验卡)
|
||
- **payment** — 微信支付集成,用于购卡
|
||
- **scheduler** — 定时任务:02:00 自动生成时段,02:30 清理过期时段
|
||
|
||
### 前端结构
|
||
- **pages/** — 按路由组织的页面(home、booking、card、profile、admin)
|
||
- **stores/** — Pinia 状态管理(user、booking、studio、admin)
|
||
- **utils/request.ts** — 封装 `uni.request` 的 HTTP 客户端,自动携带 JWT
|
||
- **utils/auth.ts** — 微信登录流程:uni.login → 服务端 /auth/login → 存储 token
|
||
|
||
### Shared 包
|
||
所有 API 类型、DTO、枚举和业务常量定义在 `packages/shared/src/`,前后端通过 `@mp-pilates/shared` 引用。路径别名配置在 `tsconfig.base.json` 和 Jest 的 `moduleNameMapper` 中。
|
||
|
||
### 数据库 Schema
|
||
Prisma schema 位于 `packages/server/prisma/schema.prisma`,关键约定:
|
||
- Model 用 PascalCase,表名用 snake_case(`@@map`)
|
||
- 字段用 camelCase,列名用 snake_case(`@map`)
|
||
- 所有 ID 为 UUID
|
||
- 金额字段使用 `Decimal(10, 0)`
|
||
- 关键唯一约束:`TimeSlot` 的 `@@unique([date, startTime, endTime])`,`Booking` 的 `@@unique([userId, timeSlotId])`
|
||
|
||
### 核心业务规则
|
||
- 预约需要有效的会员卡(剩余次数或有效期内)
|
||
- 取消预约需在课程开始前 `cancelHoursLimit` 小时(默认 2 小时,可在 StudioConfig 中配置)
|
||
- 时段根据 WeekTemplate 自动生成未来 14 天的课程
|
||
- 默认时段容量为 1(私教课)
|
||
|
||
## 环境配置
|
||
|
||
需要 Node 20+(.nvmrc)、pnpm 8+、PostgreSQL。复制 `packages/server/.env.example` 为 `.env.local`,需配置 DATABASE_URL、JWT_SECRET 及微信相关凭证(APPID、SECRET、MCH_ID、MCH_KEY、证书路径)。
|
||
|
||
## 开发约定
|
||
|
||
- **API 前缀**:所有路由在 `/api` 下(setGlobalPrefix)
|
||
- **参数校验**:全局 ValidationPipe,启用 whitelist + forbidNonWhitelisted + transform
|
||
- **鉴权守卫**:受保护路由使用 `@UseGuards(JwtAuthGuard)`,通过 `@Req()` 从 JWT 载荷提取用户
|
||
- **角色**:MEMBER 和 ADMIN;管理员路由使用自定义角色守卫
|
||
- **异常处理**:使用 NestJS 内置异常(BadRequestException、NotFoundException 等)
|
||
- **分页**:统一使用 `PaginatedResponse<T>`,包含 data、total、page、limit
|
||
- **pnpm**:使用 `shamefully-hoist=true`(.npmrc),为 Uni-app 兼容所需
|