DPOT - Next.js 15 App Router 기반 Creators Support and donate platform frontend (https://dpot.web.or.kr)
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 → 인증 미들웨어 (토큰 검증, 리다이렉트)
memberID, postID (camelCase + 대문자 ID)'use client' 선언'use server' 선언 (Server Actions, lib/utils/server.ts)PopupModal.tsx, Layout.tsx)support/faq/)app/styles/ 에 컴포넌트별 SCSS 파일 (inline CSS 사용 금지 → SCSS 또는 Tailwind)block__element--modifier)| 문자 양쪽에 공백 제거해(예시로 string|null|undefined)type="button" 필수) => { 한 줄에 붙여 작성 (개행 금지) — Frontend에서도 동일 스타일 적용if (loading) return <p className="studio-page__empty">준비 중...</p>; 이런 식으로 한 줄로 처리하지 말고 중괄호 사용해줘 그리고 다음 줄로 개행을 하도록 해'use client' 없으면 RSCapp/api/[도메인]/[...path]/route.ts → 백엔드
fetchJson() → 백엔드 직접 호출/hubs/app) — 채팅, 알림, 쪽지, 접속자, 크루 초대/hubs/donation) — 후원 위젯/리모콘@danalpay/javascript-sdk)fetchApi<T>() — 클라이언트에서 Route Handler 호출 (lib/utils/client.ts), 실패 시 자동 throw (에러 무시 시 { silent: true })fetchJson<T>() — 서버에서 백엔드 직접 호출 (lib/utils/server.ts)ResultDto<T> — 모든 API 응답 래퍼 ({ success, status, message, data, errors })cn() — Tailwind 클래스 병합 (clsx + tailwind-merge)dangerouslySetInnerHTML — 서버에서 받은 HTML 콘텐츠 렌더링(auth), (main)/(account), (main)/(forum) 으로 관련 페이지 그룹화notFound() — 데이터 없을 때 404 처리style.scss, 글로벌 globals.scsscommon.module.scss (레이아웃 그리드)components/ui/)--background, --foreground 등)ThemeProvider → SignalRProvider → AuthProvider → MemberProvider → ConfigProvider → {children}
ThemeProvider: 테마 관리 (라이트/다크 모드)SignalRProvider: WebSocket 연결 (AppHub) — accessToken, signalRUrl propAuthProvider: 로그인 상태 관리, 토큰 갱신MemberProvider: 현재 사용자 정보ConfigProvider: initialConfig prop으로 서버에서 설정 전달 (React.cache)ChannelSidebar): 채널 목록, 온/오프라인 LED, 시청자 수, 다크모드/다국어/즐겨찾기// app/api/{도메인}/[...path]/route.ts
export async function POST(request: NextRequest, { params }: { params: Promise<{ path: string[] }> }) {
const { path } = await params;
const endpoint = `/api/${path.join('/')}`;
const res: ResultDto = await fetchJson(endpoint, {
method: 'POST',
body: await request.arrayBuffer(),
headers: { 'Content-Type': request.headers.get('content-type') || '' }
});
return NextResponse.json(res);
}
# 개발 서버 (HTTPS, 포트 3000)
npm run dev
# 프로덕션 빌드
npm run build
# 프로덕션 실행
npm run start
# 린트
npm run lint