본문으로 건너뛰기

개요

기술 스택

핵심 프레임워크

라이브러리버전용도
Next.js16.2.6+풀스택 React 프레임워크 (App Router)
React19.2.3UI 라이브러리
TypeScript5정적 타입 시스템

UI / 스타일링

라이브러리버전용도
Tailwind CSS4유틸리티 기반 CSS 프레임워크
Radix UI-접근성 기반 헤드리스 컴포넌트
shadcn/ui (owned-fork)-Lumie가 직접 관리하는 포크된 컴포넌트 (components/ui/)
Lucide React-아이콘 라이브러리
CVA (class-variance-authority)-컴포넌트 변형(variant) 관리
FullCalendar6.1.20일정/캘린더 컴포넌트
Recharts3.7.0데이터 시각화 차트

상태 관리 / 데이터 패칭

라이브러리버전용도
TanStack React Query5.90.20서버 상태 관리 및 데이터 페칭
Zustand5.0.11클라이언트 전역 상태 관리
React Hook Form7.71.1폼 상태 관리
Zod4.3.6스키마 유효성 검사
@hookform/resolvers-RHF + Zod 연동
orval-BE OpenAPI 스냅샷에서 React Query 훅 코드 생성

통신

라이브러리용도
STOMP / SockJSWebSocket 실시간 통신

테스팅

라이브러리버전용도
Playwright1.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.tsENV.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 재작성)

자세한 아키텍처 설명은 아키텍처 문서를 참고하세요.