🎉 init: Nuxt 프로젝트를 위한 공통 지침 및 스크립트 추가

This commit is contained in:
hyeonggil
2026-04-19 20:44:32 +09:00
commit 5ccb27f86e
337 changed files with 3191 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
# Claude 작업 방식 지침
이 문서는 Claude가 팀 프로젝트에서 작업할 때 따라야 할 일반적인 원칙을 정의합니다.
## 기본 원칙
1. **기존 코드 존중**: 수정 전에 관련 파일과 주변 컨벤션을 먼저 파악합니다.
2. **최소 변경**: 요구사항을 충족하는 최소한의 변경만 수행합니다. 관련 없는 리팩토링은 별도 작업으로 분리합니다.
3. **가정 대신 질문**: 요구사항이 모호하면 추측하지 말고 사용자에게 확인합니다.
4. **근거 있는 수정**: 코드 변경의 이유를 설명할 수 있어야 합니다.
## 작업 순서
1. **탐색 (Explore)**
- 관련 파일을 먼저 읽고 프로젝트 구조를 파악합니다.
- 유사한 패턴이 이미 존재하는지 확인합니다.
2. **계획 (Plan)**
- 여러 파일을 수정하거나 복잡한 작업이면 할 일 목록을 만들어 공유합니다.
- 아키텍처에 영향을 주는 변경은 착수 전에 사용자 승인을 받습니다.
3. **구현 (Implement)**
- 한 번에 하나의 논리적 변경에 집중합니다.
- 공통 지침과 프로젝트 지침을 모두 준수합니다.
4. **검증 (Verify)**
- 린트 / 타입체크 / 빌드가 깨지지 않는지 확인합니다.
- 테스트가 있는 프로젝트라면 관련 테스트를 실행합니다.
- 수동 검증이 필요한 경우 확인 방법을 사용자에게 안내합니다.
## 해서는 안 되는 것
- **임의 기능 추가 금지**: 사용자가 요청하지 않은 기능을 추가하지 않습니다.
- **기존 코드 대량 리팩토링 금지**: 요청 범위를 벗어나는 변경은 하지 않습니다.
- **주석 / 문서 임의 삭제 금지**: 불필요해 보여도 삭제 전 사용자에게 확인합니다.
- **비밀정보 출력 금지**: 환경변수, 키, 토큰 등은 코드에 하드코딩하지 않습니다.
- **의존성 버전 임의 변경 금지**: 요청이 없다면 `package.json`의 버전을 변경하지 않습니다.
- **강제 푸시 / 히스토리 재작성 금지**: `push --force`, `reset --hard` 등은 사용자의 명시적 요청 없이 실행하지 않습니다.
## 커뮤니케이션
- 답변은 간결하게, 결론을 먼저 말합니다.
- 코드를 수정했다면 **어떤 파일을 어떻게 바꿨는지** 요약합니다.
- 불확실한 부분은 솔직하게 밝히고 대안을 제시합니다.
- 긴 설명보다 실제 결과물(코드/파일)을 우선합니다.
## 파일 작업 원칙
- 새 파일 생성보다 **기존 파일 수정**을 우선합니다.
- README, 문서는 사용자가 명시적으로 요청했을 때만 생성합니다.
- 파일을 읽지 않고 수정하지 않습니다.
- 대량 변경 시에는 diff를 확인할 수 있도록 단계별로 진행합니다.
## 질문이 필요한 상황
다음의 경우 반드시 사용자에게 확인을 요청합니다.
- 요구사항의 일부가 불명확할 때
- 여러 구현 방식이 있고 각각 장단점이 뚜렷할 때
- 공통 지침과 프로젝트 지침이 충돌할 때
- 파괴적 작업(파일 삭제, 데이터 마이그레이션, 스키마 변경 등)이 필요할 때
- 외부 서비스 호출이나 결제 관련 작업일 때

View File

@@ -0,0 +1,50 @@
# 코딩 컨벤션
## 기본 원칙
- **가독성 우선**: 영리한 코드보다 읽기 쉬운 코드를 선호합니다.
- **일관성 유지**: 기존 코드의 스타일을 먼저 관찰하고 그에 맞춥니다.
- **작은 단위**: 함수와 파일은 한 가지 책임만 지도록 작게 유지합니다.
## 포맷팅
- 들여쓰기: 스페이스 2칸 (탭 사용 금지)
- 문자열: 싱글 쿼터(`'`) 사용, JSX/템플릿 속성값은 더블 쿼터(`"`)
- 세미콜론: 생략하지 않고 항상 작성
- 줄 끝 공백 제거, 파일 끝 개행 1줄 유지
- 한 줄 최대 100자 (초과 시 줄바꿈)
- Prettier 설정 파일(`.prettierrc`)이 있는 경우 해당 설정을 우선합니다.
## 네이밍
- **변수/함수**: `camelCase` (예: `userProfile`, `fetchUserData`)
- **상수**: `UPPER_SNAKE_CASE` (예: `MAX_RETRY_COUNT`)
- **컴포넌트/클래스/타입**: `PascalCase` (예: `UserCard`, `OrderStatus`)
- **파일명**
- Vue 컴포넌트: `PascalCase.vue` (예: `UserCard.vue`)
- Composable: `use` 접두사 + `camelCase` (예: `useAuth.ts`)
- 일반 TS 모듈: `kebab-case.ts` (예: `format-date.ts`)
- **이벤트 핸들러**: `handle` 또는 `on` 접두사 (예: `handleClick`, `onSubmit`)
- **불리언**: `is`, `has`, `can`, `should` 접두사 (예: `isLoading`, `hasError`)
## 타입
- `any` 사용 금지. 불가피할 경우 주석으로 이유를 남기고 `unknown`을 먼저 고려합니다.
- 함수 시그니처에는 매개변수와 반환 타입을 명시합니다.
- 공개 API(타 모듈에서 import 되는 것)는 반드시 타입을 export 합니다.
- 유니온 타입은 `as const` 또는 별도 타입 alias로 관리합니다.
## 주석
- "무엇을" 보다 "왜"를 설명합니다.
- TODO/FIXME 주석에는 작성자와 날짜 또는 이슈 번호를 포함합니다.
- 공개 함수/컴포넌트에는 JSDoc 한 줄 설명을 권장합니다.
## import 순서
1. 외부 라이브러리 (예: `vue`, `nuxt`)
2. 내부 절대 경로 (예: `~/components/...`)
3. 상대 경로 (예: `./utils`)
4. 타입 only import는 각 그룹 내에서 별도 블록으로 분리
그룹 사이에는 빈 줄을 한 줄 둡니다.

View File

@@ -0,0 +1,83 @@
# 커밋 / PR 규칙
## 커밋 메시지
[Conventional Commits](https://www.conventionalcommits.org/)를 따릅니다.
```
<type>(<scope>): <subject>
<body>
<footer>
```
### type
- `feat`: 새로운 기능 추가
- `fix`: 버그 수정
- `refactor`: 기능 변화 없는 구조 개선
- `style`: 코드 포맷/세미콜론 등 스타일 변경
- `docs`: 문서 수정
- `test`: 테스트 추가/수정
- `chore`: 빌드, 설정, 패키지 업데이트 등
- `perf`: 성능 개선
- `ci`: CI 설정 변경
### 작성 규칙
- **subject**는 50자 이내, 명령형 현재 시제(예: `add`, `fix``added`, `fixes` 아님)
- subject 끝에 마침표를 찍지 않습니다.
- body는 "무엇을"보다 "왜"를 설명합니다. 한 줄 72자 이내로 줄바꿈합니다.
- 한 커밋에는 하나의 논리적 변경만 담습니다.
### 예시
```
feat(user): add profile image upload
프로필 이미지 업로드 요구사항에 따라 multipart 업로드 경로를 추가했습니다.
기존 텍스트 필드 업데이트 API는 변경하지 않았습니다.
Refs: #123
```
## Pull Request
### 제목
커밋 메시지와 동일한 컨벤션을 따릅니다. (`<type>(<scope>): <subject>`)
### 본문 템플릿
```markdown
## 변경 사항
- 무엇이 바뀌었는지 요약
## 배경 / 이유
- 왜 이 변경이 필요했는지
## 테스트
- 어떻게 검증했는지 (수동/자동 테스트 내용)
## 스크린샷 (UI 변경 시)
- Before / After
## 체크리스트
- [ ] 로컬에서 빌드/테스트 통과
- [ ] 린트/포맷 통과
- [ ] 공통 지침(gameservice-fe-agent) 준수
- [ ] 관련 문서 업데이트
```
### 리뷰 기준
- 최소 1명 이상의 승인 필요
- CI(Lint / Test / Build) 전부 통과 필요
- 머지 전략은 **Squash and merge**를 기본으로 합니다.
- 리뷰어는 변경 범위에 대해 질문이 남지 않도록 배경을 충분히 이해한 뒤 승인합니다.
### Draft PR
- 작업 중간 중간 피드백이 필요한 경우 Draft로 먼저 올리는 것을 권장합니다.
- Draft 상태에서는 CI 실패가 있어도 괜찮습니다.

View File

@@ -0,0 +1,47 @@
# 프레임워크 / 라이브러리 사용 규칙
## Vue 3 / Nuxt
### 컴포넌트 작성
- **`<script setup lang="ts">` 사용**을 기본으로 합니다. Options API는 신규 코드에서 사용하지 않습니다.
- 컴포넌트는 단일 책임 원칙을 지키며, 200줄을 넘으면 분리를 검토합니다.
- Props는 `defineProps<T>()` 제네릭 형태로 타입을 명시합니다.
- Emits는 `defineEmits<{ ... }>()` 제네릭 형태로 선언합니다.
- `ref` vs `reactive`: 원시값과 단일 객체는 `ref`, 복잡한 상태 트리는 `reactive`를 고려합니다. 일관성을 위해 팀 내에서 가능한 `ref`를 우선합니다.
### 상태 관리
- 컴포넌트 내 로컬 상태: `ref` / `reactive`
- 여러 컴포넌트가 공유하는 상태: **Pinia** 사용
- 서버 상태: Nuxt `useFetch` / `useAsyncData` 사용, 직접 `fetch` 호출은 지양합니다.
### 라우팅
- Nuxt의 파일 기반 라우팅을 사용합니다. 수동 라우트 정의는 특수한 경우에만 허용됩니다.
- 동적 라우트 파라미터는 `[param].vue` 형식을 사용합니다.
### Composable
- 재사용 가능한 로직은 `composables/` 디렉토리의 `useXxx` 함수로 추출합니다.
- Composable은 부수효과를 최소화하고, 반환 객체에 상태와 메서드를 함께 묶어 반환합니다.
## TypeScript
- `strict: true`를 유지합니다.
- 공용 타입은 `types/` 또는 각 도메인의 `types.ts`에 모아둡니다.
- 외부 API 응답은 반드시 타입을 정의하여 사용합니다.
## Tailwind CSS
- **유틸리티 클래스 우선** 사용. 공통 패턴은 컴포넌트로 추출합니다.
- `@apply`는 꼭 필요한 경우에만 사용하고, 가능한 유틸리티를 직접 나열합니다.
- 임의값 클래스(`w-[123px]`)는 디자인 시스템에 등록되지 않은 값에만 제한적으로 사용합니다.
- 조건부 클래스는 `clsx` 또는 `cn` 유틸리티를 사용하여 가독성을 확보합니다.
- 클래스 순서는 Tailwind 공식 프리셋(`prettier-plugin-tailwindcss`)을 따릅니다.
## 외부 라이브러리 도입
- 새로운 라이브러리를 추가할 때는 **PR 설명에 도입 이유, 번들 영향, 대안 검토 내용**을 기록합니다.
- 동일 기능의 라이브러리를 중복 도입하지 않습니다.
- 유지보수가 중단된 패키지(6개월 이상 업데이트 없음)는 도입하지 않습니다.