Files
project-base/.claude/commands/nestjs.md
T
ttipo f5a18a52f4 docs: 템플릿 규칙 정비 및 환경변수 예제·README 추가
- CLAUDE.md: 모노레포 개요·표준 응답 포맷·에러 코드 맵(구현 일치)·환경변수 위임 구조(SSOT) 정리
- nestjs/vue3/flutter 규칙을 실제 구현(클래스명, env키, 디렉터리)과 정합화
- 루트 .env 단일 진실 공급원 구조에 맞춰 docker-compose 변수명 정정(BACKEND_API_URL, DB/REDIS_DATA_DIR)
- backend/frontend/flutter 예제 env 추가(루트 위임 반영, 서비스 고유 값만 작성)
- README.md 신규 작성, command.md 범용화, .gitignore에 *.example 재포함 규칙 추가

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 11:14:42 +09:00

4.4 KiB

description
description
NestJS 백엔드 개발 규칙

이 파일은 .claude/commands/nestjs.md에 위치한다. 사용법: /nestjs [요청 내용]


아키텍처 원칙

관심사 분리 (Separation of Concerns)

Controller  →  HTTP 라우팅, 요청/응답 파싱만 담당
Service     →  모든 비즈니스 로직 처리
Repository  →  데이터 접근 계층 (TypeORM)
DTO         →  요청/응답 데이터 형식 정의 및 검증
  • Controller에 비즈니스 로직 작성 금지
  • new 키워드로 수동 객체 생성 지양 → 의존성 주입(DI) 활용

모듈 구조

src/
├── modules/
│   └── user/
│       ├── user.module.ts
│       ├── user.controller.ts
│       ├── user.service.ts
│       ├── user.repository.ts      ← 커스텀 Repository (선택)
│       └── dto/
│           ├── create-user.dto.ts
│           └── update-user.dto.ts
├── common/
│   ├── interceptors/               ← 응답 래핑, 에러 처리
│   ├── filters/                    ← 전역 Exception Filter
│   ├── guards/                     ← 인증/권한 Guard
│   ├── decorators/                 ← 커스텀 데코레이터
│   └── pipes/                      ← 전역 Validation Pipe
└── shared/
    └── utils/                      ← 순수 유틸 함수

DTO 작성 규칙

import { IsString, IsEmail, IsNotEmpty, MinLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class CreateUserDto {
  @ApiProperty({ description: '사용자 이메일', example: 'user@example.com' })
  @IsEmail({}, { message: '올바른 이메일 형식을 입력해 주세요.' })
  @IsNotEmpty()
  email: string;

  @ApiProperty({ description: '비밀번호 (최소 8자)', example: 'password123' })
  @IsString()
  @MinLength(8, { message: '비밀번호는 최소 8자 이상이어야 합니다.' })
  password: string;
}
  • 모든 DTO는 class-validator + class-transformer 사용
  • 에러 메시지는 한국어로 작성
  • @ApiProperty() 반드시 포함 (Swagger 명세용)

표준 응답 인터셉터

// common/interceptors/transform.interceptor.ts
@Injectable()
export class TransformInterceptor<T> implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map((data) => ({
        success: true,
        data: data ?? null,
      })),
    );
  }
}
  • main.ts에서 전역 등록: app.useGlobalInterceptors(new TransformInterceptor())
  • 실패 응답(success: false)은 아래 Exception Filter가 생성한다.

전역 Exception Filter

// common/filters/http-exception.filter.ts
@Catch()
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();

    // HTTP 상태 → 에러 코드 매핑 후 { success: false, error: { code, message } } 반환
    // SYS_001 / AUTH_001 / VAL_001 등 CLAUDE.md 에러 맵 참조
  }
}

Swagger 필수 적용

// main.ts
const config = new DocumentBuilder()
  .setTitle('API 문서')
  .setDescription('프로젝트 API 명세서')
  .setVersion('1.0')
  .addBearerAuth()
  .build();

const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api-docs', app, document);
  • 모든 Controller에 @ApiTags() 적용
  • 모든 엔드포인트에 @ApiOperation(), @ApiResponse() 작성
  • 모든 DTO에 @ApiProperty() 작성

인증 (JWT)

  • Access Token: 만료 시간 짧게 (15분 ~ 1시간)
  • Refresh Token: HttpOnly Secure 쿠키로 전달
  • @nestjs/jwt + @nestjs/passport 사용
  • Guard를 통한 라우트 보호

성능 & 최신 트렌드 추가 규칙

  • 캐싱: 자주 조회되는 데이터는 @nestjs/cache-manager (Redis) 활용 고려
  • Rate Limiting: @nestjs/throttler로 API 남용 방지
  • Pagination: 목록 API는 반드시 커서 기반 또는 오프셋 페이지네이션 적용
  • Logging: winston 또는 @nestjs/common Logger 사용, console.log 지양
  • Health Check: @nestjs/terminus/health 엔드포인트 구성 권장
  • Versioning: API 버전 관리 (/v1/, /v2/) 적용 고려