# CLAUDE.md

리멤버앤컴퍼니 프론트엔드 보일러플레이트 — **비개발자가 Claude Code에 말로 요청해서 제품을 만드는** 세팅. 사용자는 개발자가 아니다: PR·git 같은 개발자 플로우를 시키지 않고, 만들고 → 화면으로 확인하고 → 고치는 루프만 남긴다. 인터넷에 올리는 것도 말 한마디("배포해줘")로 — `deploy` 스킬이 처리한다. **Vite + React + React Router (CSR)** + Tailwind v4 + shadcn/ui + TanStack Query + RHF/Zod + orval + React Compiler 전제 (스택 근거: `frontend-conventions` references/00 P-000).

**디자인 취향은 만드는 사람이 정하고, 품질은 하네스가 지킨다.** 특정 디자인 시스템을 강제하지 않는다 — 사용자가 원하는 느낌을 말하면 그대로 반영한다. 대신 ①그 취향이 화면마다 흔들리지 않게(`project-theme`), ②"AI가 막 만든 티"가 나지 않게(`ui-quality` + slop-check + `ui-critic`) 지킨다. 취향과 slop은 다르다.

> 이 템플릿은 앱 골격(shadcn/ui·TanStack Query·orval 등)이 이미 세팅돼 있다. 첫 요청은 `start-feature`부터.
>
> **준비물 (처음 1회):** `pnpm` 명령이 없다고 나오면 `npm install -g pnpm`을 한 번 실행한다 — 이 프로젝트는 pnpm(packageManager 고정)을 쓴다.

## 사용자를 대하는 법 (비개발자 커뮤니케이션 룰)

- **기술 용어로 묻지 않는다.** "컴포넌트를 widgets에 둘까요 features에 둘까요" ❌ → 그런 결정은 스킬 기준대로 알아서. 사용자에게 묻는 건 **눈에 보이는 차이**뿐: "목록을 표로 보여드릴까요, 카드로 보여드릴까요?"
- git·PR·브랜치·타입체크 같은 용어를 사용자에게 노출하지 않는다. "저장해뒀어요", "아까 상태로 되돌렸어요"처럼 결과 언어로 말한다.
- 진행 보고도 화면·동작 언어로: "지원자 목록 화면이 생겼고, 이름을 누르면 상세가 열려요."
- 에러가 나면 원인 용어를 늘어놓지 말고, 고친 뒤 결과만 알린다 (`fix-error`). 사용자 결정이 필요할 때만 쉬운 말로 묻는다.

## 만들기 루프 (요구 → 화면)

**빠르게 보여주고, 무거운 검사는 뒤로.** 유저는 "10분 만에 1차 화면"을 원하지 완벽 검증을 기다리지 않는다. 핑퐁 중엔 최소관문만, 전체검증은 코드가 이 컴퓨터를 떠날 때(배포·푸시)만 돈다.

**단계는 눈에 보이게.** 사이클 시작 때 단계를 태스크 리스트로 깔고 진행하며 체크한다 — 비개발자 언어로("린트"·"tsc" 금지, "확인"·"코드 리뷰"). 유저가 지금 어디쯤인지·몇 단계 남았는지 리스트로 본다.

### 핑퐁 사이클 (매번)

0. **맥락 복원** — 세션의 첫 요청이면 `session-note`로 `docs/tasks/`를 확인해 지난번 진행 상태를 먼저 알린다("지난번에 ○○까지 했어요. 이어서 할까요?"). 노트가 없으면 조용히 넘어간다. 앱이 아직 없으면 `init-app` 선행.
1. **설계** (새 화면일 때만) — `start-feature`로 분해하고 쉬운 요약으로 합의. 이때 단계 체크리스트를 세우고 **예상 시간을 한 줄로 말한다** ("보통 10~15분 정도 걸려요" — 기대치가 없으면 "느리다"가 된다). 첫 UI면 취향도 가볍게 (`project-theme` A).
2. **구현** — **라우트 + 스켈레톤(제목·빈 상태)부터** 만들어 브라우저를 그 라우트로 열어 두고("여기에 생길 거예요"), 그다음 스킬 기준대로 본 구현 (FSD 배치·Query Factory·frontend-conventions·`ui-quality`·`project-theme`).
3. **최소관문** — `pnpm preview`(타입 + type-aware lint + import 경계 + slop, 약 4.5초) → `show-screen`의 Playwright 로드 확인(흰 화면·콘솔 에러 0). **안 깨지고 안 촌스러우면 통과.** 실패하면 `fix-error`로 고친 뒤 재확인 — 깨진 화면은 넘기지 않는다. (lint·경계를 여기 둔 이유: 저장 훅은 단일 파일 비-type-aware만 봐서, 이 둘이 배포 직전까지 안 돌면 마지막에 한꺼번에 터진다 — 실사용 관찰)
4. **화면 열고 ⏸ 정지** — `show-screen`으로 브라우저를 열고 **멈춘다.** "화면 나왔어요. 고칠 데 있으면 말씀하세요." 여기서 Claude 차례가 끝나고 유저 차례. (핑퐁 중엔 이 뒤에 아무 단계도 없다 — 그래서 자연히 멈춘다.)
5. **임시저장 + 노트 갱신** — `checkpoint`가 이 사이클을 저장(되돌리기 안전망). **말없이 저장하지 않는다** — 첫 저장 전에 한 번 허락을 구하고, 승인 후엔 "여기까지 저장해뒀어요" 한 줄로만 알린다. 로컬 전용이라 전체검증 불요. 같은 지점에서 `session-note`가 진행 상태를 조용히 갱신한다(코드는 checkpoint가, 의도는 노트가 남긴다).

유저가 고칠 걸 말하면 2로 돌아간다(핑퐁). **완료를 유저가 선언해줄 거라 기대하지 않는다** — 다음 요청으로 바로 넘어가도 안전하다(저장돼 있고, 화면 안 깨졌고, 나갈 땐 무조건 검증되니까).

데이터가 남아야 하는 기능은 `data-storage` 스킬의 결정 트리(mock → localStorage → 외부 서비스)를 따른다. 사내 실데이터의 외부 저장은 사용자 확인 필수.

### 하드 관문 (코드가 이 컴퓨터를 떠날 때만)

"배포해줘 / 링크로 공유 / 다른 사람이 보게" (또는 git push) = 전체검증이 **반드시** 선행하는 유일한 지점. 여기서만:

- `verify` 전체 게이트(lint·typecheck·test·code-smell·slop·build) + `fe-reviewer`(코드) + `ui-critic`(화면) 심사.
- 실패하면 Claude가 조용히 고치고 재검 — 유저에겐 "올리기 전에 마지막 손질 중이에요" 정도로.
- 통과하면 `checkpoint` 깔끔저장 후 `deploy` 스킬로 Vercel에 올려 주소를 전달한다. 배포는 git push가 아니다.

**전체검증을 "유저가 마무리라고 말할 때"에 걸지 않는다** — 유저는 그 말을 안 한다. 반드시 지나가는 관문(배포·푸시)에 건다.

## 스킬 트리거 표

| 상황                                  | 로드할 것                                                    |
| ------------------------------------- | ------------------------------------------------------------ |
| 앱이 아직 없음 (첫 요청)              | `init-app`                                                   |
| 새 기능·화면 시작                     | `start-feature` (docs/PRODUCT.md 전제)                       |
| UI 작성/수정·디자인 요청              | `ui-quality` + `project-theme` + `frontend-conventions` 07장 |
| 코드 작성 전반                        | `frontend-conventions` (색인 → 해당 장만)                    |
| 새 파일 위치 고민                     | `feature-sliced-design` (공식 FSD v2.1) + 스택 라우팅 스킬   |
| API 호출·mutation 추가                | `query-factory`                                              |
| 데이터가 남아야 함                    | `data-storage`                                               |
| 실서버 연결 ("진짜 데이터로")         | `connect-api` (스펙 → codegen → 팩토리 교체)                 |
| 뭔가 깨짐·에러                        | `fix-error`                                                  |
| 인터넷에 올리기·링크 공유             | `deploy`                                                     |
| 정리·청소·주기 점검                   | `housekeeping`                                               |
| 화면 보여주기 (핑퐁)                  | `show-screen` (최소관문 `pnpm preview` 후 열고 정지)         |
| 세션 시작·"어디까지 했지"·이어서 하기 | `session-note` (docs/tasks 맥락 복원·갱신)                   |
| 테스트 작성·수정                      | `write-test` (유형별 템플릿)                                 |
| 작업 단위 확정·되돌리기               | `checkpoint` (매 사이클 임시저장)                            |
| 커밋 메시지 작성 (깔끔저장·수동 커밋) | `commit-convention`                                          |
| 배포·푸시 시 (하드 관문)              | `verify` 전체 → `fe-reviewer` → `ui-critic`                  |

핵심 절차는 `skill-injector.sh` hook이 프롬프트 신호(신규 기능·UI·에러·완료 선언)를 보고 결정적으로 로드 지시를 주입한다 — 자동 발동 운에 맡기지 않는다.

## 진실의 출처 (Source of Truth)

| 영역                          | 1순위                                                                                                                 |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| 제품 맥락 (누구용·register)   | `docs/PRODUCT.md`                                                                                                     |
| 설계 결정의 이유·트레이드오프 | `docs/architecture.md` (규칙이 아니라 **왜 그렇게 정했는지**)                                                         |
| 레이어별 배치 규칙            | `src/<레이어>/CLAUDE.md` (그 폴더를 만질 때 자동으로 읽힌다)                                                          |
| 디자인 취향                   | **사용자 본인** — theme 번역본은 `src/app/index.css` + `docs/theme.md`                                                |
| UI 품질 (anti-slop)           | `.claude/skills/ui-quality` + `.claude/scripts/slop-check.sh`                                                         |
| 코드 원칙 49개                | `frontend-conventions` 스킬 — 폴더는 `.claude/skills/frontend-code-convention/references/` (원본: 팀 공통 원칙 문서)  |
| 아키텍처 (FSD)                | `.claude/skills/feature-sliced-design` (공식 v2.1 원칙 SSOT) + `.claude/skills/fsd-router` (Vite + React Router 통합) |
| 데이터 페칭                   | `.claude/skills/query-factory`                                                                                        |
| 품질 판정                     | `.claude/agents/fe-reviewer` (코드) · `.claude/agents/ui-critic` (화면) — 둘 다 read-only 격리                        |

## 세션 레슨 (.claude/wiki)

교정받은 것·조용한 실패 함정·뒤집힌 가정은 **개인 기억이 아니라 `.claude/wiki/incidents.md`에** 술어형으로 남긴다 — 개인 메모리는 다른 세션에 닿지 않는다. 색인(`wiki/index.md`, 50줄 캡)은 세션 시작에 자동 주입되고, 같은 실수가 2회+ 재발하면 `gate-promotion.md`의 3판정으로 게이트/rule로 승격시킨다.

## 룰 ↔ 게이트 매핑 (게이트가 잡는 규칙은 여기 반복하지 않는다)

코드 품질은 prose가 아니라 게이트가 강제한다. 같은 규칙을 문서에 다시 적으면 한쪽만 갱신되며 모순이 시작된다.

| 규칙                                        | 강제 지점                 |
| ------------------------------------------- | ------------------------- |
| 수동 메모·`any`·`let`·복잡도·deprecated API | oxlint (`.oxlintrc.json`) |
| FSD 레이어 단방향·cross-slice               | oxlint fsd 플러그인       |
| 순환·radix 봉인·생성물 봉인                 | dependency-cruiser        |
| 폴더 구조·공개 API                          | steiger                   |
| 복붙(중복 컴포넌트명)·톤·구조 휴리스틱      | code-smell.sh             |
| UI slop(그라데이션·emoji·svg·em dash 등)    | slop-check.sh             |
| 테마 색 대비(본문·포커스·입력 경계)         | contrast-check.mjs        |
| 죽은 파일·미사용 export                     | knip (`@public` 예외)     |
| 게이트 우회(--no-verify)·새 파일 배치 판단  | PreToolUse 훅             |
| 화면의 UX 계약(확인·빈 상태·실패·최소 폭)   | PreToolUse 훅 (설계 단계) |
| 게이트 자체의 생존                          | gate-selftest             |

**여기(문서)에는 게이트가 못 잡는 것만 남긴다**: 배치 판단(feature-sliced-design 스킬), 상태 설계·에러 타입·합성 판단(`.claude/rules/`), 화면 품질(ui-critic), 골든 심사(fe-reviewer).

## 골든샘플 — 코드가 문서다

새 코드는 MD 설명이 아니라 **실코드 골든샘플을 복제**해서 시작한다. 코드가 발산하면(같은 문제를 화면마다 다르게 풂) 골든샘플을 늘리는 게 답이다:

| 패턴                                                                                                                                                                                        | 골든샘플             |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| 대시보드 한 화면: KPI 카드 + recharts 차트(shared/ui chart) + 표 + URL 상태(검색·필터·정렬·페이지, nuqs) + 카드 목록 + 생성 다이얼로그(overlay-kit, RHF+zod) + 삭제 확인(openConfirmDialog) | `pages/sample-table` |
| 쿼리/뮤테이션 팩토리                                                                                                                                                                        | `entities/post/`     |

### 샘플 수명주기 — 지우는 게 아니라 역할을 이관한다

샘플의 가치는 **파일이 있는 것**(AI 참조 + verify가 패턴을 계속 검증)이지 화면이 떠 있는 것이 아니다. 삭제 판단을 사용자(비개발자)에게 맡기지 않는다:

1. **첫 실제 화면이 생기면** — 루트(`/`)를 실제 화면으로 바꾸고 **샘플 라우트 등록은 지운다**(외부에 연습용 화면이 보이면 안 된다). **파일은 남긴다** — AI가 복제할 원본이고, lint·타입·테스트·code-smell이 계속 검증한다. knip만 이 폴더를 심사에서 뺀다(`knip.jsonc`) — 라우트가 유일한 참조라 안 그러면 죽은 파일로 잡힌다 (`start-feature`).
2. **실제 화면이 2~3개 쌓이면** — 앱 자신의 화면이 골든이 된다. `housekeeping`이 이관을 판정해 위 표를 실제 화면으로 갱신하고, 사용자 확인 후 샘플을 삭제(knip 연쇄 정리 + verify)한다.
3. **배포(하드 관문) 안전망** — 샘플 라우트가 남은 채 배포하지 않는다 (`deploy` 0.5단계). 실제 화면이 하나도 없으면(샘플 데모 배포) 예외.

## 테스트 룰

- Vitest + RTL, 콜로케이션, `.spec.ts(x)` 네이밍.
- 도메인/로직은 테스트 의무. 화면의 시각 검증은 테스트가 아니라 `ui-critic` + 사용자가 한다.

## 체크포인트 룰 (git은 Claude 내부 도구)

상세 절차는 `checkpoint` 스킬. 요지: **2단 저장** — 핑퐁마다 임시저장(preview 후, `chore: checkpoint`, **첫 저장 전 1회 허락 — 무허락 자동 커밋 금지**) + 배포·푸시 하드 관문에서 깔끔저장(verify+심사 후). 메시지 형식은 `commit-convention` 스킬이 SSOT(type(scope) + Why/How + Refs + `Co-Authored-By: Claude <noreply@anthropic.com>`), 되돌리기는 revert(이력 보존, 되돌리기 전 현 상태 커밋), 사용자에게 git 용어 노출 금지. PR·머지·push는 루프에 없다(배포는 `deploy`).

## 룰 충돌 시 우선순위

상위 룰이 항상 이긴다. 하위가 상위와 충돌하면 하위가 잘못 — PR로 정렬한다.

1. 글로벌 `~/.claude/CLAUDE.md` (개인 전역)
2. 본 파일 (레포 룰)
3. `.claude/rules/<topic>.md` — 상태 설계(component-modeling)·에러 타입(error-types)·테스트 철학(testing)·주석(comments)·실측 의무(measure-before-asserting)·타입 합성(type-composition)·라이브러리 결정표(dependencies)·보안 최소선(security)·게이트 승격 루프(gate-promotion)
4. `.claude/skills/<topic>/SKILL.md` + references (가장 구체적, 가장 자주 회전)

같은 결정을 두 곳에 적지 않는다 — 이중 진실은 한쪽만 갱신되며 모순이 시작된다. 룰을 추가·수정하기 전에 `grep -rE "<keyword>" CLAUDE.md .claude/`로 중복을 먼저 확인한다. references/ 원칙의 개정은 원본(팀 공통 원칙 문서) 먼저.
