Next.js 16 App Routerμ MDX κΈ°λ°μΌλ‘ ꡬμΆλ κ°μΈ κ°λ° λΈλ‘κ·Έμ
λλ€.
Git μλΈλͺ¨λλ‘ μ»¨ν
μΈ λ₯Ό κ΄λ¦¬νλ©° SSG(Static Site Generation) λ°©μμΌλ‘ μ΅μ νλ μ±λ₯μ μ 곡ν©λλ€.
- Framework: Next.js 16 App Router (Turbopack λΉλ, React Compiler νμ±)
- UI Runtime: React 19
- Language: TypeScript 6 (strict mode)
- Styling: Tailwind CSS 4 Β· shadcn/ui Β· next-themes
- Icons: lucide-react
- Content: MDX (Git Submodule
contents/) Β· Shiki μ½λ νμ΄λΌμ΄ν - Type Safety: Zod (frontmatterΒ·API runtime validation)
- Testing: Vitest Β· React Testing Library Β· MSW Β· Playwright
- Runtime: Vercel KV (
/api/viewsμ‘°νμ, fail-soft fallback) - Quality: ESLint 9 Β· Prettier 3 Β· Lefthook 2
3-Layer (app β features β shared λ¨λ°©ν₯):
src/
βββ app/ β λΌμ°ν
, metadata, providers
βββ features/ β 9κ° λλ©μΈ (posts, tags, series, search, views, comments, theme, lightbox, about)
βββ shared/ β components, ui(shadcn), styles, seo, config, utils, hooks, types, modules
contents/ β MDX μ½ν
μΈ (Git Submodule)
docs/ β PRD, ROADMAP, TASKS, AI_WORKFLOW_GUIDE
.claude/ β AI μμ΄μ νΈ νλ€μ€ (agents, skills, rules, commands, hooks)
3 Laws (.claude/rules/project-structure.md):
app β features β sharedλ¨λ°©ν₯ μμ‘΄ (μλ°©ν₯ κΈμ§)sharedλfeaturesλ₯Ό λͺ¨λ¦- feature κ° μ§μ import κΈμ§ β
app/μμ 쑰립 λλshared/λ‘ μΉκ²©
pnpm dev # κ°λ° μλ² (port 3100)
pnpm build # νλ‘λμ
λΉλ (Turbopack)
pnpm lint # ESLint
pnpm format # Prettier ν¬λ§€ν
pnpm test # Vitest (Unit + Integration)
pnpm test:e2e # Playwright E2E (5 spec)ν¬νΈ: κ°λ° μλ²λ 3100 (Next.js κΈ°λ³Έ 3000μ΄ μλ).
- SSG-first β λ°νμ CMSΒ·μλ² κ²μΒ·ν΄λΌμ΄μΈνΈ μΊμ(TanStack Query) λμ
νμ§ μμ. μ μΌν λ°νμ APIλ
/api/views(Vercel KV). - TDD (RedβGreenβRefactor) + Testing Trophy (Integration ~60%)
- Page-First Skeleton β M1μμ λλ―Έ λ°μ΄ν°λ‘ μ νμ΄μ§ UI μμ± ν λ¨κ³μ μ€λ°μ΄ν° κ΅μ²΄
- μ½ν
μΈ λ Git Submodule β
contents/μ μ₯μ λΆλ¦¬λ‘ μμ€μ κΈμ μ»€λ° μ΄λ ₯ λ 립 - νκΈ slug μμλ³ λΆλ¦¬ β ν¬μ€νΈλ μλ¬Έ κ°μ (λꡬ·CDN νΈν), νκ·ΈΒ·μ리μ¦λ νκΈ νμ© + 곡백βhyphen μ κ·ν
- Fail-soft μ‘°νμ β KV λ―Έμ€μ /μ₯μ μ GET=0, POST=silent skip (νμ΄μ§ 500 μ°¨λ¨)
| λ¬Έμ | μ©λ |
|---|---|
docs/TASKS.md |
M0~M7 νμ€ν¬ 체ν¬λ¦¬μ€νΈ (199/199 μλ£) |
docs/ROADMAP.md |
λ§μΌμ€ν€λ³ μμΈ β κ²μ¦ κΈ°μ€, Entry/Exit |
docs/PRD_PRODUCT.md |
μ ν μ€ν β FEAT, US, μ±κ³΅ μ§ν |
docs/PRD_TECHNICAL.md |
κΈ°μ κ³μ½ β MOD, RT, ADR, λ°μ΄ν° λͺ¨λΈ |
docs/AI_WORKFLOW_GUIDE.md |
Claude Code λ©ν° μμ΄μ νΈ νλ€μ€ λμ μ리 |
CLAUDE.md |
Claude Code μ¨λ³΄λ© Β· Progressive Disclosure |
μ΄ νλ‘μ νΈλ Claude Code κΈ°λ° μ»΄νμ΄λ μμ§λμ΄λ§ νλ€μ€λ₯Ό κ°μΆκ³ μλ€.
μ¬μ©μκ° μμ°μ΄λ‘ μμ²νλ©΄ λ΄λΆμμ μ λ¬Έ μμ΄μ νΈ νμ΄ μλ ꡬμ±λμ΄ 6λ¨κ³ νμ§ μ¬μ΄ν΄μ λλ€.
"M0-01 μ§νν΄μ€"
β blog-dev μ€ν¬ νΈλ¦¬κ±°
β TeamCreate (Feature νΈλ ν ꡬμ±)
β PLAN β EXECUTE β REVIEW(νν 3ν) β VALIDATE β DOCUMENT β SYNTHESIZE
β μ¬μ©μ λ³΄κ³ (λ³κ²½ νμΌΒ·μ¬μ΄ν΄ ν΅κ³Β·λΉλ κ²°κ³Ό)
| νΈλ | νΈλ¦¬κ±° μμ |
|---|---|
| Feature | M0-06 μ§ν, κ²μ κΈ°λ₯ λ§λ€μ΄μ€ |
| Content | React 19 use ν
ν¬μ€νΈ μ΄μ |
| GC | Week 0 GC, μ²μν΄μ€, νλ€μ€ νκ° |
| Docs | TASKS μ²΄ν¬ λ§μΆ°μ€, ROADMAP μ§νλ₯ |
- 15κ° μμ΄μ νΈ (
orchestrationΒ·developerΒ·planningΒ·qualityΒ·contentΒ·documentation) - 15κ° μ€ν¬ (μ€μΌμ€νΈλ μ΄μ
3 Β· λλ©μΈ μμ
4 Β· μ°Έμ‘° μ§μ 8 β
ai-seoΒ·programmatic-seoΒ·seo-auditμΆκ°) - 17κ° κ·μΉ (μν€ν μ²Β·μ€νμΌΒ·νμ§Β·νλ€μ€Β·μμ΄μ½Β·REVIEW κ°μ Β·No-FallbackΒ·Comments)
- 9κ° μ¬λμ 컀맨λ (μλ λ¨μΌ μμ μ©)
μμΈ λμμ docs/AI_WORKFLOW_GUIDE.md μ°Έμ‘°.
- μλ:
src/μ½λ, ν μ€νΈ,docs/TASKS.md체ν¬λ°μ€,CHANGELOG.md - μ¬μ©μ μΉμΈ νμ: μμ‘΄μ± μΆκ°(
package.json)Β·μν€ν μ² λ³κ²½Β·PRD μμ Β·Git μ°κΈ° μμ (commitΒ·pushΒ·PRΒ·λ¨Έμ§Β·tag λͺ¨λ λͺ μ μμ² νμ,.claude/rules/workflow.md"Git μ°κΈ° μ λ κΈμ§ κ·μΉ" μ°Έμ‘°)
main β νλ‘λμ
λ¦΄λ¦¬μ€ (보νΈ)
develop β κΈ°λ³Έ ν΅ν© λΈλμΉ (λͺ¨λ feature PRμ base)
feature/M{n}-{μ¬λ¬κ·Έ} β λ§μΌμ€ν€ λ¨μ κ°λ°
1 λ§μΌμ€ν€ = 1 feature λΈλμΉ.
μ λ§μΌμ€ν€ 첫 νμ€ν¬ μ§μ
μ orchestratorκ° λ¦¬λͺ¨νΈ μ΅μ developμΌλ‘λΆν° feature/M{n}-* λΈλμΉ μμ±μ μ μνλ€ (μ¬μ©μ μΉμΈ ν μ€ν).
λ§μΌμ€ν€ μλ£ μ developμΌλ‘ PR, merge commit λλ rebase merge (squash merge κΈμ§ β atomic commits 보쑴).
PR μμ± μ λ°λμ origin/main (λλ base λΈλμΉ)μ developμ mergeν΄μ conflict μ¬μ ν΄μ.
# μμ‘΄μ± μ€μΉ + μλΈλͺ¨λ (contents) μ΄κΈ°ν
git clone --recurse-submodules https://github.com/chan9yu/dev-blog.git
cd dev-blog
pnpm install
# κ°λ° μλ²
pnpm dev
# β http://localhost:3100
# νλ‘λμ
λΉλ ν
μ€νΈ
pnpm buildchan9yu.dev β Vercel μλ λ°°ν¬ (main λ¨Έμ§ β νλ‘λμ
, develop PR β Preview).
- Framework Preset: Next.js
- Build Command:
pnpm build(Turbopack) - Output:
.next/ - Environment Variables (μ ν, μ‘°νμ νμ±ν μ):
KV_REST_API_URL,KV_REST_API_TOKENβ@vercel/kvμλ μΈμ- λ―Έμ€μ μ λΉλΒ·λ λ μ μ λμ, μ‘°νμλ§
0μΌλ‘ νμ
- νμ§ κ²μ΄νΈ: λ‘컬
lefthookpre-commit (Prettier Β· ESLint Β· tsc) + Vercel λΉλ μ typecheck
MIT License - μμΈν λ΄μ©μ LICENSE νμΌμ μ°Έμ‘°νμΈμ.