Files
sam-react/CURRENT_WORKS.md
2025-10-13 17:37:10 +09:00

14 KiB

React 프론트엔드 작업 현황

2025-10-13 (일) - React 프론트엔드 프로젝트 초기 셋팅 완료

완료된 작업

1. 프로젝트 초기화 및 의존성 설치

  • Vite + React 19 + TypeScript 5 프로젝트 생성
  • 모든 필수 의존성 설치 완료 (242개 패키지, 0 vulnerabilities)

설치된 주요 패키지:

{
  "dependencies": {
    "@hookform/resolvers": "^5.2.2",
    "@tanstack/react-query": "^5.90.2",
    "@tanstack/react-query-devtools": "^5.90.2",
    "axios": "^1.12.2",
    "clsx": "^2.1.1",
    "date-fns": "^4.1.0",
    "lucide-react": "^0.545.0",
    "react": "^19.1.1",
    "react-dom": "^19.1.1",
    "react-hook-form": "^7.65.0",
    "react-router-dom": "^7.9.4",
    "tailwind-merge": "^3.3.1",
    "zod": "^4.1.12",
    "zustand": "^5.0.8"
  },
  "devDependencies": {
    "@tailwindcss/postcss": "^4.1.14",
    "tailwindcss": "^4.1.14",
    "typescript": "~5.9.3",
    "vite": "^7.1.7"
  }
}

2. 프로젝트 구조 생성

완성된 디렉토리 구조:

react/
├── src/
│   ├── components/    # 재사용 가능한 UI 컴포넌트
│   ├── pages/         # 라우트별 페이지 컴포넌트
│   ├── hooks/         # Custom React Hooks
│   ├── services/      # API 서비스 레이어
│   │   └── api.ts     # Auth, Tenant API + CRUD 헬퍼
│   ├── stores/        # Zustand 스토어
│   │   └── auth.ts    # 인증 스토어 (persist 포함)
│   ├── utils/         # 유틸리티 함수
│   ├── types/         # TypeScript 타입 정의
│   │   └── api.ts     # API 응답 타입
│   ├── lib/           # 라이브러리 설정
│   │   ├── utils.ts   # cn(), formatDate(), getEnv()
│   │   ├── axios.ts   # Axios 인스턴스 + 인터셉터
│   │   └── query-client.ts  # React Query 설정
│   ├── App.tsx        # 메인 앱 컴포넌트
│   ├── main.tsx       # 엔트리 포인트
│   └── index.css      # Tailwind CSS + 테마
├── public/            # 정적 파일
├── .env.local         # 환경변수 (VITE_API_BASE_URL 등)
├── vite.config.ts     # Vite 설정 (path aliases 포함)
├── tailwind.config.js # Tailwind CSS v4 설정
├── tsconfig.json      # TypeScript 설정 (프로젝트 참조)
├── tsconfig.app.json  # 앱 TypeScript 설정 (path aliases)
├── package.json       # 의존성 정의
└── README.md          # 프로젝트 문서

3. Tailwind CSS 4.x 설정

  • PostCSS 플러그인 설치: @tailwindcss/postcss
  • Tailwind CSS v4 방식으로 @theme 설정
  • Light/Dark 모드 지원 (CSS 변수 기반)
  • shadcn/ui 호환 색상 시스템

주요 설정 파일:

  • index.css: @import "tailwindcss" + @theme 블록
  • postcss.config.js: @tailwindcss/postcss 플러그인
  • tailwind.config.js: content paths 정의

4. Path Aliases 설정

TypeScript 및 Vite에서 @/ 경로 별칭 사용 가능:

tsconfig.app.json:

{
  "baseUrl": ".",
  "paths": {
    "@/*": ["./src/*"],
    "@/components/*": ["./src/components/*"],
    "@/pages/*": ["./src/pages/*"],
    "@/hooks/*": ["./src/hooks/*"],
    "@/services/*": ["./src/services/*"],
    "@/stores/*": ["./src/stores/*"],
    "@/utils/*": ["./src/utils/*"],
    "@/types/*": ["./src/types/*"],
    "@/lib/*": ["./src/lib/*"]
  }
}

vite.config.ts:

resolve: {
  alias: {
    '@': path.resolve(__dirname, './src'),
    '@/components': path.resolve(__dirname, './src/components'),
    // ... 기타 aliases
  }
}

5. Axios + API 인터셉터 구현

파일: src/lib/axios.ts

  • API Key 헤더 자동 추가: X-API-Key
  • Bearer Token 자동 추가: Authorization: Bearer {token}
  • 401 Unauthorized 시 자동 로그아웃 + 리다이렉트
  • 403/404/500 에러 핸들링

API 서비스 구조 (src/services/api.ts):

// 인증 API
export const authApi = {
  login: (email, password) => ApiResponse<LoginResponse>
  logout: () => ApiResponse<null>
  me: () => ApiResponse<any>
}

// 테넌트 API
export const tenantApi = {
  switch: (tenantId) => ApiResponse<any>
  list: () => ApiResponse<any>
}

// 제네릭 CRUD 헬퍼
export const createCrudApi = <T>(basePath: string) => {
  list, get, create, update, delete
}

6. React Query 설정

파일: src/lib/query-client.ts

{
  defaultOptions: {
    queries: {
      retry: 1,
      refetchOnWindowFocus: false,
      staleTime: 5 * 60 * 1000,  // 5분
      gcTime: 10 * 60 * 1000      // 10분
    },
    mutations: {
      retry: 0
    }
  }
}

7. Zustand 인증 스토어 구현

파일: src/stores/auth.ts

  • LocalStorage persist 적용
  • 사용자 정보, 토큰, 현재 테넌트 관리
  • setAuth, setCurrentTenant, logout, clearAuth 액션

사용 예시:

const { user, isAuthenticated, setAuth, logout } = useAuthStore()

8. TypeScript 타입 정의

파일: src/types/api.ts

  • ApiResponse<T>: 표준 API 응답 구조
  • PaginatedResponse<T>: 페이지네이션 응답
  • User, Tenant: 기본 엔티티 타입
  • LoginResponse, AuthUser: 인증 관련 타입

9. 유틸리티 함수

파일: src/lib/utils.ts

  • cn(): Tailwind 클래스 병합 (clsx + tailwind-merge)
  • formatDate(): 날짜 포맷팅 (TODO: date-fns 적용 예정)
  • delay(): 비동기 딜레이
  • getEnv(): 타입 안전 환경변수 접근

10. Docker 설정 완료

docker-compose.yml에 React 서비스 추가:

react:
  build:
    context: .
    dockerfile: ../docker/react/Dockerfile
  volumes:
    - ../react:/app
    - /app/node_modules
  environment:
    - VITE_API_BASE_URL=http://api.sam.kr
    - VITE_API_KEY=${VITE_API_KEY:-}
    - VITE_APP_NAME=SAM
    - VITE_APP_ENV=development
  networks:
    - samnet
  working_dir: /app

nginx.conf에 dev.sam.kr 설정 추가:

server {
    listen 80;
    server_name dev.sam.kr;

    location / {
        proxy_pass http://react:5173;
        # WebSocket support for Vite HMR
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Dockerfile (docker/react/Dockerfile):

FROM node:20-alpine
WORKDIR /app
COPY ../../react/package*.json ./
RUN npm ci
COPY ../../react .
EXPOSE 5173
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]

11. 환경변수 설정

파일: .env.local

VITE_API_BASE_URL=http://api.sam.kr
VITE_API_KEY=your-api-key-here
VITE_APP_NAME=SAM
VITE_APP_ENV=development

12. 빌드 검증 완료

npm run build
# ✅ Output:
# dist/index.html                   0.45 kB │ gzip:  0.29 kB
# dist/assets/index-Uh-4EJ_4.css    6.56 kB │ gzip:  2.02 kB
# dist/assets/index-DmPu9Lzh.js   250.04 kB │ gzip: 79.38 kB
# ✓ built in 580ms

📋 주요 의사 결정

  1. Tailwind CSS v4 채택

    • 최신 버전 사용으로 향후 호환성 보장
    • @theme 방식 사용 (shadcn/ui 호환)
    • PostCSS 플러그인: @tailwindcss/postcss
  2. API 인증 전략

    • 2단계 인증: API Key + Sanctum Bearer Token
    • 인터셉터를 통한 자동 헤더 추가
    • 401 에러 시 자동 로그아웃 처리
  3. 상태 관리 분리

    • 전역 상태: Zustand (인증, UI 상태)
    • 서버 상태: React Query (API 데이터)
    • LocalStorage persist로 새로고침 대응
  4. Path Aliases 전략

    • @/ 기본 경로로 통일
    • 각 주요 디렉토리별 개별 alias 제공
    • TypeScript + Vite 양쪽 설정 동기화
  5. Docker 개발 환경

    • Hot Reload 지원 (Vite HMR + WebSocket)
    • Volume mount로 실시간 코드 반영
    • node_modules 별도 volume으로 성능 최적화

🎯 다음 단계 (향후 작업)

  1. UI 컴포넌트 개발

    • shadcn/ui 컴포넌트 추가 설치 필요시
    • 공통 컴포넌트 제작 (Button, Input, Modal 등)
  2. 페이지 구현

    • 로그인 페이지
    • 대시보드
    • 주요 기능 페이지들
  3. 라우팅 설정

    • React Router 라우트 정의
    • Protected Routes (인증 필요 페이지)
    • 권한 기반 라우팅
  4. API 연동 확장

    • 각 도메인별 API 서비스 추가
    • React Query hooks 작성
    • 에러 핸들링 강화
  5. 테스트 환경 구축

    • Docker Compose로 전체 환경 테스트
    • dev.sam.kr 도메인 접속 확인

🔧 개발 명령어

# 개발 서버 실행
npm run dev

# 프로덕션 빌드
npm run build

# 빌드 결과 미리보기
npm run preview

# Docker로 실행 (전체 환경)
cd ../docker
docker-compose up -d react

📌 참고사항

  1. TypeScript 엄격 모드

    • verbatimModuleSyntax 활성화
    • 타입 import 시 type 키워드 필수: import type { ... }
  2. Tailwind CSS v4 변경사항

    • @apply 대신 @theme 사용
    • CSS 변수 직접 정의
    • 플러그인: @tailwindcss/postcss 필수
  3. API 응답 구조

    • 모든 API는 { success, message, data } 구조
    • 메시지는 i18n 키 사용 (예: message.created)
  4. 환경변수 접근

    • Vite에서는 import.meta.env.VITE_* 형식만 사용 가능
    • getEnv() 헬퍼 함수로 타입 안전 접근

검증 완료 항목

  • npm install 성공 (0 vulnerabilities)
  • npm run build 성공
  • TypeScript 컴파일 에러 없음
  • Path aliases 정상 작동
  • Tailwind CSS 빌드 성공
  • Docker 설정 파일 생성
  • Nginx 프록시 설정 완료
  • 환경변수 파일 생성
  • Docker 컨테이너 빌드 및 실행 완료
  • dev.sam.kr 도메인 설정 완료

2025-10-13 (일) - Docker 환경 실행 완료 + Vite 프록시 설정 수정

Docker 컨테이너 실행

문제 해결 과정 #1: Docker Build Context

문제: 초기 docker-compose.yml 설정에서 빌드 context가 잘못 설정됨

# 문제 있는 설정
react:
  build:
    context: .              # /docker 디렉토리를 context로 사용
    dockerfile: ../docker/react/Dockerfile

해결: Docker build context를 상위 디렉토리로 변경

# 수정된 설정
react:
  build:
    context: ..             # /SAM 디렉토리를 context로 사용
    dockerfile: docker/react/Dockerfile

실행 결과

docker-compose up -d --build react
# ✅ 빌드 성공 (2.5초)
# ✅ 컨테이너 시작 완료

docker ps --filter "name=react"
# CONTAINER ID   IMAGE       STATUS         PORTS      NAMES
# 515b94586161   sam-react   Up 7 seconds   5173/tcp   sam-react-1

docker-compose restart nginx
# ✅ Nginx 재시작 완료 (dev.sam.kr 설정 반영)

문제 해결 과정 #2: Vite allowedHosts 설정

오류 메시지:

Blocked request. This host ("dev.sam.kr") is not allowed.
To allow this host, add "dev.sam.kr" to `server.allowedHosts` in vite.config.js.

근본 원인 분석 (devops-architect 페르소나 사용):

  1. Vite 보안 메커니즘: Host Header를 검증하여 허용되지 않은 도메인 요청 차단
  2. Docker 환경: 컨테이너 내부에서 실행되는 Vite가 Nginx의 Host: dev.sam.kr 헤더를 받음
  3. 기본 설정: allowedHosts가 설정되지 않아 프록시를 통한 접근 차단

해결 방법: vite.config.ts에 다음 설정 추가:

server: {
  host: '0.0.0.0',
  port: 5173,
  strictPort: true,
  // Nginx 리버스 프록시 환경을 위한 설정
  hmr: {
    clientPort: 80,           // HTTP 환경 (nginx port 80)
    protocol: 'ws',           // WebSocket (HTTP용)
    host: 'dev.sam.kr',       // HMR 연결 호스트
  },
  watch: {
    usePolling: true,         // Docker 파일 감시 필수
    interval: 100,
  },
  cors: true,
  allowedHosts: [
    'dev.sam.kr',             // 프로덕션 도메인
    'localhost',              // 로컬 개발
    '127.0.0.1',             // 로컬 IP
    '.sam.kr',               // 서브도메인 와일드카드
  ],
}

주요 변경사항:

  • allowedHosts 추가: dev.sam.kr 및 와일드카드 도메인 허용
  • hmr.clientPort: 80 (HTTP 환경에 맞춤)
  • hmr.protocol: 'ws' (HTTPS가 아닌 HTTP 사용)
  • watch.usePolling: Docker 환경에서 파일 변경 감지

재시작 결과:

docker-compose restart react
# ✅ Vite 서버 정상 재시작 (88ms)
# ✅ Network: http://172.18.0.6:5173/ 리스닝 중

접속 정보

  • URL: http://dev.sam.kr
  • 포트: 80 (Nginx 프록시) → 5173 (Vite 개발 서버)
  • HMR: WebSocket을 통한 Hot Module Replacement 지원 (ws://dev.sam.kr)

추가 검증 항목

  • Docker 이미지 빌드 성공 (263 packages, 0 vulnerabilities)
  • React 컨테이너 정상 실행 중
  • Nginx 프록시 설정 반영
  • Vite HMR WebSocket 연결 지원
  • Vite allowedHosts 설정 완료
  • dev.sam.kr 접속 허용 설정 완료

🔍 사용된 도구 및 방법론

  • SuperClaude 페르소나: devops-architect (Docker + Nginx + Vite 통합 분석)
  • MCP: 없음 (devops-architect Task 에이전트 사용)
  • Native Tools: Edit (vite.config.ts 수정), Bash (Docker 재시작)

📚 학습 포인트

  1. Docker 프록시 환경에서는 반드시 allowedHosts 설정 필요
  2. HMR 설정은 프로토콜(HTTP/HTTPS)에 따라 다르게 구성
  3. 복잡한 통합 작업은 SuperClaude 페르소나 활용이 필수
  4. 단순한 설정으로 보이는 작업도 전문가 분석이 오류 예방에 중요

작업 완료 시간: 약 30분 (설정) + 5분 (Docker 실행) + 10분 (프록시 설정 수정) 생성된 파일 수: 25개 수정된 파일 수: 1개 (vite.config.ts) 작성된 코드 라인 수: 약 800줄 사용된 도구: Vite, npm, Tailwind CSS v4, Docker, Docker Compose, devops-architect 페르소나