개요
기술 스택
핵심 프레임워크
| 라이브러리 | 버전 | 용도 |
|---|---|---|
| Next.js | 16.2.6+ | 풀스택 React 프레임워크 (App Router) |
| React | 19.2.3 | UI 라이브러리 |
| TypeScript | 5 | 정적 타입 시스템 |
UI / 스타일링
| 라이브러리 | 버전 | 용도 |
|---|---|---|
| Tailwind CSS | 4 | 유틸리티 기반 CSS 프레임워크 |
| Radix UI | - | 접근성 기반 헤드리스 컴포넌트 |
| shadcn/ui (owned-fork) | - | Lumie가 직접 관리하는 포크된 컴포넌트 (components/ui/) |
| Lucide React | - | 아이콘 라이브러리 |
| CVA (class-variance-authority) | - | 컴포넌트 변형(variant) 관리 |
| FullCalendar | 6.1.20 | 일정/캘린더 컴포넌트 |
| Recharts | 3.7.0 | 데이터 시각화 차트 |
상태 관리 / 데이터 패칭
| 라이브러리 | 버전 | 용도 |
|---|---|---|
| TanStack React Query | 5.90.20 | 서버 상태 관리 및 데이터 페칭 |
| Zustand | 5.0.11 | 클라이언트 전역 상태 관리 |
| React Hook Form | 7.71.1 | 폼 상태 관리 |
| Zod | 4.3.6 | 스키마 유효성 검사 |
| @hookform/resolvers | - | RHF + Zod 연동 |
| orval | - | BE OpenAPI 스냅샷에서 React Query 훅 코드 생성 |
통신
| 라이브러리 | 용도 |
|---|---|
| STOMP / SockJS | WebSocket 실시간 통신 |
테스팅
| 라이브러리 | 버전 | 용도 |
|---|---|---|
| Playwright | 1.58.1+ | E2E 테스트 (API / 플로우 / UI / SSR) |
| Vitest + RTL | - | 유닛/컴포넌트 테스트 |
프로젝트 구조
lumie-frontend/
├── src/
│ ├── shared/ # 공통 기반 인프라
│ │ ├── api/ # API 클라이언트 팩토리, orval 뮤테이터, adaptMutation
│ │ ├── config/ # 환경 설정 (ENV.API_URL = '/api')
│ │ ├── lib/ # 유틸리티 함수, customDomain 해석
│ │ ├── providers/ # QueryProvider, AuthModalProvider
│ │ ├── types/ # 공통 타입 정의
│ │ └── ui/ # Lumie 커스텀 UI 래퍼
│ ├── entities/ # 비즈니스 도메인 (19개 엔티티)
│ │ ├── session/ # 인증 상태 (useMe React Query)
│ │ ├── student/
│ │ ├── exam/
│ │ ├── tenant/
│ │ └── ... # 각 엔티티: api/generated.ts (orval) + api/queries.ts + model/ + index.ts
│ ├── features/ # 기능 모듈 (30+ 피처)
│ │ ├── auth/
│ │ ├── exam-management/
│ │ ├── admin-dashboard/
│ │ └── ...
│ └── widgets/ # 레이아웃 컴포넌트
│ ├── admin-sidebar/
│ ├── student-sidebar/
│ ├── header/
│ ├── auth-modal/
│ └── landing-templates/
├── app/ # Next.js App Router 페이지
│ ├── (auth)/ # 로그인/회원가입 그룹 레이아웃
│ ├── (marketing)/ # 마케팅 공개 페이지 (SSR)
│ ├── [customId]/ # 테넌트 랜딩 페이지 (SSR, 공개)
│ ├── admin/ # 관리자 페이지 (CSR, 인증 필요)
│ ├── dashboard/ # 학생 대시보드 (CSR, 인증 필요)
│ └── api/ # Next.js Route Handler (BE 프록시)
│ └── [...path]/ # 모든 /api/* 요청을 BE 게이트웨이로 포워딩
├── components/
│ └── ui/ # owned-fork shadcn 프리미티브 (비즈니스 로직 금지)
├── e2e/ # Playwright E2E 테스트
│ ├── api/ # API 테스트
│ ├── flows/ # 사용자 플로우 테스트
│ ├── ui/ # 브라우저 UI 테스트
│ ├── ssr/ # SSR 회귀 테스트
│ ├── config/ # 전역 setup/teardown
│ ├── fixtures/ # 테스트 픽스처
│ └── utils/ # 테스트 유틸리티
├── openapi.json # BE OpenAPI 스냅샷 (orval 코드 생성 입력)
├── orval.config.ts # orval 코드 생성 설정
└── ...설정 파일들
경로 별칭 (Path Aliases)
tsconfig.json에 정의된 경로 별칭으로 임포트를 단순화합니다.
{
"compilerOptions": {
"paths": {
"@/*": ["./*"],
"@/src/*": ["./src/*"],
"@/shared/*": ["./src/shared/*"],
"@/entities/*": ["./src/entities/*"],
"@/features/*": ["./src/features/*"],
"@/widgets/*": ["./src/widgets/*"]
}
}
}
사용 예:
import { Button } from "@/shared/ui/button";
import { useMe } from "@/entities/session";
import { LoginForm } from "@/features/auth";
import { AdminSidebar } from "@/widgets/admin-sidebar";
환경 설정
.env 파일은 제거되었습니다(2026-06-01). 로컬 개발 설정은 Tiltfile의 local_resource serve_env로 런타임에 주입됩니다.
# Tiltfile이 local_resource serve_env로 주입하는 값
NEXT_PUBLIC_API_BASE=https://dev.lumie-infra.com
NEXT_PUBLIC_API_BASE는 게이트웨이 오리진(예: https://dev.lumie-infra.com)입니다. 브라우저 코드는 이 변수를 직접 사용하지 않습니다. shared/config/env.ts의 ENV.API_URL은 항상 /api로 고정되어 있으며, 브라우저 요청은 동일 오리진의 Next.js 프록시(app/api/[...path]/route.ts)를 통해 BE 게이트웨이로 전달됩니다.
// src/shared/config/env.ts
export const ENV = {
API_URL: '/api',
} as const;
로컬 개발 워크플로우
Tilt가 FE 라이프사이클을 클러스터 서비스와 함께 관리합니다.
# 워크스페이스 루트에서
.github/tilt-up.sh # 클러스터 서비스 + FE local_resource 동시 시작
# → http://localhost:3000
FE는 항상 개발자 로컬 머신에서 실행됩니다. dev 클러스터에 배포하지 않습니다.
중요 제약:
- ❌
next dev를 dev 클러스터에 절대 배포하지 마세요. Turbopack 16.2+ HMR이 Traefik HTTP/2 ALPN을 통하면 클라이언트 hydration이 교착 상태에 빠집니다. - 공유 프리뷰 URL이 필요한 경우
next build && next start(프로덕션 이미지)를 사용 하세요.
npm 스크립트
# 개발 서버 시작 (Tilt로 관리됨, 직접 실행도 가능)
npm run dev
# 프로덕션 빌드
npm run build
# 프로덕션 서버 시작
npm run start
# TypeScript 타입 검사
npm run type-check
# ESLint 린팅
npm run lint
# 유닛/컴포넌트 테스트 (Vitest + RTL)
npm run test:unit
# E2E 테스트 전체 실행
npm run test:e2e
# API 테스트만 실행
npm run test:e2e:api
# 플로우 테스트만 실행
npm run test:e2e:flows
# 로컬 환경 테스트
npm run test:e2e:local
# k3s 환경 테스트
npm run test:e2e:k3s
# mirrord 환경 테스트
npm run test:e2e:mirrord
# Playwright 리포트 확인
npm run test:e2e:report
주요 의존성 요약
FSD 레이어별 의존성 역할을 정리합니다.
shared/api → API 클라이언트 팩토리, orval 뮤테이터, adaptMutation, tryRefreshToken
shared/config → ENV.API_URL = '/api' (단일 엔드포인트)
shared/ui → Button, Input, Modal 등 Lumie 커스텀 래퍼
entities/session → useMe (React Query), getServerUser (SSR)
entities/* → Zod 스키마 + orval-generated React Query 훅 + queries.ts 래퍼
features/* → 비즈니스 로직 + UI 조합
widgets/* → 페이지 레이아웃 조립
app/* → Next.js 라우트 및 페이지 진입점
app/api/[...path] → BE 게이트웨이 프록시 (Origin·Set-Cookie·Content-Encoding 재작성)
자세한 아키텍처 설명은 아키텍처 문서를 참고하세요.