LLM은 컨텍스트가 좋을수록 좋은 코드를 냅니다. 반대로 컨텍스트가 비어 있으면 그럴듯하지만 일관성 없는 결과를 만듭니다. 그래서 "어떤 시스템인지"를 먼저 문서로 고정해 두고, 코드를 생성할 때마다 그 문서를 근거로 삼게 하는 것이 핵심입니다.
docs/에 두고, 각 단계 산출물을 다음 단계의 입력으로 넘긴다.
가장 먼저 무엇을 만들 것인가를 정리합니다. 기능 목록과 핵심 엔터티(데이터)를 뽑고, 엔터티 간 관계를 ER 다이어그램으로 그립니다. Mermaid로 그리면 마크다운에 그대로 박혀 깃에서 렌더링되고, 나중에 Prisma 스키마의 근거가 됩니다.
블로그 시스템을 만들 거야. 다음을 docs/requirements.md 에 작성해줘.
1. 기능 요구사항 — 사용자/관리자 시나리오 단위로 목록화
2. 핵심 엔터티와 속성 정의
3. 엔터티 관계를 Mermaid erDiagram 으로 작성
지금은 문서만 만들고 코드는 작성하지 마.
```mermaid
erDiagram
USER ||--o{ POST : writes
USER ||--o{ COMMENT : writes
POST ||--o{ COMMENT : has
POST }o--o{ TAG : tagged
USER {
string id PK
string email
string name
datetime createdAt
}
POST {
string id PK
string title
string body
string authorId FK
datetime publishedAt
}
```
코드는 작성하지 마를 붙여 산출물을 한정하세요.
각 화면이 어떤 데이터를 보여주고, 어떤 동작을 하며, 어떤 API를 호출하는지를 마크다운으로 정의합니다. 화면 정의서는 프론트엔드 컴포넌트와 API 명세를 잇는 다리 역할을 합니다.
# 화면: 글 목록 (PostList)
## 경로 `/posts`
## 구성 요소
| 영역 | 내용 | 데이터 출처 |
|------|------|------------|
| 헤더 | 검색 입력, 태그 필터 | - |
| 목록 | 카드(제목·요약·작성자·날짜) | `GET /api/posts` |
| 페이지네이션 | 이전/다음 | `?page`, `?size` |
## 동작
- 카드 클릭 → `/posts/:id` 이동
- 태그 클릭 → `?tag=` 필터 적용
## 상태
- 로딩 / 빈 목록 / 에러 각각의 UI 정의
화면 정의서에서 끌어낸 엔드포인트를 OpenAPI(Swagger) 스펙으로 정리합니다. OpenAPI는 사람이 읽기도 좋지만, 타입/클라이언트/목 서버를 자동 생성할 수 있어 표준으로 두기 좋습니다.
paths:
/api/posts:
get:
summary: 글 목록 조회
parameters:
- name: page
in: query
schema: { type: integer, default: 1 }
responses:
'200':
description: 목록
content:
application/json:
schema:
$ref: '#/components/schemas/PostList'
openapi-typescript 같은 도구로 프론트 타입을 자동 생성할 수 있습니다.
명세와 코드가 어긋날 일이 줄어듭니다.
마지막 문서는 테스트 명세서입니다. "이 기능이 끝났다"의 정의를 케이스 단위로 적어두면, 클로드 코드가 이 명세를 보고 실제 테스트 코드(Vitest 등)를 작성하고, 통과를 완료 기준으로 삼습니다.
## API: GET /api/posts
| ID | 케이스 | 입력 | 기대 결과 |
|----|--------|------|-----------|
| TC-01 | 기본 목록 | page 없음 | 200, 최신순 10건 |
| TC-02 | 페이지네이션 | `?page=2` | 200, 11~20번째 |
| TC-03 | 태그 필터 | `?tag=js` | 200, 해당 태그만 |
| TC-04 | 잘못된 page | `?page=-1` | 400 검증 에러 |
## 인증: POST /api/login
| ID | 케이스 | 입력 | 기대 결과 |
|----|--------|------|-----------|
| TC-10 | 성공 | 올바른 자격 | 200 + 토큰 |
| TC-11 | 비번 오류 | 틀린 비번 | 401 |
CLAUDE.md는 클로드 코드가 작업할 때 자동으로 읽는 프로젝트 지침서입니다.
여기에 위에서 만든 문서들의 위치를 알려주면, 매번 같은 컨텍스트로 작업합니다.
그런데 모든 규칙을 루트 한 파일에 몰아넣으면 점점 비대해지고, 프론트 작업 중에
백엔드 규칙까지 통째로 읽히는 비효율이 생깁니다.
소스 코드가 위치한 디렉토리마다 그 영역에 맞는 CLAUDE.md를 두면, 클로드 코드는
해당 폴더에서 작업할 때 그 파일을 함께 참고합니다. 프론트 작업엔 프론트 규칙만,
백엔드 작업엔 백엔드 규칙만 — 컨텍스트가 가벼워지고 관리가 쉬워집니다.
# 프로젝트 지침
설계 문서는 docs/ 에 있다. 코드 작성 전 반드시 참고할 것.
- 요구사항·ER: `docs/requirements.md`
- 화면 정의서: `docs/screens/`
- API 명세: `docs/openapi.yaml`
- 테스트 명세: `docs/test-spec.md`
세부 규칙은 각 디렉토리의 CLAUDE.md 를 따른다.
# 백엔드 규칙
- DB 접근은 Prisma Client 로만. raw SQL 금지.
- 모든 입력은 zod 로 검증 후 처리.
- 응답 스키마는 `docs/openapi.yaml` 과 일치시킬 것.
- 새 엔드포인트는 `docs/test-spec.md` 케이스를 먼저 통과시킬 것.
LLM이 생성한 코드는 자동 검증 장치(가드레일)로 한 번 걸러야 합니다. 가장 기본은 린터입니다. ESLint 설정을 추가하고, 작업이 끝날 때마다 lint 체크를 돌리게 하면 스타일 붕괴와 흔한 실수를 코드가 쌓이기 전에 잡습니다.
import js from '@eslint/js';
import ts from 'typescript-eslint';
export default [
js.configs.recommended,
...ts.configs.recommended,
{
rules: {
'no-unused-vars': 'error',
'no-console': 'warn',
'@typescript-eslint/no-explicit-any': 'error',
},
},
];
$ npm install -D eslint @eslint/js typescript-eslint
$ npx eslint . # 작업 후 매번 실행 → 0 errors 가 완료 조건
작업을 마치면 npx eslint . 를 실행하고 에러가 0이어야 한다고 적어두세요.
그러면 클로드 코드가 스스로 돌려보고, 걸린 부분을 고친 뒤에야 작업을 끝냅니다.
린트 + 타입체크 + 테스트, 이 셋이 LLM 코드의 기본 가드레일입니다.
2단계에서 만든 ER 다이어그램을 근거로 Prisma 스키마를 생성합니다. ER이 이미 엔터티·관계를 정의해 두었으므로, 스키마 작성은 거의 번역에 가깝습니다.
라이브러리는 빠르게 바뀝니다. LLM의 학습 시점 지식은 종종 낡아 있어서, 옛 문법으로 스키마를
짜기도 합니다. Context7은 라이브러리의 최신 공식 문서를 그 자리에서
가져다주는 MCP 서버입니다. 프롬프트 끝에 use context7을 붙이면, 클로드 코드가
현재 버전의 Prisma 문법을 참고해 스키마를 만듭니다.
docs/requirements.md 의 ER 다이어그램을 참고해서
prisma/schema.prisma 를 작성해줘.
- 관계(1:N, N:M)를 정확히 반영
- id 는 cuid, 타임스탬프 필드 포함
- 최신 Prisma 문법으로. use context7
model Post {
id String @id @default(cuid())
title String
body String
author User @relation(fields: [authorId], references: [id])
authorId String
comments Comment[]
tags Tag[]
publishedAt DateTime?
createdAt DateTime @default(now())
}
use context7 한 줄이면 "지금 버전" 기준으로 코드를 짜게 됩니다.
마지막으로, 프로젝트가 쓰는 기술을 한 곳에 명시합니다. 이걸 CLAUDE.md(또는
docs/tech-stack.md)에 적어두면, 클로드 코드가 임의의 다른 라이브러리를 끌어오지 않고
정해진 스택 안에서 일합니다.
| 영역 | 선택 | 비고 |
|---|---|---|
| 언어 | TypeScript | 프론트·백엔드 공통 |
| 프레임워크 | Next.js / Express | 웹 / API |
| UI 컴포넌트 | Tailwind CSS | 유틸리티 우선 스타일 |
| API 스키마 | OpenAPI | 스펙 우선, 타입 자동생성 |
| DB 스키마 | Prisma | ER → schema.prisma |
| 테스트 | Vitest | 테스트 명세서 기반 |
| 가드레일 | ESLint | 완료 조건에 lint 포함 |
| 배포 | Vercel 등 | 프로젝트 상황에 맞게 |
클로드 코드로 시스템을 만드는 절차의 핵심은 "문서로 컨텍스트를 고정하고, 가드레일로 검증한다"입니다.
use context7로 최신 라이브러리 문법을 따른다