quizverse/
├─ build.gradle
├─ src/
│ └─ main/
│ ├─ java/
│ │ └─ com/quizverse/
│ │ ├─ QuizverseApplication.java
│ │ ├─ config/ # 보안, Swagger, CORS
│ │ ├─ domain/ # 엔티티, 도메인 로직
│ │ ├─ service/ # 서비스 (비즈니스 로직)
│ │ ├─ repository/ # JPA 레포지토리
│ │ ├─ controller/ # REST API 컨트롤러
│ │ ├─ dto/ # 요청/응답 DTO
│ │ ├─ security/ # JWT, 필터
│ │ ├─ storage/ # S3/파일 스토리지
│ │ └─ exception/ # 예외 처리
│ │
│ ├─ react/ # 프론트엔드 (React)
│ │ ├─ package.json
│ │ └─ src/
│ │ ├─ app/ # 라우터, 전역 상태, 전역 스타일
│ │ ├─ layout/ # 메인 레이아웃 (Header/Footer/Chatbot)
│ │ ├─ pages/ # 라우팅 단위 페이지 (Home, Book, Study 등)
│ │ ├─ features/ # 기능 단위 묶음 (quiz, studyroom, modal 등)
│ │ ├─ components/ # 공용 UI 컴포넌트 (layout/common/sidebar 등)
│ │ ├─ routes/ # PrivateRoute, ErrorPage 등 라우팅 보조
│ │ ├─ api/ # axios 인스턴스, API 모듈
│ │ ├─ hooks/ # 커스텀 훅
│ │ ├─ lib/ # 유틸 함수 모음
│ │ └─ assets/ # 이미지, 아이콘
│ │
│ └─ resources/
│ ├─ application.yml
│ └─ db/migration/ # Flyway 마이그레이션
│
├─ infra/
│ ├─ docker/
│ │ ├─ backend.Dockerfile
│ │ ├─ web.Dockerfile
│ │ └─ docker-compose.yml
│ └─ scripts/
│ ├─ dev.sh
│ └─ seed.sql
│
├─ .github/workflows/ci.yml # CI/CD 파이프라인
├─ README.md
├─ .gitignore
└─ LICENSE (선택)
1) app — “전역 뼈대”
역할: 앱 시작과 동시에 필요한 전역 설정/초기화.
넣는 것: 라우터 설정(router.jsx), 전역 상태(store), 전역 Provider(Theme, Query, i18n), 전역 스타일(index.css).
예시: <RouterProvider router={router} />, <QueryClientProvider>, <ReduxProvider>.
주의: 화면 로직/비즈니스 로직 넣지 말기. “앱이 켜질 때 필요한 세팅”만.
2) layout — “공통 틀(껍데기)”
역할: 페이지마다 반복되는 UI 프레임.
넣는 것: MainLayout.jsx(Header/Sidebar/Footer/<Outlet/>), AuthLayout.jsx 등.
예시: Header + CategoryHeader + <Outlet/> + Footer + Chatbot.
주의: 개별 페이지 내용은 넣지 말고, 틀만!
3) pages — “URL = 화면”
역할: 라우팅 대상으로 직접 랜더링되는 페이지 컴포넌트.
넣는 것: HomePage.jsx, LoginPage.jsx, BookDetailPage.jsx…
예시: /, /account/login, /book/:id.
주의: 무거운 비즈니스 로직은 여기서 직접 하지 말고 features나 hooks로 분리.
4) features — “도메인(기능) 묶음”
역할: 특정 기능에 필요한 UI + API + 훅 + 스타일을 한 폴더에 모으기.
구성 예시:
features/quiz/
├─ components/ # 퀴즈 전용 UI
├─ api.js # 퀴즈 API
├─ hooks.js # 퀴즈 상태/로직 훅
└─ styles/ # (있다면) 전용 스타일
장점: 기능별로 캡슐화 → 유지보수/이동/삭제가 쉬움.
주의: 공용이 아닌 그 기능에서만 쓰는 것만 담기.
5) components — “공용 UI 부품”
역할: 여러 페이지/기능에서 재사용되는 발표용 UI 조각.
하위 분류 추천:
components/layout/ (Header, Footer, CategoryHeader)
components/common/ (Button, Input, Modal, Pagination)
components/sidebar/ (EditSidebar, MypageSidebar)
주의: 특정 도메인 로직이 섞이면 features로 이동.
6) routes — “라우팅 보조”
역할: 라우팅과 관련된 도우미만.
넣는 것: PrivateRoute.js, 에러 경로 컴포넌트(ErrorPage404.jsx), 로더/액션.
주의: 실제 페이지는 pages/에, routes에는 가드/보조만 남기기.
7) api — “통신 레이어”
역할: 서버 통신(HTTP) 관련 모든 것의 중심.
넣는 것:
apiClient.js (axios 인스턴스, baseURL, interceptors, 401 리프레시 등)
리소스별 모듈: authApi.js, bookApi.js, studyApi.js …
주의: 컴포넌트에서 바로 axios 쓰지 말고 항상 api 모듈을 통해 호출.
8) hooks — “공용 상태/로직 훅”
역할: 뷰와 분리된 재사용 가능한 로직(폼, 페이징, 스크롤, auth 상태 등).
예시: useAuth(), useDebounce(), usePagination().
주의: 특정 기능 전용이면 features/XXX/hooks.js로!
9) lib — “유틸/도메인 무관 도구”
역할: 순수 함수(포맷터, 날짜 계산, 유효성 검사 등).
예시: formatDate.ts, assert.ts, downloadFile.ts.
주의: React 의존(X). 상태/렌더링(X). 순수 로직만.
10) assets — “정적 리소스”
역할: 이미지, 아이콘, 폰트, Lottie 등.
주의: 페이지/기능 전용 이미지는 가능하면 그 폴더 근처에 두고, 공용 이미지만 assets/에.
🔎 10초 결정 트리
URL로 직접 들어오는 화면? → pages/
여러 곳에서 쓰는 버튼/모달? → components/
특정 기능(퀴즈/스터디룸/모달) 전용 묶음? → features/기능명/
라우터 가드/에러/로더? → routes/
HTTP 통신/인스턴스/REST 함수? → api/
재사용 로직(React 훅)? → hooks/ (or features/기능/hooks.js)
순수 유틸? → lib/
이미지/아이콘? → assets/
전역 설정/Provider/스토어/라우터 선언? → app/
Header/Footer/Outlet을 묶는 공통 틀? → layout/
🧩 네이밍 룰(딱 4개)
페이지: SomethingPage.jsx (검색이 쉬움)
도메인 기능: features/quiz/{components|api.js|hooks.js}
공용 컴포넌트: components/common/Button.jsx
스타일: 같은 폴더에 Component.module.css (근접 배치)