# CLAUDE.md ## Project Overview DPOT - Next.js 15 App Router 기반 Creators Support and donate platform frontend (https://dpot.web.or.kr) - **Framework**: Next.js 15.3+ (App Router, Server Components) - **React**: 19.1+ - **Language**: TypeScript 5 - **Backend API**: https://localhost:4000 (ASP.NET Core Minimal API) ## Project Structure ``` app/ ├── (auth)/ → 인증 (login, register, forgot-password, reset-password, welcome, approval) ├── (main)/ → 메인 레이아웃 그룹 │ ├── (account)/ → 계정 관리 (profile, change-password, change-email 등) │ ├── (forum)/ → 게시판 (board, post, comment, latest) │ ├── channel/ → 채널 상세 ([channelSID]) │ ├── note/ → 쪽지 (inbox, send) │ ├── notification/→ 알림 목록 │ ├── support/ → 고객지원 (faq, guide, contact) │ └── docs/ → 문서 페이지 ├── widget/ → OBS 위젯 (alert, goal, rank, crew — 별도 레이아웃) ├── remote/ → 후원 리모콘 ([channelSID] — 별도 레이아웃) ├── api/ → Route Handler (auth, channel, donation, note, notification, payment, forum 등) ├── auth/ → 인증 관련 ├── component/ → 공통 레이아웃 컴포넌트 │ ├── channel/ → ChannelSidebar (좌측), ChannelSidebarItem │ ├── NotificationBell, ProfileDropdown, ChargeModal │ └── Layout, PopupModal, Editor └── styles/ → 글로벌 + 컴포넌트 SCSS components/ui/ → shadcn/ui 컴포넌트 (accordion, button, checkbox, dialog, dropdown-menu, input, label, select, textarea, HotIndicator) contexts/ → React Context Provider ├── authProvider.tsx → 로그인 상태 관리, 토큰 갱신 ├── memberProvider.tsx → 현재 사용자 정보 ├── configProvider.tsx → 시스템 설정 (initialConfig prop, React.cache) ├── signalrProvider.tsx → SignalR WebSocket (채팅) └── themeProvider.tsx → 테마 관리 hooks/ → 커스텀 훅 (useAuth, useChat, useDragScroll, useTheme, useErrorAlert, useDonationAlert, useDonationHub, useNotification) lib/ ├── api/ → 서버 사이드 API 호출 함수 (Server Actions) │ ├── auth.ts → 인증 API │ ├── account.ts → 계정 관련 API │ ├── system.ts → 시스템 설정 API │ ├── forum/ → board.ts, post.ts │ └── page/ → document.ts, faq.ts └── utils/ ├── client.ts → 클라이언트 유틸 (fetchApi, cn, formatDate, throwError) ├── server.ts → 서버 유틸 (fetchJson, getAccessToken, checkPermission, getSignalRChatUrl) └── permission.ts → 권한 체크 types/ → TypeScript 타입 정의 ├── response/ → API 응답 타입 (common, account, forum, page) ├── request/ → 요청 페이로드 타입 ├── forum/ → 게시판 도메인 타입 (post, comment, board, boardGroup 등) ├── account/ → 계정 타입 (member, loginLog) ├── chat.ts, broadcast.ts, config.ts └── editor.min.d.ts → CKEditor 타입 constants/ → 상수 정의 (common.ts, forum.ts) middleware.ts → 인증 미들웨어 (토큰 검증, 리다이렉트) ``` ## Code Style Rules - 인덴트: 탭 사용 - PK/ID 변수명: `memberID`, `postID` (camelCase + 대문자 ID) - 클라이언트 컴포넌트: 파일 최상단에 `'use client'` 선언 - 서버 전용 함수: `'use server'` 선언 (Server Actions, lib/utils/server.ts) - 컴포넌트 파일명: PascalCase (`PopupModal.tsx`, `Layout.tsx`) - 페이지/라우트: 소문자 kebab-case 디렉토리 (`support/faq/`) - 스타일: `app/styles/` 에 컴포넌트별 SCSS 파일 (inline CSS 사용 금지 → SCSS 또는 Tailwind) - SCSS 클래스명: BEM 네이밍 (`block__element--modifier`) - 파일 내용의 마지막 줄 제거 (빈 줄 없이 끝남) - type 을 지정할 때 `|` 문자 양쪽에 공백 제거해(예시로 `string|null|undefined`) - button 태그에 submit type이 아니면 `type="button"` 필수 - C# 람다 `) => {` 한 줄에 붙여 작성 (개행 금지) — Frontend에서도 동일 스타일 적용 - `if (loading) return
준비 중...
;` 이런 식으로 한 줄로 처리하지 말고 중괄호 사용해줘 그리고 다음 줄로 개행을 하도록 해 ## Architecture Rules - **서버 컴포넌트가 기본** — `'use client'` 없으면 RSC - **클라이언트 상태**: React Context (AuthProvider, MemberProvider, ConfigProvider) - **API 프록시 패턴**: 클라이언트 → `app/api/[도메인]/[...path]/route.ts` → 백엔드 - 클라이언트에서 직접 백엔드 호출 안 함 (CORS, 쿠키 처리) - **서버 데이터 흐름**: Server Component → `fetchJson()` → 백엔드 직접 호출 - **인증**: JWT Bearer 토큰 (accessToken/refreshToken, httpOnly 쿠키) - **실시간**: SignalR WebSocket - AppHub (`/hubs/app`) — 채팅, 알림, 쪽지, 접속자, 크루 초대 - DonationHub (`/hubs/donation`) — 후원 위젯/리모콘 - **결제**: 다날 PG (`@danalpay/javascript-sdk`) ## Code Conventions ### 사용하는 패턴 - `fetchApi