- 基于 NestJS + TypeScript + MySQL + Redis 架构 - 完整的模块化设计(认证、用户、小组、游戏、预约等) - JWT 认证和 RBAC 权限控制系统 - Docker 容器化部署支持 - 添加 CLAUDE.md 项目开发指南 - 配置 .gitignore 忽略文件 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
7.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
GameGroup Backend is a NestJS-based REST API for a game group management platform. It provides team organization, appointment scheduling, asset management, and financial ledgers for gaming groups.
Tech Stack: NestJS 10.x, TypeScript 5.x, MySQL 8.0, Redis 7.x, TypeORM
Common Commands
Development
npm run start:dev # Development server with hot reload
npm run start:debug # Debug mode
npm run build # Production build
npm run start:prod # Production server
Database
# Start MySQL and Redis using Docker
docker compose up -d mysql redis
# Reset database (drops and recreates)
./reset-db.sh
Testing & Quality
npm run test # Unit tests
npm run test:e2e # End-to-end tests
npm run test:cov # Test coverage
npm run lint # ESLint with auto-fix
npm run format # Prettier formatting
Architecture
Module Structure
The application follows NestJS's modular architecture:
-
src/common/- Shared utilities and cross-cutting concerns:decorators/- Custom decorators (@Public(),@Roles(),@CurrentUser())guards/- Authentication and authorization guards (JWT, Roles)filters/- Global exception handlinginterceptors/- Response transformation and loggingpipes/- Input validationutils/- Utility functions (crypto, pagination, date helpers)
-
src/config/- Configuration files loaded by @nestjs/config:app.config.ts- Application settingsdatabase.config.ts- Database connectionjwt.config.ts- JWT configurationredis.config.ts- Redis configurationcache.config.ts- Cache settingsperformance.config.ts- CORS and compression settings
-
src/entities/- TypeORM database entities -
src/modules/- Feature modules (auth, users, groups, games, appointments, ledgers, schedules, blacklist, honors, assets, points, bets)
Global Middleware Stack
In src/main.ts, the following are applied globally:
- Compression middleware - Response compression
- CORS - Configurable origins (dev: all, prod: from env)
- Global prefix -
/api(configurable viaAPI_PREFIX) - Exception filter - HttpExceptionFilter for unified error responses
- Interceptors - LoggingInterceptor → TransformInterceptor
- Validation pipe - ValidationPipe with class-validator
Swagger documentation is enabled only in development at /docs.
Authentication & Authorization
The system uses a two-layer permission system:
-
JWT Authentication (JwtAuthGuard) - Verifies user identity
- Applied globally via APP_GUARD in src/app.module.ts
- Use
@Public()decorator on controllers/methods to bypass authentication
-
Role-Based Authorization (RolesGuard) - Checks system-level roles
- Also applied globally via APP_GUARD
- Use
@Roles(UserRole.ADMIN)to restrict to specific roles - Currently defined roles:
admin,user(see src/common/enums/index.ts)
Important: Group-level permissions (Owner/Admin/Member) are checked in service layer business logic, not via guards. See 权限管理文档.md for detailed permission rules.
Response Format
All responses follow a unified format defined in src/common/interfaces/response.interface.ts:
Success:
{
"code": 0,
"message": "success",
"data": { ... },
"timestamp": 1703001234567
}
Error:
{
"code": 10001,
"message": "用户不存在",
"data": null,
"timestamp": 1703001234567
}
Error codes are defined in the ErrorCode enum. Use ErrorCode.CONSTANT_NAME when throwing errors.
Common Patterns
Service with TypeORM:
// Inject repository in constructor
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
) {}
// Use repository methods
async findOne(id: string): Promise<User> {
return this.userRepository.findOne({ where: { id } });
}
Throwing business errors:
import { ErrorCode, ErrorMessage } from '@/common/interfaces/response.interface';
throw new BadRequestException({
code: ErrorCode.USER_NOT_FOUND,
message: ErrorMessage[ErrorCode.USER_NOT_FOUND],
});
Getting current user:
@Get('me')
async getProfile(@CurrentUser() user: User) {
return this.usersService.findOne(user.id);
}
Marking public endpoints:
@Public()
@Post('login')
async login(@Body() loginDto: LoginDto) {
return this.authService.login(loginDto);
}
Environment Variables
The app uses .env files with fallback order:
.env.${NODE_ENV}(e.g.,.env.development,.env.production).env.local.env
Key environment variables:
NODE_ENV-development|productionPORT- Server port (default: 3000)API_PREFIX- API route prefix (default:api)DB_HOST,DB_PORT,DB_USERNAME,DB_PASSWORD,DB_DATABASE- MySQL connectionREDIS_HOST,REDIS_PORT- Redis connectionJWT_SECRET- JWT signing secretCORS_ORIGIN- CORS allowed origins (default:*)
TypeORM Configuration
- Synchronize - Enabled in development (
synchronize: true), disable in production - Timezone - Set to
+08:00 - Charset -
utf8mb4 - Entities - Auto-loaded from
**/*.entity{.ts,.js}
Creating New Modules
When adding a new feature module:
- Generate module structure:
nest g resource modules/feature-name - Create entity in
src/entities/ - Add module to imports in
src/app.module.ts - Add Swagger tag in
src/main.tsfor documentation - Implement service with TypeORM repositories
- Apply decorators (
@Public(),@Roles()) as needed on controller
Important Files
- src/main.ts - Application bootstrap, middleware configuration
- src/app.module.ts - Root module, global guards, database setup
- src/common/guards/ - JWT and Role guards
- src/common/decorators/ - Custom decorators
- src/common/interfaces/response.interface.ts - Error codes and response format
- 权限管理文档.md - Detailed permission system documentation (Chinese)
Testing Notes
- Unit tests:
*.spec.tsfiles alongside source code - E2E tests:
test/directory with Jest configuration attest/jest-e2e.json - Tests use Jest with ts-jest preset
- Coverage reports output to
coverage/directory
Deployment Notes
- Docker image builds from
Dockerfile - Use
docker-compose.ymlfor full stack (MySQL + Redis + App) - Production uses PM2 for process management (see
ecosystem.config.js) - Build output:
dist/directory