외주 납품용 Next.js 풀스택 보일러플레이트
| 영역 | 기술 | 이유 |
|---|---|---|
| 프레임워크 | Next.js 15 (App Router) | SSR/SSG + API Routes 통합 |
| ORM | Drizzle ORM 0.x | 타입 안전, 경량, SQL에 가까움 |
| DB | Supabase PostgreSQL | 무료 티어, 관리형, Auth 연동 가능 |
| 인증 | Better Auth | 프레임워크 독립적, Drizzle 어댑터 |
| UI | shadcn/ui + Tailwind CSS | 커스터마이징 자유도, 복붙 컴포넌트 |
| 검증 | Zod | 타입 추론, 런타임 검증 |
# 1. 클론
git clone https://github.com/codemon-ai/nextjs-fullstack-template.git
cd nextjs-fullstack-template
# 2. 환경변수 설정
cp .env.example .env
# .env 파일에 DATABASE_URL, BETTER_AUTH_SECRET 등 입력
# 3. 의존성 설치
pnpm install
# 4. DB 스키마 푸시 (Supabase 연결 후)
pnpm db:push
# 5. 개발 서버 실행
pnpm devsrc/
├── app/
│ ├── (web)/ # 고객용 페이지
│ │ ├── page.tsx # 랜딩 페이지
│ │ └── layout.tsx
│ ├── (admin)/ # 어드민 영역
│ │ ├── admin/
│ │ │ ├── page.tsx # 대시보드
│ │ │ └── layout.tsx # 사이드바 레이아웃
│ │ └── layout.tsx
│ ├── api/
│ │ ├── auth/[...all]/ # Better Auth
│ │ └── health/ # 헬스체크
│ ├── layout.tsx # 루트 레이아웃
│ └── globals.css
├── auth/
│ ├── server.ts # Better Auth 서버 설정
│ └── client.ts # 클라이언트 훅
├── db/
│ ├── schema/ # Drizzle 스키마
│ ├── client.ts # DB 싱글톤 클라이언트
│ └── migrate.ts # 마이그레이션 실행기
├── components/ui/ # shadcn/ui 컴포넌트
├── lib/
│ ├── utils.ts # cn() 유틸
│ └── validators/ # Zod 스키마
└── middleware.ts # /admin 경로 보호
pnpm dev # 개발 서버 (Turbopack)
pnpm build # 프로덕션 빌드
pnpm start # 프로덕션 서버
pnpm lint # ESLint
pnpm db:push # 스키마를 DB에 직접 푸시 (개발용)
pnpm db:generate # 마이그레이션 파일 생성
pnpm db:migrate # 마이그레이션 실행
pnpm db:studio # Drizzle Studio (DB GUI)# src/app/(web)/about/page.tsx# src/app/(admin)/admin/users/page.tsx# src/app/api/users/route.ts- 스키마 파일 생성:
// src/db/schema/posts.ts
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { user } from "./users";
export const post = pgTable("post", {
id: text("id").primaryKey(),
title: text("title").notNull(),
content: text("content"),
authorId: text("author_id").notNull().references(() => user.id),
createdAt: timestamp("created_at").notNull().defaultNow(),
});src/db/schema/index.ts에 export 추가:
export * from "./users";
export * from "./posts";- DB에 반영:
pnpm db:push"use client";
import { signIn, signOut, useSession } from "@/auth/client";
// 이메일 로그인
await signIn.email({ email, password });
// 카카오 로그인
await signIn.social({ provider: "kakao" });
// 로그아웃
await signOut();
// 세션 확인
const { data: session } = useSession();- 카카오 개발자 앱 생성
- 카카오 로그인 활성화
- Redirect URI:
{BETTER_AUTH_URL}/api/auth/callback/kakao .env에KAKAO_CLIENT_ID,KAKAO_CLIENT_SECRET설정
- GitHub 연결 후 Import
- 환경변수 설정 (
.env.example참고) - Build Command:
pnpm build - Output Directory:
.next
DATABASE_URL— Supabase 풀러 연결 문자열 (aws-N 클러스터 주의)BETTER_AUTH_SECRET— hex 랜덤 시크릿 (node -e "..."로 생성)BETTER_AUTH_URL— 배포 URL (예:https://your-app.vercel.app)NEXT_PUBLIC_APP_URL— 배포 URL
Supabase + Vercel 연결에서 흔히 겪는 문제는 docs/supabase-vercel-guide.md 참고.
pnpm dlx shadcn@latest add [컴포넌트명]설치된 컴포넌트: button, card, input, label, form, table, dialog, sheet, dropdown-menu, avatar, badge, separator
프로젝트별 필요에 따라 추가:
- 결제 연동 — 토스페이먼츠 v2 (결제창 + 웹훅 + 환불)
- 파일 업로드 — Supabase Storage 연동 (이미지/문서)
- 이메일 발송 — Resend + React Email (가입 환영, 비밀번호 리셋)
- 권한 관리 (RBAC) — role별 페이지/API 접근 제어 미들웨어 고도화
- 다크모드 — next-themes + shadcn 테마 전환
- 국제화 (i18n) — next-intl (다국어 필요 시)
- E2E 테스트 — Playwright 기본 셋업 (핵심 플로우만)
- 에러 추적 — Sentry 연동
- SEO — generateMetadata 유틸, sitemap.xml, robots.txt
- PWA — next-pwa (모바일 앱 느낌 필요 시)
- Rate Limiting — API 요청 제한 (upstash/ratelimit)
- 검색 — 상품/게시물 전문 검색 (Supabase Full Text Search)
팀 커뮤니케이션 + 알림. Vercel/Supabase 연동으로 배포/에러 알림 자동화.
- Slack API
- Vercel Integration: 프로젝트 설정 → Integrations → Slack
이슈 트래킹. GitHub PR과 자동 연동, 칸반 기본.
- Linear
- GitHub 연동: Settings → Integrations → GitHub
- 이슈 키(예:
BM-123)를 커밋/PR에 포함하면 자동 링크
기획 문서, 회의록, 클라이언트 공유용.
- Notion API
- 릴리즈 노트, 기능 명세 등 클라이언트 공유 문서에 적합
- 개발 문서는 레포 안
docs/(CODA)에, 기획/공유 문서는 Notion에
AI 코딩 에이전트(Claude Code, Cursor 등)와 협업할 때 권장하는 문서 구조.
프로젝트가 커지면 docs/ 폴더에 CODA 구조를 적용:
docs/
├── INDEX.md ← 라우팅 테이블 (진입점, 에이전트가 이것만 읽으면 전체 파악)
├── prd/ ← WHY: 왜 만드나 (기획서, 요구사항)
├── spec/ ← HOW: 어떻게 만드나 (API 명세, DB 스키마, 설계)
├── wiki/ ← NOW: 현재 실제 상태 (아키텍처, ADR, 제한사항)
├── changelog/ ← DELTA: 뭘 왜 바꿨나 (일별 변경 기록)
└── _templates/ ← 문서 템플릿
핵심 원칙:
- INDEX.md가 라우팅 테이블 — 작업 유형 → 읽어야 할 문서 매핑
- CLAUDE.md는 30줄 이내 — 행동 규칙만, 지식은 docs/에
- spec(원래 계획) ≠ wiki(실제 상태) — 둘이 다르면 wiki가 맞다
- ADR(Architecture Decision Record) — "왜 이렇게 짰는지" 기록
- 에이전트 드래프트 → 인간 리뷰 — 문서 자동 업데이트를 믿지 않는다
소규모 프로젝트에선 CLAUDE.md + README만으로 충분. 테이블 10개+, 도메인 3개+ 넘어가면 CODA 도입 권장.
참고: CODA 상세 가이드 (발행 예정)
MIT