# 전역 규칙
## 작업
### 순서
1. **이해** — 요청 파악
2. **작업 계획** — 계획표 제시
3. **작업** — 계획 제시 후 바로 진행
4. **작업 완료** — 완료표 + 테스트 방법 제시
5. **커밋** — 작업 완료 후 자동 진행, `Co-Authored-By: Claude` 포함 금지
> 빌드(`npm run build`)와 푸시(`git push`)는 명시적 요청 시에만 실행
### 규칙
- 요청 범위 밖 코드는 건드리지 말 것
- 삭제 전 다른 곳에서 참조하는지 확인할 것
- 범위가 클 때는 단계별로 진행하며 중간에 확인받을 것
- 불확실하면 추측하지 말고 물어볼 것
- 버그 수정 시 근본 원인을 파악할 것 (증상만 막는 우회 금지)
- 같은 파일이라도 기능이 다르면 커밋 분리
- 태스크 파일: 새 작업이면 시작 전 항목 추가, 커밋 완료 후 완료(`[x]`) 처리
### Supabase MCP
- DB 스키마 변경·RLS 정책·데이터 조회 작업 시 Supabase MCP 활용
- MCP 미연결 상태에서 DB 관련 작업 요청 시: 즉시 알리고 작업 일시 중지
| 상황 | 도구 |
|------|------|
| 테이블 스키마 변경 | `apply_migration` |
| 테이블 구조 확인 | `list_tables` |
| 데이터 조회·수정·RLS 확인 | `execute_sql` |
| TypeScript 타입 동기화 | `generate_typescript_types` |
### 빌드 검증
- 빌드는 자동 실행 금지 — 명시적 요청 또는 "배포 오류" 언급 시에만 실행
- 에러 발생 시 즉시 수정 후 재빌드 — 통과될 때까지 반복
### 양식
#### 작업 계획표
작업 시작 전 아래 형식으로 계획을 제시할 것:
**작업명:** (작업 이름)
**작업 경로:** 홈페이지 > 캠프 신청 > 기본정보 (페이지 > 섹션 > UI 단위)
| 순서 | 파일 | 변경 내용 |
|------|------|-----------|
| 1 | `src/foo/Bar.tsx` | 어떤 이유로 무엇을 어떻게 변경할지 |
| 2 | `src/foo/baz.ts` | 어떤 이유로 무엇을 어떻게 변경할지 |
#### 작업 완료표
작업 완료 후 아래 형식으로 정리할 것:
**작업명:** (작업 이름)
**작업 경로:** 홈페이지 > 캠프 신청 > 기본정보 (페이지 > 섹션 > UI 단위)
| 작업 | 경로 (파일:라인 또는 파일:시작-끝) | 설명 |
|------|-----------------------------------|------|
| 추가 | `src/foo/Bar.tsx:12` | 설명 |
| 수정 | `src/foo/Bar.tsx:34-56` | 설명 |
| 삭제 | `src/foo/Bar.tsx:78` | 설명 |
**요약:** 무엇을 왜 바꿨는지 1~3문장으로 서술.
**테스트:** 홈페이지 > 캠프 신청 > 등록하기 버튼 클릭 (UI·동작 변경 없으면 생략)
#### 커밋 컨벤션
형식: `이모지 한국어 설명`
| 이모지 | 용도 |
|--------|------|
| ✨ | 새 기능 |
| 🐛 | 일반 버그 픽스 |
| 🚑 | 긴급 버그 픽스 |
| 🌱 | 일반 / 기타 |
| 🚀 | 배포 |
| ⚙ | 리팩토링 / 설정 변경 |
| 🎨 | 스타일링 |
| 🧪 | 테스트 / 데모 |
#### 기본 답변 양식
- 한국어로 답변할 것
- 핵심만 간결하게, 불필요한 말 생략
- 파일 검색 시 관련 라인 함께 첨부
---
## 검수
코드 변경 후 품질 검증이 필요할 때 수행. 자동화 도구 없이 DB 쿼리 + 코드 리뷰 방식으로 진행.
### 검수 순서
1. **범위 파악** — `git log --format="%h %ad %s" --date=format:"%m-%d %H:%M" --since="YYYY-MM-DD"` 로 커밋 목록 조회
2. **DB 검증** — Supabase MCP `execute_sql`로 스키마·제약·FK 확인
3. **코드 리뷰** — 핵심 변경 파일 정적 분석 (로직 추적, 엣지 케이스 확인)
4. **TC 작성** — 아래 양식으로 결과 정리
5. **이슈 수정** — 발견된 버그 즉시 수정 후 커밋
### TC 양식
#### A. DB 스키마 검증
Supabase MCP `execute_sql`로 직접 쿼리하여 확인.
```
확인 항목: 컬럼 존재, CHECK 제약, FK, NOT NULL 등
```
| TC | 항목 | 확인 방법 | 결과 |
|----|------|-----------|------|
| A-1 | 컬럼명 존재 | `information_schema.columns` | ✅ / ❌ |
| A-2 | CHECK 제약 내용 | `pg_constraint` | ✅ / ❌ |
#### B. 핵심 로직 코드 리뷰
변경된 핵심 파일 직접 읽고 로직 정합성 확인.
| TC | 항목 | 확인 내용 | 결과 |
|----|------|-----------|------|
| B-1 | 로직명 | 파일:라인 — 확인 내용 | ✅ / ❌ |
#### C. 브라우저 직접 확인 필요
코드 리뷰로 확인 불가한 UI·렌더링·인터랙션 항목.
| TC | 항목 | 테스트 경로 |
|----|------|-------------|
| C-1 | UI 항목 | 홈페이지 > 섹션 > 동작 확인 |
#### D. 발견된 이슈
| 번호 | 심각도 | 파일 | 내용 |
|------|--------|------|------|
| I-1 | 🔴 심각 / 🟡 경미 / 🟢 낮음 | `경로:라인` | 이슈 설명 |
> 심각도 기준: 🔴 데이터 손실·기능 불가 / 🟡 잘못된 동작·UX 저하 / 🟢 코드 품질·잠재적 위험
---
## 코딩 규칙
### 공통
- MUI + Emotion styled components 사용 (스타일은 파일 하단에 모아서 정리)
- styled component 이름은 PascalCase, 의미 있게 작성
- styled component에 전달하는 조건부 props는 `$` prefix 사용 (예: `$isFilled`, `$isActive`) — DOM 전파 방지
- TypeScript 사용, `any` 최소화 (불가피한 경우 주석으로 이유 명시)
- 새 파일보다 기존 파일 수정 선호, 불필요한 코드/파일 즉시 정리
- 간단한 레이아웃은 MUI `<Stack>`, `<Grid2>` 사용
- 파일당 컴포넌트 1개 원칙 (스타일 컴포넌트 제외)
- props 타입 항상 명시 (`type PropsType = { ... }`)
- 컴포넌트 로직 200줄 초과 시 분리 고려
- 자주 쓰는 UI는 MUI 테마 또는 공통 컴포넌트로 재사용
- `console.log` 배포 전 제거 (console.error는 에러 처리용으로 유지)
- 매직 넘버/문자열은 상수로 분리하여 의미 부여
### 아키텍처: 관심사 분리(Separation of Concerns) 기반 레이어드 아키텍처
FSD(Feature-Sliced Design)에서 영향을 받은 레이어드 아키텍처를 사용한다. 각 레이어는 아래 역할만 담당하며 역할 침범 금지.
| 레이어 | 위치 | 역할 | 금지 사항 |
|--------|------|------|-----------|
| **Presentation** | `views/`, `components/` | UI 렌더링 | 데이터 패칭, 유틸 정의, 상수 정의 |
| **Application** | `views/[domain]/_hooks/`, `hooks/` | 데이터 패칭 + 로컬 상태 조율 | UI 반환, supabase 직접 호출 |
| **Service** | `service/` | Supabase 호출 전담, 순수 async 함수 | 상태 변경, UI 로직 |
| **State** | `store/` | 전역 상태 변경만 | 데이터 패칭, 비즈니스 로직 |
| **Shared** | `utils/`, `constants/`, `types/` | 전역 재사용 유틸·상수·타입 | 특정 도메인 종속 로직 |
#### 컴포넌트 (Presentation)
- UI 렌더링 중심. `useState`는 순수 UI 상태(모달 열림, 탭 선택 등)만 허용
- 데이터 패칭, 비즈니스 로직, 유틸 함수 정의 금지
- 서비스 함수 직접 호출 금지 — 반드시 훅을 통해 사용
#### 훅 (Application)
- 데이터 패칭 + 관련 로딩/에러 상태 + 액션 함수를 묶어 반환
- `service/` 함수만 호출, supabase 직접 import 금지
- 전역 범위: `src/hooks/`, 도메인/페이지 범위: `src/views/[domain]/_hooks/`
#### 상수 (Constants)
- 전역 재사용: `src/constants/`
- 특정 도메인/페이지 전용: `src/views/[domain]/_constants/`
- 중복 정의 절대 금지 — 같은 값이 두 곳에 있으면 공통 파일로 통합
#### 유틸 함수 (Utils)
- 전역 재사용: `src/utils/`
- 특정 도메인/페이지 전용: `src/views/[domain]/_utils/`
- 컴포넌트·훅 내부에 유틸 함수 인라인 정의 금지
### 폴더 구조
```
src/
├── app/ # 라우트 (page.tsx, layout.tsx만)
│ ├── admin/ # 어드민
│ ├── api/ # API Route Handlers
│ └── ...
├── views/ # 페이지별 컨테이너 + 하위 구성
│ └── [domain]/
│ ├── [PageContainer].tsx
│ ├── _components/ # 해당 도메인 내 재사용 컴포넌트
│ ├── _hooks/ # 해당 도메인 데이터 패칭 훅
│ ├── _utils/ # 해당 도메인 전용 유틸 함수
│ └── _constants/ # 해당 도메인 전용 상수
├── components/ # 전역 공통 컴포넌트
├── service/ # DB 쿼리, 외부 API 호출 (Supabase 전담)
├── store/ # Zustand 전역 상태 관리 (상태 변경만)
├── hooks/ # 전역 공통 커스텀 훅
├── types/ # 전역 타입
├── constants/ # 전역 상수
├── styles/ # 전역 스타일, mixins
├── lib/ # 라이브러리 초기화
└── utils/ # 전역 유틸 함수
```
### 에러
- catch 블록: `console.error` 후 `throw`
- 사용자 노출 에러: `notistack enqueueSnackbar` 사용
### 주석
- 한국어로 작성
- 섹션: `//////////////////////////////////////// 섹션명 ////////////////////////////////////////`
- 중간: `////////// 함수/기능명`
- 소단위: `//////////////////// 설명 ////////////////////`
- 인라인: `// 설명`
- JSX: `{/* 설명 */}`
### 보안
- 민감 정보 하드코딩 금지, 환경변수로 처리
- 서버 전용 환경변수에 `NEXT_PUBLIC_` 접두사 사용 금지
- `.env.local` 수정 시 `.env.production`도 함께 수정
- 커밋 전 민감 정보(키, 비밀번호, 토큰) 포함 여부 확인
### 기술 스택
- Next.js (App Router)
- TypeScript
- MUI v6 + Emotion
- Zustand (persist 미들웨어)
- Supabase (Auth, DB)
- notistack (스낵바)
- dayjs (날짜)
- Vercel (배포)
> 데이터 패칭은 `useEffect` + async 직접 호출 방식 사용 (React Query 미도입). 도입 필요 시 먼저 논의할 것.
> 현재 스택으로 해결하기 어렵거나 더 적합한 라이브러리가 있으면 이유와 함께 추천할 것