Cursor Agent Mode 실전 사례: 핀테크 스타트업의 Express.js → NestJS 3일 마이그레이션

핀테크 스타트업의 레거시 API 리팩토링: Cursor Agent Mode 실전 사례

결제 처리 API 32개 엔드포인트를 운영하는 핀테크 스타트업 ‘페이브릿지(가명)‘는 Express.js 기반 레거시 코드의 유지보수 한계에 직면했습니다. 타입 안전성 부재, 테스트 커버리지 12%, 모놀리식 라우터 구조가 문제였습니다. Cursor Agent Mode를 활용해 NestJS로 3일 만에 전환한 실제 워크플로우를 공유합니다.

1일차: 프로젝트 셋업과 Docs 인덱싱 설정

Step 1. NestJS 프로젝트 초기화

npm i -g @nestjs/cli nest new paybridge-api —strict cd paybridge-api npm install @nestjs/swagger @nestjs/config class-validator class-transformer npm install @nestjs/typeorm typeorm pg

Step 2. Cursor에서 Docs 인덱싱 활성화

Cursor Settings → Features → Docs에서 프로젝트에 필요한 문서를 인덱싱합니다. // .cursor/settings.json { "docs": [ { "name": "NestJS", "url": "https://docs.nestjs.com" }, { "name": "TypeORM", "url": "https://typeorm.io" }, { "name": "class-validator", "url": "https://github.com/typestack/class-validator#readme" } ] }

Docs 인덱싱이 완료되면 Agent Mode가 NestJS 공식 문서의 최신 패턴을 참조하여 코드를 생성합니다. Cmd+L (Mac) 또는 Ctrl+L (Windows)로 채팅을 열고 Agent Mode를 선택합니다.

Step 3. .cursorrules 파일로 코드베이스 컨텍스트 설정

// .cursorrules You are working on a fintech NestJS API migration.

  • Use strict TypeScript with no any types
  • All endpoints must have Swagger decorators
  • Use class-validator for DTO validation
  • Follow NestJS modular architecture: module/controller/service/dto
  • Database: PostgreSQL with TypeORM
  • Auth: JWT Bearer tokens
  • Error responses follow RFC 7807 Problem Details format
  • All amounts are in integer (cents), never floating point

2일차: Agent Mode로 멀티파일 마이그레이션 실행

Step 4. 레거시 라우터를 NestJS 모듈로 변환

Agent Mode(Ctrl+I)를 열고 다음 프롬프트를 입력합니다: @workspace 레거시 Express 라우터 /routes/payments.js를 분석하고 NestJS 모듈 구조로 변환해줘. payments.module.ts, payments.controller.ts, payments.service.ts, create-payment.dto.ts, payment.entity.ts 파일을 한 번에 생성해줘. 기존 비즈니스 로직은 보존하면서 타입 안전성을 추가해.

Agent Mode가 생성하는 멀티파일 결과 예시: // src/payments/dto/create-payment.dto.ts import { IsString, IsInt, Min, IsEnum } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger';

export enum PaymentMethod { CARD = ‘CARD’, BANK_TRANSFER = ‘BANK_TRANSFER’, VIRTUAL_ACCOUNT = ‘VIRTUAL_ACCOUNT’, }

export class CreatePaymentDto { @ApiProperty({ description: ‘결제 금액 (원 단위 정수)’, example: 50000 }) @IsInt() @Min(100) amount: number;

@ApiProperty({ enum: PaymentMethod }) @IsEnum(PaymentMethod) method: PaymentMethod;

@ApiProperty({ description: ‘주문 ID’ }) @IsString() orderId: string; }

// src/payments/payments.controller.ts
import { Controller, Post, Body, UseGuards, HttpCode } from ‘@nestjs/common’;
import { ApiBearerAuth, ApiOperation, ApiResponse } from ‘@nestjs/swagger’;
import { JwtAuthGuard } from ’../auth/jwt-auth.guard’;
import { PaymentsService } from ’./payments.service’;
import { CreatePaymentDto } from ’./dto/create-payment.dto’;

@Controller(‘api/v2/payments’) @ApiBearerAuth() @UseGuards(JwtAuthGuard) export class PaymentsController { constructor(private readonly paymentsService: PaymentsService) {}

@Post() @HttpCode(201) @ApiOperation({ summary: ‘결제 생성’ }) @ApiResponse({ status: 201, description: ‘결제가 성공적으로 생성됨’ }) async createPayment(@Body() dto: CreatePaymentDto) { return this.paymentsService.create(dto); } }

// src/payments/payments.service.ts
import { Injectable, BadRequestException } from ‘@nestjs/common’;
import { InjectRepository } from ‘@nestjs/typeorm’;
import { Repository } from ‘typeorm’;
import { Payment } from ’./entities/payment.entity’;
import { CreatePaymentDto } from ’./dto/create-payment.dto’;

@Injectable() export class PaymentsService { constructor( @InjectRepository(Payment) private readonly paymentRepo: Repository, ) {}

async create(dto: CreatePaymentDto): Promise { const payment = this.paymentRepo.create({ …dto, status: ‘PENDING’, pgTransactionId: null, }); return this.paymentRepo.save(payment); } }

Agent Mode는 @workspace 컨텍스트를 통해 기존 Express 라우터의 미들웨어 체인, 에러 핸들링 패턴, DB 쿼리를 분석한 뒤 NestJS 관용 패턴으로 변환합니다. 한 번의 프롬프트로 5개 파일이 동시에 생성되며, Accept All 버튼으로 일괄 적용합니다.

3일차: 자동 테스트 생성과 검증

Step 5. Agent Mode로 E2E 테스트 자동 생성

@payments.controller.ts @payments.service.ts 이 모듈에 대한 단위 테스트와 E2E 테스트를 생성해줘. Jest + supertest 사용, 성공/실패/엣지 케이스 모두 포함.

생성된 테스트 코드: // test/payments.e2e-spec.ts import { Test, TestingModule } from ‘@nestjs/testing’; import { INestApplication, ValidationPipe } from ‘@nestjs/common’; import * as request from ‘supertest’; import { AppModule } from ’../src/app.module’;

describe(‘PaymentsController (e2e)’, () => { let app: INestApplication; const validToken = ‘Bearer YOUR_TEST_JWT_TOKEN’;

beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).compile(); app = moduleFixture.createNestApplication(); app.useGlobalPipes(new ValidationPipe({ whitelist: true })); await app.init(); });

it(‘POST /api/v2/payments - 정상 결제 생성’, () => { return request(app.getHttpServer()) .post(‘/api/v2/payments’) .set(‘Authorization’, validToken) .send({ amount: 50000, method: ‘CARD’, orderId: ‘ORD-001’ }) .expect(201) .expect((res) => { expect(res.body.status).toBe(‘PENDING’); }); });

it(‘POST /api/v2/payments - 금액 음수 시 400’, () => { return request(app.getHttpServer()) .post(‘/api/v2/payments’) .set(‘Authorization’, validToken) .send({ amount: -100, method: ‘CARD’, orderId: ‘ORD-002’ }) .expect(400); });

afterAll(async () => { await app.close(); }); });

Step 6. 테스트 실행 및 커버리지 확인

npx jest --coverage --verbose
# 또는 Agent Mode 터미널에서 직접 실행
npm run test:e2e

마이그레이션 결과 요약

지표Before (Express.js)After (NestJS)
테스트 커버리지12%78%
타입 안전성없음 (JS)Strict TypeScript
API 문서화수동 PostmanSwagger 자동 생성
DTO 유효성 검사수동 if문class-validator 데코레이터
소요 기간-3일 (Agent Mode 활용)
변환된 엔드포인트32개32개
## Pro Tips: Agent Mode 파워 유저 팁 - **@workspace + @파일명 조합**: 전체 코드베이스 컨텍스트와 특정 파일을 동시에 참조하면 정확도가 크게 향상됩니다.- **Docs 인덱싱 우선순위**: 마이그레이션 대상 프레임워크 문서를 먼저 인덱싱하면 Agent가 최신 API를 참조합니다. @NestJS로 직접 문서를 참조할 수 있습니다.- **단계적 프롬프트 전략**: 32개 엔드포인트를 한 번에 변환하지 말고, 도메인별(payments, users, orders)로 나누어 프롬프트를 작성하면 컨텍스트 윈도우를 효율적으로 사용합니다.- **.cursorrules 파일 활용**: 프로젝트 루트에 코딩 규칙을 명시하면 모든 Agent 응답에 자동 적용됩니다.- **Composer Mode로 대규모 편집**: 10개 이상의 파일을 동시에 수정할 때는 Ctrl+Shift+I로 Composer를 사용하세요. ## Troubleshooting: 자주 발생하는 문제
증상원인해결 방법
Agent가 Express 문법으로 코드 생성Docs 인덱싱 미완료 또는 .cursorrules 미설정Settings → Docs에서 NestJS 인덱싱 상태 확인, .cursorrules에 NestJS 명시
멀티파일 생성 시 import 경로 오류프로젝트 구조를 Agent가 잘못 인식@workspace 태그를 포함하여 전체 구조를 컨텍스트에 추가
테스트 생성 시 모듈 의존성 누락Agent가 module.ts의 providers를 참조하지 못함관련 module.ts 파일을 @payments.module.ts로 명시적 참조
Agent Mode 응답이 느리거나 끊김컨텍스트 윈도우 초과대화를 리셋(Ctrl+L → New Chat)하고 필요한 파일만 참조
TypeORM 엔티티 데코레이터 누락tsconfig의 experimentalDecorators 미설정tsconfig.json"experimentalDecorators": true, "emitDecoratorMetadata": true 추가
## 자주 묻는 질문 (FAQ)

Q1. Cursor Agent Mode로 마이그레이션할 때 기존 비즈니스 로직이 손실될 수 있나요?

Agent Mode는 @workspace 컨텍스트로 기존 코드를 분석한 뒤 변환하므로 로직 보존율이 높습니다. 다만 복잡한 미들웨어 체인이나 동적 라우팅은 수동 검증이 필요합니다. 변환 전에 기존 API의 통합 테스트를 먼저 작성하여 동작을 검증한 뒤 마이그레이션하는 것을 권장합니다.

Q2. Docs 인덱싱과 일반 채팅의 차이는 무엇인가요?

일반 채팅은 모델의 학습 데이터(특정 시점까지)에 의존하지만, Docs 인덱싱은 지정한 공식 문서의 최신 내용을 실시간으로 참조합니다. NestJS v10에서 v11로 업데이트된 API 변경사항도 인덱싱된 문서를 통해 정확하게 반영됩니다. @Docs 태그로 특정 문서를 프롬프트에 직접 참조할 수 있습니다.

Q3. 32개 엔드포인트 전체를 한 번의 프롬프트로 변환할 수 있나요?

기술적으로 가능하지만 권장하지 않습니다. 컨텍스트 윈도우 제한으로 인해 후반부 엔드포인트의 품질이 저하될 수 있습니다. 도메인 단위(결제, 사용자, 주문 등)로 나누어 5~8개씩 변환하고, 각 단계에서 테스트를 실행하여 검증하는 점진적 접근이 안정적입니다.

다른 도구 둘러보기

Grok 실시간 뉴스 분석 및 팩트체킹 베스트 프랙티스 가이드 모범사례 Devin 멀티파일 리팩토링 위임 베스트 프랙티스: 명세서, 브랜치 격리, 코드 리뷰 체크포인트 완벽 가이드 모범사례 Bolt 케이스 스터디: 솔로 개발자가 주말 48시간 만에 풀스택 SaaS MVP를 출시한 방법 사례 미드저니 캐릭터 컨셉아트 케이스 스터디: 인디 게임 스튜디오가 200개 에셋의 일관성을 유지한 워크플로우 사례 Antigravity AI 설치 및 설정 가이드: Python SDK, API 키 관리, Blender 통합까지 가이드 Runway Gen-3 Alpha AI 영상 생성 완벽 가이드: 계정 설정부터 렌더링 내보내기까지 가이드 Replit Agent vs Cursor AI vs GitHub Copilot Workspace 비교: 솔로 개발자를 위한 풀스택 프로토타이핑 완벽 가이드 (2026) 비교 v0에서 재사용 컴포넌트 블록으로 멀티페이지 SaaS 랜딩 사이트 만들기 완벽 가이드 방법 Kling AI vs Runway Gen-3 vs Pika Labs 비교: AI 영상 생성 품질·가격·제어력 완벽 분석 (2026) 비교 Claude 3.5 Sonnet vs GPT-4o vs Gemini 1.5 Pro 장문 요약 비교: 컨텍스트 윈도우, 정확도, 토큰 비용 완벽 분석 (2025) 비교 Midjourney v6 vs DALL-E 3 vs Stable Diffusion XL 제품 사진 비교: 포토리얼리즘, 프롬프트 제어, 이미지당 비용 분석 비교 Runway Gen-3 Alpha vs Pika 1.0 vs Kling AI 비교: 숏폼 영상 광고 제작을 위한 모션 품질·프롬프트 정확도·초당 가격 완벽 분석 (2026) 비교 BMI 계산기 - 무료 온라인 체질량지수 측정 도구 계산기 은퇴 저축 계산기 - 무료 온라인 노후 자금 시뮬레이터 계산기 401(k) 클리프 베스팅 스케줄이란? 퇴사 시 회사 매칭금이 어떻게 달라지는지 쉽게 설명 설명 중소기업을 위한 13주 현금흐름 예측 모범 사례: 주간 업데이트, 수금 추적, 시나리오 플래닝 모범사례 다점포 레스토랑 그룹 매입채무 자동화 사례: OCR 캡처·승인 라우팅·주간 지급으로 인보이스 처리 시간 단축 사례 아마존 PPC 사례: 프라이빗 라벨 건강기능식품 브랜드가 네거티브 키워드 마이닝과 Exact Match로 ACOS를 낮춘 방법 사례 Antigravity vs Jasper vs Copy.ai 비교: AI 브랜드 보이스 일관성, 콘텐츠 품질 및 협업 기능 완벽 분석 (2026) 비교 아파트 승인 준비도 퀴즈: 첫 자취생을 위한 신용점수·소득·코사이너 셀프 진단 자가진단