μ΄ λ¬Έμλ KFE3-e2e-Chwee-up-hajah νλ‘μ νΈμ ꡬ쑰, κΈ°μ , κ°λ° κ°μ΄λλΌμΈμ λν μμΈν κ°μλ₯Ό μ 곡ν©λλ€.
- νλ μμν¬: κ°λ°μ μν΄ Turbopackκ³Ό ν¨κ» Next.js 15+ (React 19+)λ₯Ό μ¬μ©ν©λλ€.
- μ€νμΌλ§: Tailwind CSS v4λ₯Ό μ¬μ©ν©λλ€.
packages/tailwind-configμμ μ€μ μ§μ€μμΌλ‘ μ€μ μ νμ©ν©λλ€. - λμμΈ μμ€ν
:
packages/uiμ 컀μ€ν λμμΈ μμ€ν μ΄ κ΅¬νλμ΄ μμ΅λλ€. ν΅μ¬ λμμΈ ν ν°(μμ, νμ΄ν¬κ·ΈλνΌ, κ°κ²©)μpackages/ui/src/theme.cssμ CSS λ³μλ‘ μ μλμ΄ μμ΅λλ€. μ΄ λ³μλ€μ Tailwind ν΄λμ€μμbg-[var(--color-primary-500)]μ κ°μ μμ κ° κ΅¬λ¬Έ(arbitrary value syntax)μ μ¬μ©νμ¬ νμ©ν΄μΌ ν©λλ€. - μν κ΄λ¦¬: μ μ ν΄λΌμ΄μΈνΈ μΈ‘ μν κ΄λ¦¬λ₯Ό μν΄ Zustandλ₯Ό μ¬μ©ν©λλ€.
- λ°μ΄ν° νμΉ: μλ² μν κ΄λ¦¬(μΊμ±, μ¬νμΉ λ±)λ₯Ό μν΄ Tanstack Queryλ₯Ό μ¬μ©ν©λλ€.
- PWA:
apps/webμ ν리μΌμ΄μ μnext-pwaλ‘ κ΅¬μ±λ νλ‘κ·Έλ μλΈ μΉ μ±(Progressive Web App)μ λλ€.
- λ°μ΄ν°λ² μ΄μ€ λ° μΈμ¦: λ°μ΄ν°λ² μ΄μ€ λ° μ¬μ©μ μΈμ¦μ μν΄ Supabaseλ₯Ό μ¬μ©ν©λλ€. SSR(Server-Side Rendering) νΈν ν΄λΌμ΄μΈνΈλ
apps/web/lib/supabaseμ μ€μ λμ΄ μμ΅λλ€. - API μ€κ³: API μλν¬μΈνΈλ Next.js App Routerμ
route.tsλ₯Ό μ¬μ©νμ¬ κ΅¬νλλ©°, μΌλ°μ μΌλ‘ RESTful μμΉμ λ°λ¦ λλ€. μ£Όμ API κ²½λ‘λapps/web/app/api/μλμ μ μλ©λλ€ (μ:api/auction,api/auth). - μΈμ¦ λ° μΈκ°: μ¬μ©μ μΈμ¦μ Supabase Authλ₯Ό ν΅ν΄ μ²λ¦¬λ©λλ€. API λΌμ°νΈ λ° λ°μ΄ν°λ² μ΄μ€ μ κ·Όμ λν μΈκ°λ Supabaseμ Row Level Security (RLS) λ° μλ² μΈ‘ λ‘μ§μ ν΅ν΄ ꡬνλ©λλ€. Supabase ν΄λΌμ΄μΈνΈ μ€μ μ
apps/web/lib/supabase/supabase.tsμμ κ΄λ¦¬λ©λλ€. - λ°°ν¬: νλ‘μ νΈλ Vercelμ λ°°ν¬λ©λλ€.
mainλΈλμΉμ λ³κ²½ μ¬νμ΄ νΈμλλ©΄ μλ λ°°ν¬κ° νΈλ¦¬κ±°λ©λλ€.
μ΄ νλ‘μ νΈλ Turborepo λͺ¨λ
Έλ ν¬μ
λλ€. ꡬ쑰λ appsμ packagesλ‘ λλ©λλ€.
apps/web: μ΅μ’ μ¬μ©μμκ² μλΉμ€λ₯Ό μ 곡νλ λ©μΈ Next.js μ ν리μΌμ΄μ μ λλ€. Feature-Sliced Design (FSD) μν€ν μ²λ₯Ό λ°λ¦ λλ€.apps/docs:packages/uiμ UI μ»΄ν¬λνΈλ₯Ό λ¬Έμννκ³ ν μ€νΈνκΈ° μν Storybook μΈμ€ν΄μ€λ‘λ μ¬μ©λλ Next.js μ ν리μΌμ΄μ μ λλ€.
packages/ui: μ¬μ¬μ© κ°λ₯ν UI μ»΄ν¬λνΈ(μ: Button, Card, Input)μ ν΅μ¬ λμμΈ μμ€ν (theme.css)μ ν¬ν¨νλ 곡μ ν¨ν€μ§μ λλ€.packages/eslint-config: λͺ¨λ Έλ ν¬ μ 체μμ μΌκ΄λ μ½λ μ€νμΌμ μν 곡μ ESLint μ€μ μ λλ€.packages/tailwind-config: 곡μ Tailwind CSS μ€μ μ λλ€.packages/typescript-config: 곡μ TypeScripttsconfig.jsonνμΌμ λλ€.
web μ ν리μΌμ΄μ
μ νμ₯ κ°λ₯νκ³ μ μ§λ³΄μνκΈ° μ¬μ΄ λ°©μμΌλ‘ μ½λλ₯Ό ꡬμ±νκΈ° μν΄ Feature-Sliced Design λ°©λ²λ‘ μ λ°λ¦
λλ€.
-
app/: Next.js App Router λλ ν 리μ λλ€. λ μ΄μμ, νμ΄μ§, API λΌμ°νΈλ₯Ό ν¬ν¨ν©λλ€. -
features/: μ¬μ©μ λλ©΄ κΈ°λ₯μΌλ‘, κ° κΈ°λ₯μ νΉμ κΈ°λ₯μ μΊ‘μνν©λλ€.authentication: λ‘κ·ΈμΈ, νμκ°μ , λ‘κ·Έμμ κΈ°λ₯μ λλ€.chat-list: μ¬μ©μ μ±ν λ°© λͺ©λ‘μ νμν©λλ€.chat-room: νΉμ λνλ₯Ό μν μ€μ μ±ν μΈν°νμ΄μ€μ λλ€.product-list: νν°λ§ λ° μ λ ¬μ ν¬ν¨νμ¬ μ νμ νμν©λλ€.
-
widgets/: κΈ°λ₯(features)κ³Ό μν°ν°(entities)λ₯Ό μ‘°ν©νμ¬ κ΅¬μ±λ UIμ κ΅¬μ± λΈλ‘μ λλ€.header,footer: μ¬μ΄νΈ μ 체μ ν€λ λ° νΈν°μ λλ€.auction-listings: κ²½λ§€ λͺ©λ‘μ νμνλ μμ ―μ λλ€.auction-detail-card: λ¨μΌ κ²½λ§€μ μμΈ λ³΄κΈ° μΉ΄λμ λλ€.image-banner: νλ‘λͺ¨μ μ½ν μΈ λ₯Ό μν λ°°λμ λλ€.
-
hooks/: μ¬μ¬μ© κ°λ₯ν λ‘μ§μ μν 컀μ€ν React ν μ λλ€ (μ:useLogin,useCreateAuction). -
lib/: μ νΈλ¦¬ν° ν¨μ, Supabase ν΄λΌμ΄μΈνΈ μ€μ , μ ν¨μ± κ²μ¬κΈ°(validators)λ₯Ό ν¬ν¨ν©λλ€. -
stores/: Zustand μ€ν μ΄ μ μμ λλ€ (μ:auth.ts,modal.ts).
μ΄ ν¨ν€μ§λ νλ‘μ νΈ UIμ κΈ°λ°μ λλ€.
src/theme.css: λͺ¨λ λμμΈ ν ν°(μμ, κΈκΌ΄ λ±)μ μ§μ€μ μμ²(source of truth)μ λλ€. λͺ¨λ μ€νμΌλ§μ μ΄ λ³μλ€μ μ°Έμ‘°ν΄μΌ ν©λλ€.src/styles.css: μ μ μ€νμΌ λ° κΈ°λ³Έ Tailwind CSS λ μ΄μ΄ μ μμ λλ€.src/design-system/:Button,Card,Badge,Inputλ± κ°λ³μ μ΄κ³ μ¬μ¬μ© κ°λ₯ν UI μ»΄ν¬λνΈλ₯Ό ν¬ν¨ν©λλ€.dist/: UI ν¨ν€μ§μ λΉλ μΆλ ₯λ¬Όλ‘, μ»΄νμΌλ CSS λ° JavaScriptλ₯Ό ν¬ν¨ν©λλ€.
-
μ½λ μμ±: μλ‘μ΄ μ»΄ν¬λνΈλ₯Ό μ€μΊν΄λ©(μλ μμ±)νλ €λ©΄
plopλ₯Ό μ¬μ©ν©λλ€ (pnpm plop ComponentName). -
컨벀μ : κΈ°μ‘΄ μ½λ μ€νμΌ, λͺ λͺ κ·μΉ λ° FSD μν€ν μ²λ₯Ό μ격νκ² μ€μν΄μΌ ν©λλ€.
-
μ€νμΌλ§: Tailwindμ μμ κ° κ΅¬λ¬Έμ μ¬μ©νμ¬
packages/ui/src/theme.cssμ ν λ§ λ³μλ₯Ό νμ μ¬μ©νλ κ²μ μ νΈν©λλ€. -
컀λ°:
.github/.gitmessage.txtμ μ μλ 컨벀μ λ μ»€λ° λ©μμ§ νμμ λ°λ¦ λλ€. -
ν μ€ν : νλ‘μ νΈμ μμ μ±κ³Ό νμ§μ 보μ₯νκΈ° μν΄ λ€μν μμ€μ ν μ€νΈλ₯Ό μνν©λλ€.
-
UI μ»΄ν¬λνΈ ν μ€νΈ (Storybook):
packages/uiμ UI μ»΄ν¬λνΈλapps/docsλ΄ Storybook νκ²½μμ μκ°μ μΌλ‘ ν μ€νΈλκ³ λ¬Έμνλ©λλ€.- μ΄λ μ»΄ν¬λνΈμ μΈνκ³Ό κΈ°λ³Έμ μΈ μνΈμμ©μ λ 립μ μΌλ‘ νμΈνλ λ° μ€μ μ λ‘λλ€.
-
λ¨μ/ν΅ν© ν μ€νΈ (Vitest):
- νμ¬ μν: νμ¬ νλ‘μ νΈμλ
hooks,features,lib(μ νΈλ¦¬ν° λ° μ ν¨μ± κ²μ¬κΈ°),storesλ± λ€μν μμμ λ¨μ/ν΅ν© ν μ€νΈ μ½λκ° μ‘΄μ¬ν©λλ€. - λͺ©ν:
hooks,lib,stores,featuresλ± μ ν리μΌμ΄μ μ ν΅μ¬ λΉμ¦λμ€ λ‘μ§μ λν λ¨μ λ° ν΅ν© ν μ€νΈ μμ±μ κ°λ ₯ν κΆμ₯ν©λλ€. - λꡬ:
apps/docsμμ μ¬μ©λλ Vitestλ₯Όapps/webμμλ νμ©νμ¬ ν μ€νΈλ₯Ό μμ±ν©λλ€. - ν
μ€νΈ μ λ΅ λ° μ°μ μμ (κΆμ₯ λ¨κ³):
apps/webμ Vitest μ€μΉ λ° μ€μ :apps/webλλ ν λ¦¬λ‘ μ΄λνμ¬ Vitestλ₯Ό κ°λ° μμ‘΄μ±μΌλ‘ μ€μΉν©λλ€.cd apps/web pnpm add -D vitest @vitest/coverage-v8apps/webλλ ν 리 λ΄μvitest.config.tsνμΌμ μμ±νκ³ ,apps/docsμ μ€μ μ μ°Έκ³ νμ¬apps/webμ λ§κ² ꡬμ±ν©λλ€.apps/web/package.jsonμ ν μ€νΈ μ€ν μ€ν¬λ¦½νΈλ₯Ό μΆκ°ν©λλ€ (μ:"test": "vitest").
stores(Zustand)μ λν λ¨μ ν μ€νΈ μμ±:apps/web/stores/auth.tsμ κ°μ Zustand μ€ν μ΄ νμΌμ λν΄ λ¨μ ν μ€νΈλ₯Ό μμ±ν©λλ€.- λ€νΈμν¬ μμ² λ± μΈλΆ μμ‘΄μ±μ λͺ¨μ(mock) μ²λ¦¬νμ¬ μ€ν μ΄μ λ‘μ§ μ체λ₯Ό κ²μ¦ν©λλ€.
lib(μ νΈλ¦¬ν°, μ ν¨μ± κ²μ¬κΈ°)μ λν λ¨μ ν μ€νΈ μμ±:apps/web/lib/utils/λλapps/web/lib/validators/μ κ°μ λλ ν 리μ μλ μμ ν¨μλ μ νΈλ¦¬ν° ν¨μμ λν λ¨μ ν μ€νΈλ₯Ό μμ±ν©λλ€.
hooksμ λν λ¨μ ν μ€νΈ μμ±:apps/web/hooks/λλ ν 리μ μλ 컀μ€ν ν μ λν λ¨μ ν μ€νΈλ₯Ό μμ±ν©λλ€.
featuresμ λν ν΅ν© ν μ€νΈ μμ±:apps/web/features/λλ ν 리μ μλ 볡μ‘ν κΈ°λ₯ κ°μ μνΈμμ©μ λν ν΅ν© ν μ€νΈλ₯Ό μμ±ν©λλ€.
- νμ¬ μν: νμ¬ νλ‘μ νΈμλ
-
E2E (End-to-End) ν μ€νΈ:
- λͺ©ν: μ¬μ©μκ° μ ν리μΌμ΄μ κ³Ό μνΈμμ©νλ λ°©μκ³Ό λμΌνκ², μ ν리μΌμ΄μ μ μ 체 νλ¦μ μ²μλΆν° λκΉμ§ ν μ€νΈν©λλ€. νλ‘ νΈμλ, λ°±μλ, λ°μ΄ν°λ² μ΄μ€ λ± λͺ¨λ μμ€ν κ΅¬μ± μμκ° μ€μ νκ²½μ²λΌ ν¨κ» μλνλμ§ κ²μ¦ν©λλ€.
- νμμ±: λ¨μ/ν΅ν© ν μ€νΈκ° κ°λ³ λ‘μ§μ μ νμ±μ 보μ₯νλ€λ©΄, E2E ν μ€νΈλ μ€μ μ¬μ©μ μλ리μ€μμ μμ€ν μ μ²΄κ° μμλλ‘ λμνλμ§ νμΈνμ¬ μ΅μ’ μ¬μ©μ κ²½νμ 보μ₯ν©λλ€.
- λꡬ: Playwright λλ Cypressμ κ°μ μ μ© E2E ν μ€νΈ νλ μμν¬λ₯Ό μ¬μ©νμ¬ μ¬μ©μ μλλ¦¬μ€ κΈ°λ°μ ν μ€νΈ μ½λλ₯Ό μμ±ν©λλ€.
-
μ½λ νμ§ κ²μ¦: 컀λ°νκΈ° μ μ
pnpm lintλ°pnpm check-typesλ₯Ό μ€ννμ¬ μ½λ νμ§κ³Ό νμ μμ μ±μ 보μ₯ν©λλ€.
-
- νλ‘μ νΈ μ€ν: κ°λ° λͺ¨λμμ
webλ°docsμ ν리μΌμ΄μ μ λͺ¨λ μμνλ €λ©΄pnpm devλ₯Ό μ¬μ©ν©λλ€. - UI μ»΄ν¬λνΈ: UI μ»΄ν¬λνΈ μμ
μ νλ €λ©΄
packages/uiλ‘ μ΄λνμ¬ μκ°ν λ° ν μ€νΈλ₯Ό μν΄apps/docsλ΄μ Storybookμ μ¬μ©ν©λλ€. - κΈ°λ₯: μλ‘μ΄ κΈ°λ₯μ μΆκ°ν λλ
apps/web/featuresμλμ μ λλ ν 리λ₯Ό λ§λ€κ³ FSD μμΉμ λ°λ¦ λλ€. - λ°μ΄ν°λ² μ΄μ€/μΈμ¦:
apps/web/lib/supabaseμ μ μλ ν΄λΌμ΄μΈνΈλ₯Ό ν΅ν΄ Supabaseμ μνΈμμ©ν©λλ€.