Next.js 15NestJS 11MikroORMPostgreSQLTanStack Query
Smart Reserve
뷰티 살롱/네일 숍 예약 관리 SaaS

역할
CTO / Full-Stack Engineer
기간
2025
클라이언트
일본 뷰티 살롱 체인 (Narimoto)
01문제
다중 매장 뷰티 살롱에서 예약, 직원 관리, 재고, 매출 집계가 수기/엑셀로 처리되어 실시간 관리가 불가능. POS/CRM/HR이 통합된 시스템이 필요했음.
02판단
ORM 선택: TypeORM vs MikroORM
선택
MikroORM
이유
Unit of Work 패턴으로 트랜잭션 안정성 확보. 70+ 엔티티 관리에 적합
트레이드오프
TypeORM 대비 커뮤니티 작지만, 데이터 정합성이 더 중요한 도메인
데이터 격리: 애플리케이션 필터링 vs PostgreSQL RLS
선택
PostgreSQL RLS
이유
DB 레벨에서 강제적 테넌트 데이터 격리. 애플리케이션 버그로도 타사 데이터 노출 방지
서버 상태 관리: SWR vs TanStack Query
선택
TanStack Query
이유
stale-while-revalidate 전략으로 대시보드 쿼리 최적화. 복잡한 캐시 무효화 제어
03결과
✓
예약 대기 시간 70% 단축
✓
매장 운영 효율 45% 개선
✓
Next.js 15 App Router 서버 컴포넌트로 초기 로딩 40% 개선
04아키텍처
graph TB
subgraph Client["클라이언트"]
Web["Next.js 15<br/>App Router"]
end
subgraph API["API Layer"]
NestJS["NestJS 11<br/>REST API"]
Auth["JWT Auth<br/>Guard"]
end
subgraph DB["데이터베이스"]
PG["PostgreSQL<br/>+ RLS"]
MikroORM["MikroORM<br/>Unit of Work"]
end
subgraph Infra["인프라"]
CloudRun["Google<br/>Cloud Run"]
Vercel["Vercel"]
end
Web -->|TanStack Query| NestJS
NestJS --> Auth
Auth --> MikroORM
MikroORM --> PG
Web --> Vercel
NestJS --> CloudRun
05기술 스택
frontend
Next.js 15 (App Router), TanStack Query, Radix UI
backend
NestJS 11, MikroORM, TypeScript 5
database
PostgreSQL (RLS)
infra
Google Cloud Run, Vercel