Skip to content

Bananamilk452/belchic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

233 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

belchic.shop

고딕 로리타 패션 커머스 belchic.shop의 클론 프로젝트입니다.
실제 서비스가 아닌 프론트엔드 아키텍처 역량을 보여주기 위한 포트폴리오 데모입니다.

Tech Stack

Category Tech
Framework Next.js 16 (App Router), React 19, TypeScript
Database PostgreSQL, Prisma (@prisma/adapter-pg custom adapter)
Auth better-auth (email/password)
Data Fetching TanStack Query, @suspensive/react-query, Streaming SSR
Styling Tailwind CSS v4, shadcn/ui (radix-luma), OKLCH color system
Payment Stripe (test mode, webhook)
Forms react-hook-form, Zod (Korean locale)
URL State nuqs
Testing Vitest, @testing-library/react, jsdom
Lint/Format oxlint, oxfmt
Package Mgr pnpm
CI/CD GitHub Actions (format + lint + test parallel)

Architecture Highlights

계층형 아키텍처 (Layered Architecture)

Schema → Model → Service → Action → Query → Component

6단계로 관심사를 완전히 분리했습니다. 각 레이어는 명확한 책임을 가지며 의존 방향이 단방향으로 흐릅니다.

Layer 역할 예시
Schema Zod 런타임 검증 lib/schemas/product.schema.ts
Model TypeScript 타입 정의 lib/models/product.model.ts
Service 비즈니스 로직 + Prisma 쿼리 lib/services/product.service.ts
Action "use server" 래퍼, withAction 적용 lib/actions/product.action.ts
Query TanStack Query options lib/queries/product.query.ts
Component UI 렌더링 (Server / SuspenseQuery) components/product/ProductCard.tsx

Server Action 패턴

모든 서버 액션은 withAction() 유틸리티로 래핑되어 ActionResult<T> 타입을 반환합니다.
타입 세이프한 에러 핸들링이 가능하며, wrapQueryFn()을 통해 TanStack Query와 매끄럽게 연결됩니다.

export const getProductsAction = withAction(GetProductsParamsSchema, async (params) =>
  getProducts(params),
);

Optimistic Updates + Debounced Mutation

장바구니 수량 변경과 아이템 삭제는 TanStack Query의 onMutate로 캐시를 즉시 반영하고,
실패 시 onError에서 롤백 + toast 에러를 표시합니다.
수량 입력은 es-toolkitdebounce(500ms)로 지연 저장하여 불필요한 요청을 최소화했습니다.

Guest Cart Merge

미들웨어가 cart_session_id 쿠키를 발급하여 비회원도 장바구니를 사용할 수 있습니다.
로그인 시 mergeGuestCart 서버 액션이 세션 장바구니를 사용자 장바구니에 자동 병합합니다.

Streaming SSR

홈페이지의 4개 CollectionSection<Suspense>로 감싸져 각각 독립적으로 스트리밍됩니다.
초기 HTML에 HeroBanner가 먼저 도착하고, 컬렉션 데이터는 준비되는 순서대로 점진적으로 렌더링되어 TTFB를 최소화했습니다.

SEO

모든 페이지에 JSON-LD 구조화 데이터(schema-dts)를 삽입했습니다:

  • 메인 페이지: Organization + WebSite
  • 상품 상세: Product (가격, 재고, 이미지, 상품명)
  • lib/seo.ts에 빌더 함수로 분리하여 재사용

Design System

전체 UI는 DESIGN.md에 문서화된 시스템을 따릅니다:

  • Minimalist Monochrome: OKLCH 흑백 스케일만 사용, 별도의 accent color 없음
  • High-Contrast Interaction: 모든 인터랙션 요소는 테두리, hover, active/selected 상태가 명확
  • Korean First: 모든 UI 텍스트, 에러 메시지, 포맷팅이 한국어 (ko-KR 로케일)
  • Restrained Motion: slide-in-bottom / pulse / spinner 세 가지 애니메이션만 사용
  • Server/Client 분리 원칙: UI Primitive는 기본 Server Component, 상태가 필요한 경우만 Client Component

Testing

36개 테스트 파일, 3개의 헬퍼 파일로 전 영역을 커버합니다:

  • Schemas: Zod 검증 로직 단위 테스트
  • Services: Prisma mock으로 비즈니스 로직 검증
  • Actions: withAction 래핑 + 권한 검증 통합 테스트
  • Components: 사용자 상호작용 시나리오 (@testing-library/user-event)
  • API Routes: Stripe webhook 처리 테스트
  • Middleware: 쿠키 기반 guest 세션 플로우 검증

CI/CD

GitHub Actions 3병렬 파이프라인:

  • format: oxfmt 실행, 변경사항 자동 커밋
  • lint: oxlint --max-warnings 0
  • test: vitest run

주요 페이지

Route Description
/ 홈 (Hero + 4 streaming sections)
/products/[handle] 상품 상세
/collections/[collection] 컬렉션별 상품 목록
/search 검색
/cart 장바구니
/favorite 관심 상품
/orders/[id] 주문 상세
/mypage 마이페이지
/sign-in 로그인
/sign-up 회원가입

Project Structure

├── app/                    # Next.js App Router pages
├── components/
│   ├── ui/                 # shadcn/ui primitives
│   ├── auth/               # SignInForm, SignUpForm
│   ├── product/            # ProductCard, ProductDetail, ProductContext
│   ├── cart/               # Cart, CartItem
│   ├── collection/         # CollectionProductList
│   ├── search/             # SearchProductList
│   ├── favorite/           # FavoriteGrid
│   ├── order/              # OrderHistory, OrderDetail
│   └── shared/             # ProductListPagination
├── lib/
│   ├── schemas/            # Zod schemas (Korean locale)
│   ├── models/             # TypeScript types
│   ├── services/           # Business logic + Prisma queries
│   ├── actions/            # Server actions (withAction wrapper)
│   ├── queries/            # TanStack Query options
│   └── generated/prisma/   # Generated Prisma client
├── hooks/                  # Custom React hooks
├── prisma/
│   ├── schema.prisma       # Database schema
│   └── migrations/         # Migration history
├── resources/icons/        # Custom SVG icon components
├── tests/                  # Vitest test suites
├── DESIGN.md               # UI design system documentation
└── middleware.ts           # Next.js middleware (guest session)

About

Next.js 연습을 위한 https://belchic.shop 클론 코딩

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors