📑 이 챕터에서 다룰 내용
새 8장에서 REVIEW.md READY: YES 판정을 받았습니다. 이제 드디어 코드를 만듭니다. 이 장에서 BUILD.md를 처음 만들고, 테스트 하네스를 설치하고, 첫 기능을 TDD로 구현하고, E4 LogOnTable 실황 보존의 첫 등장을 봅니다.
| 📚 사전 지식 체크 | 🎯 이 장의 목적 | ✅ 완료 후 결과물 |
|---|---|---|
| 새 8장 REVIEW.md READY: YES + git commit | BUILD.md 생성 + 테스트 하네스 설치 + Phase 1 첫 기능 TDD 구현 + E4 LogOnTable 패턴 첫 적용 | BUILD.md 파일 + 테스트 하네스 + Phase 1 첫 기능 + 첫 LogOnTable 트레이스 |
5파일 중 BUILD.md가 처음 만들어지는 단계입니다.
| SPEC.md (새 5장) | PLAN.md (새 6장) | REVIEW.md (새 8장) | BUILD.md ◀ 지금 여기 | CLAUDE.md (새 11장) |
|---|---|---|---|---|
| 완성 | 완성 | 완성 | 생성 중 | 미완성 |
켄트 벡의 TDD 원칙: 코드보다 테스트를 먼저 작성합니다. 테스트가 통과하면 그것이 기능 완성의 증거예요.
테스트 하네스(테스트 코드를 자동 실행하고 결과를 보여주는 시스템)가 없으면 TDD를 실천할 수 없습니다. BUILD 첫날 테스트 하네스를 설치하는 이유: 나중에 설치하면 기존 코드에 테스트를 추가하는 것이 훨씬 어렵습니다.
건물을 지을 때 외관 공사보다 골조(뼈대)를 먼저 세웁니다. 골조 없이 외관을 먼저 만들면 나중에 골조를 넣을 때 외관을 전부 뜯어내야 해요.
테스트 하네스는 코드의 골조입니다. BUILD 시작 전에 설치하면 자연스럽게 TDD로 개발하게 됩니다.
테스트 하네스는 BUILD 첫날 설치합니다. 기능을 하나라도 만들기 전에.
| 도구 | 매핑 |
|---|---|
| GSD | {N}-{M}-SUMMARY.md (작업별) + atomic commits |
| Spec-Kit | implementation logs |
| OpenSpec | proposal 진행 추적 |
| BMAD | Devon(Developer) dev journal |
| GSD STATE.md | 결정·차단·세션 간 메모리 |
BUILD.md는 BUILD가 시작되는 순간 처음 만들어집니다. "지금 무엇을 만들고 있는가, 무엇이 완성됐는가, 다음에 무엇을 해야 하는가"를 항상 담고 있어야 합니다. /clear 후 새 세션에서 Claude가 이 파일을 읽으면 즉시 상황을 파악합니다.
/model claude-sonnet-4-6 # BUILD는 Sonnet으로 전환 REVIEW.md를 확인했어. READY: YES다. BUILD.md를 아래 형식으로 생성해줘: ## 현재 Phase: Phase 1.0 ## 시작일: [오늘 날짜] ## 누적 시간: 0h ## 완성된 기능 - 없음 (시작) ## 현재 작업 중 - [PLAN.md Day 1 작업] ## 다음 단계 - [PLAN.md Day 2 작업] ## 현재 오류 - 없음 ## LogOnTable 트레이스 - (E4 첫 등장 자리, Day 1부터 매일 채움)
마지막 "LogOnTable 트레이스" 섹션이 v1.0 대비 추가된 부분입니다. E4 등장 자리예요.
Expo (React Native) 프로젝트의 경우
# Jest + Testing Library 설치 npm install --save-dev jest @testing-library/react-native npm install --save-dev @types/jest jest-expo # package.json에 scripts 추가 # "test": "jest --watchAll", # "test:ci": "jest" # Claude Code에서 설정 요청 jest.config.js와 babel.config.js를 설정해줘. Expo 52 + TypeScript 환경에서 작동하도록 해줘.
Next.js 프로젝트의 경우
# Vitest + Testing Library 설치 npm install --save-dev vitest @testing-library/react @testing-library/user-event npm install --save-dev @vitejs/plugin-react jsdom # E2E 테스트 (Playwright) npm init playwright@latest # → tests/ 폴더 생성됨 # 설치 확인 npm test -- --run # 테스트 실행. 아직 테스트 없음 → 오류 없이 실행돼야 함
직접 설정하기 어려우면 Claude Code에게 맡기세요.
"이 프로젝트에 테스트 하네스를 설치해줘. Expo 52 + TypeScript 환경이야. 단위 테스트(Jest)와 E2E 테스트(Playwright) 둘 다 설치해줘. 설치 후 npm test가 오류 없이 실행되는지 확인해줘."
Claude가 설치부터 설정까지 전부 처리합니다.
테스트 하네스가 설치됐으면 이제 기능을 만듭니다. 테스트를 먼저 쓰고, 테스트를 통과하는 코드를 만듭니다. /tdd 명령을 사용하면 Claude Code가 자동으로 이 순서를 따릅니다.
/tdd # TDD 모드 활성화 로그인 기능을 TDD 방식으로 만들어줘. 테스트를 먼저 작성하고 테스트가 통과하는 구현 코드를 만들어줘. 테스트 케이스: - 유효한 이메일+비밀번호로 로그인 성공 - 잘못된 비밀번호로 로그인 실패 + 에러 메시지 - 빈 이메일로 로그인 시도 + 에러 메시지 CLAUDE.md 규칙을 준수하고 다른 파일은 건드리지 마.
기능 하나가 완성될 때마다 반드시 아래 루틴을 실행합니다.
| 순서 | 해야 할 것 |
|---|---|
| 1 | npm test 실행 → 전체 테스트 통과 확인 |
| 2 | BUILD.md 업데이트 → 완성 기능 추가, 다음 단계 수정, LogOnTable 트레이스 1~3줄 추가 |
| 3 | CLAUDE.md "현재 완성된 것" 목록 업데이트 |
| 4 | git add . && git commit -m "[기능명] 완성" |
| 5 | /clear 실행 → 새 세션 시작 |
| 6 | 새 세션 첫 메시지: "5파일을 읽고 다음 기능을 시작해줘" |
npm test # 모든 테스트 통과 확인 # Claude Code에서: BUILD.md를 업데이트해줘. 완성된 기능: [기능명] 다음 작업: [다음 기능명] LogOnTable 트레이스: [오늘 결정한 핵심 1~3줄] CLAUDE.md의 완성된 것 목록에 [기능명]을 추가해줘. git add . && git commit -m "[기능명] 완성" /clear # 새 세션 SPEC.md, PLAN.md, REVIEW.md, BUILD.md, CLAUDE.md를 읽고 다음 기능을 시작해줘.
여기가 새 1장에서 정의한 E4의 첫 등장 자리입니다.
"왜 그 결정을 내렸는가"의 사용자-AI 대화 트레이스를 보존하는 패턴입니다.
단순 결정 결과(예: "jupjups 테이블 UNIQUE 제약 추가")가 아니라, 결정에 도달하는 과정(예: "통계 조작 가능성 발견 → 옵션 A/B/C 비교 → UNIQUE 채택"의 대화) 자체를 BUILD.md에 남기는 형식입니다.
9개 표준 도구의 자리: 모두 "산출물(artifact)" 중심입니다. GSD STATE.md도 "결정의 결과"만 남기고 "결정 과정"은 세션 종료 시 사라집니다.
BUILD.md의 LogOnTable 트레이스 형식
매일 5분에 끝나는 양식이 이미 있습니다(계획·실행·이슈·게이트·회고). 거기에 LogOnTable 트레이스 1~3줄을 추가합니다.
## Day 8 (2026-MM-DD, 4h) [계획] - jupjups 테이블 + UNIQUE 제약 SQL 작성 (PLAN G2) - 집계 트리거 함수 + 트리거 작성 [실행] - 32줄 SQL 작성 + 적용 완료 - 트리거 동작 테스트 (jupjup 추가 → benefits 자동 갱신) 통과 [LogOnTable 트레이스] > 결정: UNIQUE (user_id, benefit_id) 제약 추가 vs 트리거 안 검증의 트레이드오프 비교. UNIQUE 채택 — 통계 조작 원천 차단. > 근거: 외부 검증 (트리거 안에서 COUNT) 보다 DB 제약 (UNIQUE) 이 더 견고. 사용자가 우회 시도 시 DB 레벨 차단. > 부작용: 사용자가 "줍줍 취소"를 누르려면 DELETE 후 다시 INSERT. 추후 UI에 명시. [이슈] - 없음 [회고 1줄] - UNIQUE 제약은 SPEC §5의 "통계 조작 원천 차단"이 SQL 레벨로 박혔다.
3~5줄짜리 트레이스가 매일 BUILD.md에 누적됩니다. 33일(TSV) 또는 70일(줍줍) 후 BUILD.md에 약 100~200개의 트레이스가 모입니다.
두 사례 — LogOnTable이 작동하는 모습
[LogOnTable 트레이스] > 결정: 마이페이지의 "내가 줍줍한 지원금 총액" 계산 — DB 집계 vs 서버 캐시. DB 집계 채택 (트리거가 이미 jupjup 합계를 갱신). > 근거: SPEC §4-4의 "바이럴 훅" 가치는 "실시간 정확성". 캐시는 분 단위 지연 가능 → 사용자 "방금 한 거 안 보여요" 항의 위험. > FCM 토큰 갱신 주기: 7일. 갱신 실패 시 user.fcm_token = NULL 처리.
[LogOnTable 트레이스] > 결정: lib/match_facts.ts의 MatchFacts 인터페이스 — stats 필드 optional vs required. optional 채택. > 근거: NBA·MLB 데이터 부족 시 LLM 환각 방지. SPEC §3-9의 "입력에 없는 사실은 만들지 않는다". > cache_control 위치: 페르소나 system prompt 끝에 추가. ANTHROPIC_API_BETA="prompt-caching-2024-07-31" 헤더 필수. > 자동 일관성 테스트: tests/persona_consistency.test.ts 5개 케이스. 실패 시 cron/publish.ts 정지.
왜 LogOnTable이 운영 매뉴얼의 본질인가
6개월 후 비개발자 동업자가 줍줍 폴더를 받았다고 가정합니다. "jupjups 테이블 UNIQUE 제약은 왜 있는 거지?"라고 질문이 생겼습니다.
결과만 있는 경우 (표준 도구 패턴):
GSD STATE.md: "jupjups 테이블 + UNIQUE 제약 작성 완료"
동업자: "왜 UNIQUE을 박았는지 모르겠다. 트리거로도 가능했을 텐데..."
→ 결정의 근거가 없으니 동업자는 "이걸 빼도 되나" 같은 위험한 질문을 하게 됩니다.
LogOnTable이 있는 경우 (5파일+ 패턴):
BUILD.md Day 8 트레이스: "UNIQUE 제약 vs 트리거 안 검증 비교. UNIQUE 채택 — DB 제약이 외부 검증보다 견고. 사용자 우회 시도 시 DB 레벨 차단."
동업자: "아, 이래서 UNIQUE이구나. 트리거로도 가능했지만 DB 제약이 더 견고하다고 결정한 거네. 이걸 빼면 우회 가능."
→ 결정의 근거 + 대안 비교 + 부작용까지 모두 본문에 있습니다. 동업자가 즉시 작업 재개 가능해요.
이게 운영 매뉴얼의 본질입니다. "결정 결과"만 있는 건 "운영용"이고, "결정 과정"까지 있는 건 "운영용 + 학습용 + 인수인계용"입니다. 5파일+의 BUILD.md는 후자입니다.
책 본문 자체가 큰 LogOnTable
BUILD.md만이 아니라, 1탄·2탄·3탄 책 본문 자체가 큰 LogOnTable입니다. 이 책의 LogOnTable 사례 절들이 그 자리예요.
표준 도구의 매뉴얼이 "이 명령을 입력하세요"를 가르친다면, 5파일+의 본문은 "이런 대화로 이런 결정에 도달하세요"를 가르칩니다. 동업자가 책을 정독하면 "내가 따라할 수 있는 대화 패턴"이 손에 들립니다.
- 1️⃣ 핵심 한 줄: BUILD.md = 일자별 5분 양식 + LogOnTable 트레이스 1~3줄. 33~70일 누적됩니다.
- 2️⃣ BUILD 시작 4단계:
- BUILD.md 생성 (Phase·시작일·누적 시간·LogOnTable 섹션)
- 테스트 하네스 설치 (Expo: Jest / Next.js: Vitest + Playwright)
- /tdd 모드 + 첫 기능 구현
- 기능 완성 루틴 (npm test → BUILD.md → CLAUDE.md → git → /clear)
- 3️⃣ E4 LogOnTable 등장: BUILD.md 일자별 양식에 "LogOnTable 트레이스 1~3줄" 섹션 추가
- 4️⃣ 트레이스 3요소: "왜 그 결정인가" + "대안 비교" + "부작용" 보존
- 5️⃣ 두 사례: 줍줍 Day 17 (마이페이지 총액 — DB 집계 vs 캐시, DB 채택) / TSV Day 8 (SSOT stats 필드 — optional vs required, optional 채택)
- 6️⃣ 운영 매뉴얼 가치: "결정 결과"만이 아니라 "결정 과정"까지. 6개월 후 동업자가 즉시 작업 재개 가능합니다.
- 7️⃣ 표준 흡수 매핑: GSD SUMMARY.md + STATE.md / Spec-Kit implementation logs / BMAD Devon dev journal
테스트가 통과했고, BUILD.md에 기록됐으며, LogOnTable 트레이스가 첫 줄을 받았고, git에 저장됐습니다.
6개월 후 누군가 이 폴더를 펼쳐도 "왜 이 결정이 내려졌는지"의 답이 본문에 있습니다.
다음 장에서 5파일+ 슬래시 명령 + 표준 도구 슬래시 명령 비교를 다룹니다.