- Add end-to-end issue-to-deploy workflow with Claude Code prompts - Add daily standup assistant workflow - Add knowledge accumulation workflow with Obsidian - Add onboarding guide for new team members - Add troubleshooting guide for common scenarios Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
760 lines
26 KiB
Markdown
760 lines
26 KiB
Markdown
# CLAUDE.md – 프로젝트 가이드
|
||
|
||
> 이 파일은 AI 코딩 어시스턴트(Claude, Cursor 등)가 이 저장소에서 작업할 때
|
||
> 따라야 할 규칙과 컨텍스트를 정의합니다. 반드시 숙지 후 작업하세요.
|
||
|
||
---
|
||
|
||
## 프로젝트 개요
|
||
|
||
| 항목 | 내용 |
|
||
|------|------|
|
||
| 프로젝트명 | (프로젝트명을 여기에 입력하세요) |
|
||
| 목적 | (프로젝트의 목적을 한 줄로 설명하세요) |
|
||
| 기술 스택 | Python 3.11 · FastAPI · PostgreSQL 15 · React 18 · TypeScript |
|
||
| 아키텍처 | 모놀리스 (추후 마이크로서비스 전환 예정) |
|
||
| 주요 언어 | 한국어 (코드 내 주석 및 커밋 메시지는 영어 사용) |
|
||
|
||
---
|
||
|
||
## 디렉터리 구조
|
||
|
||
### 프로젝트 저장 위치
|
||
|
||
모든 개발 프로젝트는 **건별로** 아래 경로에 저장합니다.
|
||
|
||
```
|
||
/Users/joungmin/workspaces/
|
||
├── {프로젝트명-A}/ ← 프로젝트 단위로 디렉터리 생성
|
||
├── {프로젝트명-B}/
|
||
└── ...
|
||
```
|
||
|
||
> 새 프로젝트 시작 시:
|
||
> ```bash
|
||
> cd /Users/joungmin/workspaces
|
||
> git clone https://gitea.cloud-handson.com/{org}/{repo}
|
||
> # 또는
|
||
> mkdir {프로젝트명} && cd {프로젝트명}
|
||
> ```
|
||
|
||
### 프로젝트 내부 구조 (표준)
|
||
|
||
```
|
||
/Users/joungmin/workspaces/{프로젝트명}/
|
||
├── backend/
|
||
│ ├── api/ # FastAPI 라우터 (엔드포인트 정의)
|
||
│ ├── models/ # SQLAlchemy DB 모델
|
||
│ ├── schemas/ # Pydantic 요청/응답 스키마
|
||
│ ├── services/ # 비즈니스 로직 레이어
|
||
│ └── core/ # 설정, 의존성 주입, 미들웨어
|
||
├── frontend/
|
||
│ └── src/
|
||
│ ├── components/ # 재사용 가능한 UI 컴포넌트
|
||
│ ├── pages/ # 라우트 단위 페이지
|
||
│ ├── hooks/ # 커스텀 React Hooks
|
||
│ └── api/ # API 클라이언트 (axios/fetch 래퍼)
|
||
├── tests/
|
||
│ ├── unit/
|
||
│ ├── integration/
|
||
│ └── e2e/
|
||
├── docs/ # 설계 문서
|
||
├── .env.example # 환경 변수 템플릿 (실제 값 절대 포함 금지)
|
||
└── Makefile
|
||
```
|
||
|
||
---
|
||
|
||
## 코딩 컨벤션
|
||
|
||
### Python (Backend)
|
||
- PEP 8 준수, **type hints 필수** (매개변수 및 반환값 모두)
|
||
- Docstring: Google 스타일
|
||
- 함수는 단일 책임 원칙(SRP) 준수, 50줄 초과 지양
|
||
- 예외 처리 시 bare `except:` 금지, 반드시 구체적인 예외 타입 명시
|
||
|
||
### JavaScript / TypeScript (Frontend)
|
||
- ESLint + Prettier 설정 준수 (`npm run lint` 통과 필수)
|
||
- 컴포넌트는 **함수형**만 사용, 클래스 컴포넌트 금지
|
||
- `any` 타입 사용 금지, 불가피한 경우 `unknown` 후 타입 가드 사용
|
||
- 상태 관리: 로컬 상태는 `useState`, 전역 상태는 별도 문서 참조
|
||
|
||
### Git 브랜치 전략 (Gitflow)
|
||
```
|
||
main ← 프로덕션 배포 전용 (직접 푸시 절대 금지)
|
||
develop ← 통합 개발 브랜치
|
||
feature/* ← 기능 개발 (예: feature/user-auth)
|
||
hotfix/* ← 프로덕션 긴급 수정
|
||
release/* ← 릴리즈 준비
|
||
```
|
||
|
||
### 커밋 메시지 (Conventional Commits)
|
||
```
|
||
feat: 새로운 기능 추가
|
||
fix: 버그 수정
|
||
docs: 문서 수정
|
||
test: 테스트 코드 추가/수정
|
||
refactor: 리팩터링 (기능 변경 없음)
|
||
chore: 빌드, 설정 파일 수정
|
||
```
|
||
|
||
---
|
||
|
||
## 환경 변수 및 시크릿 관리
|
||
|
||
- 모든 시크릿은 `.env` 파일에서 관리 (`.gitignore`에 반드시 포함)
|
||
- `.env.example`에 키 이름만 기재, 실제 값은 절대 커밋 금지
|
||
- AI가 코드를 작성할 때 API Key, 비밀번호, 토큰을 **하드코딩하지 말 것**
|
||
- 환경 변수 접근: `os.getenv("KEY_NAME")` 또는 `pydantic BaseSettings` 사용
|
||
|
||
---
|
||
|
||
## 외부 시스템 연동
|
||
|
||
| 시스템 | URL | 용도 |
|
||
|--------|-----|------|
|
||
| 이슈 트래커 | https://redmine.cloud-handson.com | 작업 이슈 관리 |
|
||
| CI/CD | https://jenkins.cloud-handson.com | 자동 빌드/배포 |
|
||
| Git 서버 | https://gittea.cloud-handson.com | 소스 코드 관리 |
|
||
| 지식베이스 | Obsidian Vault (/Users/joungmin/Documents/Obsidian Vault) | 설계 문서 동기화, para document 관리법 사용 |
|
||
|
||
## MCP 툴
|
||
|
||
외부 시스템은 MCP(Model Context Protocol) 툴을 통해 직접 제어할 수 있습니다.
|
||
API 호출 대신 MCP 툴을 우선 사용하세요.
|
||
|
||
### Jenkins (`mcp__jenkins__*`)
|
||
|
||
| 툴 | 설명 |
|
||
|----|------|
|
||
| `get_jobs` | 잡 목록 조회 |
|
||
| `get_job_config` | 잡 config.xml 조회 |
|
||
| `create_job` | 새 잡 생성 (config.xml 필요) |
|
||
| `edit_job` | 잡 설정 수정 (config.xml 필요) |
|
||
| `delete_job` | 잡 삭제 |
|
||
| `trigger_build` | 빌드 트리거 |
|
||
| `get_build_status` | 빌드 상태 조회 |
|
||
| `get_build_log` | 빌드 로그 조회 |
|
||
|
||
### Redmine (`mcp__redmine__*`)
|
||
|
||
| 툴 | 설명 |
|
||
|----|------|
|
||
| `getIssues` / `getIssue` | 이슈 목록/상세 조회 |
|
||
| `createIssue` | 이슈 생성 |
|
||
| `updateIssue` | 이슈 수정 |
|
||
| `deleteIssue` | 이슈 삭제 |
|
||
| `getProjects` / `getProject` | 프로젝트 조회 |
|
||
| `createProject` / `updateProject` | 프로젝트 생성/수정 |
|
||
| `getTimeEntries` / `createTimeEntry` | 시간 기록 조회/생성 |
|
||
| `getWikiPage` / `updateWikiPage` | 위키 페이지 조회/수정 |
|
||
| `search` | 전체 검색 |
|
||
| `getCurrentUser` | 현재 로그인 사용자 조회 |
|
||
|
||
---
|
||
|
||
## 개발 방법론
|
||
|
||
- 스프린트: **2주 주기 스크럼**
|
||
- 워크플로: `Redmine 이슈 생성` → `브랜치 생성` → `PR 작성` → `코드 리뷰` → `Jenkins CI 통과` → `develop 머지`
|
||
- 테스트 커버리지 목표: **unit 80%+**, integration 60%+
|
||
- PR 머지 전 최소 1명의 코드 리뷰 승인 필요
|
||
|
||
### 이슈 → 코드 워크플로우
|
||
1. 작업 시작 시 반드시 Redmine 이슈 번호 확인
|
||
2. 브랜치명 형식: `feature/RM-{이슈번호}-{간단설명}`
|
||
예: `feature/RM-342-user-auth-refactor`
|
||
3. 커밋 메시지: `RM-{번호}: {Conventional Commit 메시지}`
|
||
예: `RM-342: feat: add JWT refresh token logic`
|
||
|
||
### 코드 품질 기준
|
||
- 새 함수는 반드시 docstring + type hints
|
||
- 비즈니스 로직에 주석 필수
|
||
- 복잡도(cyclomatic complexity) 10 이하 유지
|
||
- 함수 길이 50줄 이하 권장
|
||
|
||
### PR 규칙
|
||
- PR 제목: `[RM-{번호}] {작업 내용}`
|
||
- 최소 1명 리뷰어 승인 필요
|
||
- Jenkins CI 통과 후 머지 가능
|
||
|
||
### PR 본문 템플릿
|
||
```
|
||
## 변경 사항
|
||
-
|
||
|
||
## 테스트 방법
|
||
-
|
||
|
||
## 스크린샷 (UI 변경 시)
|
||
|
||
## 관련 이슈
|
||
RM-{번호}
|
||
```
|
||
|
||
---
|
||
|
||
## 테스트 전략
|
||
|
||
### 테스트 피라미드
|
||
- **Unit Tests (70%)**: 순수 함수, 비즈니스 로직
|
||
- **Integration Tests (20%)**: API 엔드포인트, DB 연동
|
||
- **E2E Tests (10%)**: 핵심 사용자 시나리오
|
||
|
||
### 도구
|
||
| 종류 | Python | JavaScript |
|
||
|------|--------|------------|
|
||
| Unit | pytest | Jest |
|
||
| Integration | pytest + httpx | Supertest |
|
||
| E2E | — | Playwright |
|
||
| 커버리지 | pytest-cov (80% 목표) | Istanbul (80% 목표) |
|
||
|
||
### 테스트 명명 규칙
|
||
```
|
||
test_{대상}_{조건}_{기대결과}
|
||
예: test_user_login_with_invalid_password_returns_401
|
||
```
|
||
|
||
### 테스트 작성 지침
|
||
- **AAA 패턴** (Arrange, Act, Assert) + Given/When/Then 주석
|
||
- Mocking은 외부 의존성(API, DB)만
|
||
- 경계값, 엣지 케이스 반드시 포함
|
||
- 테스트당 assert 최소화 (SRP 원칙)
|
||
|
||
### Jenkins CI 파이프라인
|
||
```groovy
|
||
pipeline {
|
||
agent any
|
||
stages {
|
||
stage('Lint') {
|
||
steps {
|
||
sh 'ruff check . --output-format=github'
|
||
sh 'mypy src/'
|
||
}
|
||
}
|
||
stage('Unit Tests') {
|
||
steps {
|
||
sh 'pytest tests/unit/ -v --cov=src --cov-fail-under=80 --junitxml=test-results/unit.xml'
|
||
}
|
||
post {
|
||
always {
|
||
junit 'test-results/unit.xml'
|
||
publishCoverage adapters: [coberturaAdapter('coverage.xml')]
|
||
}
|
||
}
|
||
}
|
||
stage('Integration Tests') {
|
||
steps {
|
||
sh 'pytest tests/integration/ -v --junitxml=test-results/integration.xml'
|
||
}
|
||
}
|
||
stage('AI Code Review') {
|
||
when { changeRequest() }
|
||
steps {
|
||
sh '''
|
||
git diff origin/develop...HEAD | \
|
||
claude -p "이 코드 변경사항을 리뷰해줘. 보안, 성능, 코딩 컨벤션 관점에서 문제점만 JSON으로 출력" \
|
||
> review_output.json
|
||
'''
|
||
archiveArtifacts 'review_output.json'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 팀 역할별 운영 가이드
|
||
|
||
> 모든 역할은 동일한 MCP 설정을 공유하되, 역할별 주요 도구와 프롬프트 패턴을 달리 사용합니다.
|
||
|
||
### PM (프로젝트 매니저)
|
||
**주요 도구**: Redmine MCP, Obsidian MCP
|
||
|
||
**지침**
|
||
- 이슈 생성 시: 제목, 담당자, 마감일, 우선순위, 예상 시간(h), 수락 기준(체크리스트) 필수 입력
|
||
- 스프린트 리뷰 리포트는 Obsidian `Sprints/` 폴더에 저장
|
||
- 에픽-스토리-태스크 계층 구조 유지
|
||
|
||
**주요 프롬프트 패턴**
|
||
```bash
|
||
# 스프린트 현황 정리
|
||
"Redmine에서 이번 스프린트 이슈들의 상태를 가져와서 완료/진행중/대기/블로커로 분류하고 Obsidian Sprints/2026-W09.md에 정리해줘"
|
||
|
||
# 스프린트 계획 보조
|
||
"Redmine 백로그 상위 20개 이슈를 가져오고 예상 시간을 합산해서 2주 스프린트(팀원 4명, 주 40시간) 기준 소화 가능한 범위를 계획해줘"
|
||
|
||
# 회의록 → 이슈 자동 생성
|
||
"오늘 기획 회의 내용이야: [회의록] / 액션아이템을 추출해서 Redmine 이슈로 생성해줘. 담당자는 미정으로."
|
||
```
|
||
|
||
---
|
||
|
||
### 기획자 / 시스템 분석가
|
||
**주요 도구**: Obsidian MCP, Redmine MCP
|
||
|
||
**지침**
|
||
- 요구사항 문서: Obsidian `Requirements/{기능명}.md`에 저장
|
||
- 사용자 스토리 형식: "나는 {역할}로서 {기능}을 원한다. 왜냐하면 {이유} 때문이다."
|
||
- 화면 정의서: Mermaid 다이어그램 또는 ASCII 와이어프레임 사용
|
||
- 용어집(`Glossary.md`) 업데이트 필수
|
||
|
||
**주요 프롬프트 패턴**
|
||
```bash
|
||
# 요구사항 → 사용자 스토리 분해
|
||
"다음 기능 요구사항을 INVEST 원칙에 따라 사용자 스토리로 분해하고 수락 기준을 추가해서 Obsidian Requirements/기능명.md에 저장해줘: [요구사항]"
|
||
|
||
# API 명세 초안
|
||
"Obsidian Requirements/user-auth.md를 읽고 OpenAPI 3.0 명세 초안을 작성해줘. 엔드포인트, 요청/응답 스키마 포함."
|
||
|
||
# 시퀀스 다이어그램
|
||
"로그인 플로우를 Mermaid 시퀀스 다이어그램으로 그리고 Obsidian Diagrams/login-flow.md에 저장해줘"
|
||
```
|
||
|
||
---
|
||
|
||
### 개발자 (백엔드 / 프론트엔드)
|
||
**주요 도구**: Gitea MCP, Redmine MCP, Jenkins MCP
|
||
|
||
**지침**
|
||
- 새 작업 시작: Redmine 이슈 확인 → 브랜치 생성 → CLAUDE.md 읽기
|
||
- 코드 생성 시 기존 코드 스타일 분석 후 일관성 유지
|
||
- 외부 라이브러리 추가 시 보안 취약점 먼저 확인
|
||
- 레거시 코드 수정 시 회귀 테스트 먼저 작성
|
||
|
||
**주요 프롬프트 패턴**
|
||
```bash
|
||
# 이슈 기반 개발 시작
|
||
"Redmine 이슈 #342의 내용을 읽고 구현 계획을 세워줘. 필요한 파일 목록, 예상 작업 시간, 잠재적 위험 요소 포함."
|
||
|
||
# 코드 리뷰 요청
|
||
"feature/RM-342-user-auth 브랜치의 변경사항을 리뷰해줘. OWASP Top 10 보안 관점과 팀 컨벤션 준수 여부 중심으로."
|
||
|
||
# 빌드 실패 분석
|
||
"Jenkins 빌드 #123의 실패 로그를 가져와서 root cause를 분석하고 수정 방법을 제시해줘."
|
||
|
||
# 새 기능 구현
|
||
"Obsidian Requirements/payment-gateway.md의 명세를 읽고 FastAPI 엔드포인트와 서비스 레이어를 구현해줘. 기존 auth_service.py 패턴을 따라서."
|
||
```
|
||
|
||
---
|
||
|
||
### QA 엔지니어
|
||
**주요 도구**: Jenkins MCP, Gitea MCP, Redmine MCP
|
||
|
||
**지침**
|
||
- 테스트 케이스는 Redmine 이슈의 수락 기준에서 도출
|
||
- 버그 이슈: 즉시 Blocker / Critical / Major / Minor 분류
|
||
- 버그 리포트 필수 항목: 재현 단계, 기대 결과, 실제 결과, 환경 정보
|
||
- 머지 전 Jenkins 회귀 테스트 자동 실행 확인
|
||
|
||
**테스트 환경**
|
||
| 환경 | URL |
|
||
|------|-----|
|
||
| DEV | http://dev.company.com |
|
||
| STG | http://staging.company.com |
|
||
| PRD | http://app.company.com |
|
||
|
||
**주요 프롬프트 패턴**
|
||
```bash
|
||
# 테스트 계획 수립
|
||
"Redmine 이슈 #342의 수락 기준을 읽고 테스트 케이스를 작성해줘. Happy Path, Negative Case, 경계값, 보안 케이스 모두 포함."
|
||
|
||
# 빌드 품질 분석
|
||
"Jenkins에서 최근 5개 빌드의 테스트 결과를 가져와서 flaky 테스트를 찾고 실패 트렌드를 분석해줘."
|
||
|
||
# 회귀 테스트 커버리지 확인
|
||
"이번 스프린트에서 변경된 Gitea PR 목록을 가져와서 테스트가 없는 PR 목록을 알려줘."
|
||
|
||
# E2E 테스트 시나리오 작성
|
||
"Obsidian Requirements/checkout-flow.md를 읽고 Playwright E2E 테스트 스크립트를 작성해줘. Page Object Model 패턴 사용."
|
||
```
|
||
|
||
---
|
||
|
||
## 공통 워크플로우: 이슈 → 개발 → 배포
|
||
|
||
```
|
||
[PM] Redmine 이슈 생성 (수락 기준 포함)
|
||
↓
|
||
[개발자] 이슈 확인 → 브랜치 생성 (feature/RM-{번호}-{설명})
|
||
↓
|
||
[개발자] 구현 + 단위 테스트 작성 (커버리지 80%+)
|
||
↓
|
||
[개발자] PR 생성 → PR 본문 템플릿 작성 → 리뷰어 지정
|
||
↓
|
||
[QA / 개발자] 코드 리뷰 + Jenkins CI 자동 실행 (lint → unit → integration)
|
||
↓
|
||
[QA] STG 환경에서 수락 기준 기반 테스트
|
||
↓
|
||
[개발자] 승인 후 develop 머지
|
||
↓
|
||
[PM] Redmine 이슈 상태 → 완료 처리
|
||
```
|
||
|
||
### Claude Code 자동화 프롬프트 (전체 사이클)
|
||
```bash
|
||
# 이슈 기반 브랜치 자동 생성 (Makefile)
|
||
make start-issue # Redmine 이슈 번호 입력 → 브랜치 자동 생성
|
||
|
||
# PR 전 체크
|
||
make pr-ready # lint + test 자동 실행
|
||
|
||
# PR 설명 초안 생성
|
||
claude -p "현재 브랜치의 git diff를 분석해서 PR 본문 초안을 한국어로 작성해줘. Conventional Commit 형식 준수."
|
||
|
||
# 배포 후 이슈 완료 처리
|
||
"Redmine 이슈 #342 상태를 완료로 변경하고 실제 소요 시간을 기록해줘."
|
||
```
|
||
|
||
### 워크플로우 1: 이슈 → 개발 → 배포 전체 사이클 (상세)
|
||
|
||
```
|
||
[PM] Redmine 이슈 생성
|
||
"API 로그인 기능에 JWT refresh token 추가 (RM-342)"
|
||
↓
|
||
[개발자] Claude Code에 작업 지시
|
||
"RM-342 이슈를 Redmine에서 읽고 구현 시작해줘"
|
||
→ Claude: 이슈 로드, Gitea 브랜치 생성, 구현 계획 제시
|
||
↓
|
||
[개발자] 코드 구현
|
||
"auth_service.py에 refresh token 로직 추가해줘. 기존 패턴 유지."
|
||
→ Claude: 코드 생성 + 단위 테스트 함께 생성
|
||
↓
|
||
[개발자] PR 생성
|
||
"현재 브랜치로 PR 만들어줘. Redmine RM-342 연결, 리뷰어 tech_lead 지정."
|
||
→ Claude: Gitea PR 생성 → Jenkins CI 자동 트리거
|
||
↓
|
||
[QA] 커버리지 검토
|
||
"RM-342 PR의 테스트 커버리지 확인하고, 추가 테스트 시나리오 제안해줘"
|
||
→ Claude: 커버리지 분석, 누락 케이스 제시
|
||
↓
|
||
[QA] 버그 발견 시
|
||
"refresh token 만료 후 재발급 시 500 에러 발생. Redmine 버그 이슈 만들어줘."
|
||
→ Claude: Redmine 버그 이슈 생성 (RM-343)
|
||
↓
|
||
[개발자] 버그 수정
|
||
"Jenkins 빌드 로그 분석해서 RM-343 원인 찾아줘"
|
||
↓
|
||
[PM] 완료 처리
|
||
"RM-342를 완료로 변경하고 Obsidian 스프린트 리포트에 추가해줘"
|
||
```
|
||
|
||
### 워크플로우 2: 일일 스탠드업 보조
|
||
```bash
|
||
claude -p "
|
||
Redmine에서 내(assigned_to=me) 이슈 중
|
||
어제 업데이트된 것과 오늘 마감인 것을 가져오고,
|
||
Jenkins에서 어제 실패한 빌드 목록을 가져와서
|
||
스탠드업용 요약을 만들어줘:
|
||
- 어제 한 일
|
||
- 오늘 할 일
|
||
- 블로커
|
||
"
|
||
```
|
||
|
||
### 워크플로우 3: 지식 축적 (Obsidian)
|
||
```bash
|
||
claude -p "
|
||
방금 JWT refresh token 구현을 완료했어.
|
||
핵심 결정사항과 트레이드오프를 Obsidian의
|
||
TIL/2026-03-01-jwt-refresh-implementation.md 에 정리해줘.
|
||
다음 개발자를 위한 '왜 이렇게 구현했는가' 포함.
|
||
"
|
||
```
|
||
|
||
---
|
||
|
||
## 팁 & 트러블슈팅
|
||
|
||
### 설정 팁
|
||
|
||
**팁 1: 환경변수 분리**
|
||
```bash
|
||
# 팀 공유 .env.example (Git 커밋)
|
||
REDMINE_URL=https://redmine.cloud-handson.com
|
||
REDMINE_API_KEY=
|
||
JENKINS_URL=https://jenkins.cloud-handson.com
|
||
|
||
# 개인 .env (Git 제외)
|
||
REDMINE_API_KEY=실제키값
|
||
```
|
||
|
||
**팁 2: MCP 서버 디버깅**
|
||
```bash
|
||
# MCP 연결 상태 확인
|
||
claude mcp list
|
||
|
||
# 특정 MCP 정보 확인
|
||
claude mcp get redmine
|
||
|
||
# 상세 로그로 실행
|
||
claude --verbose
|
||
```
|
||
|
||
**팁 3: 컨텍스트 윈도우 최적화**
|
||
|
||
MCP 서버가 많아지면 컨텍스트가 넘칠 수 있다.
|
||
```
|
||
MCP 사용 지침:
|
||
- Redmine 이슈 조회 시 필요한 필드만 요청 (전체 본문 X)
|
||
- Jenkins 로그는 최근 100줄만
|
||
- Gitea 파일 조회는 필요한 파일만
|
||
```
|
||
|
||
**팁 4: 역할별 Claude Code 세션 분리**
|
||
```bash
|
||
# 역할별 디렉터리에서 실행하면 다른 CLAUDE.md 적용 가능
|
||
/Users/joungmin/workspaces/
|
||
{프로젝트-frontend}/ # 프론트엔드용 CLAUDE.md
|
||
{프로젝트-backend}/ # 백엔드용 CLAUDE.md
|
||
```
|
||
|
||
**팁 5: Sub-agent 활용 (병렬 작업)**
|
||
```bash
|
||
claude -p "
|
||
다음 3가지를 동시에 처리해줘:
|
||
1. Redmine 이슈 #342 진행 중으로 변경
|
||
2. Gitea에 feature/RM-342 브랜치 생성
|
||
3. Obsidian Daily/2026-03-01.md에 작업 시작 기록
|
||
"
|
||
```
|
||
|
||
### 트러블슈팅
|
||
|
||
| 문제 | 원인 | 해결 |
|
||
|------|------|------|
|
||
| `claude: command not found` | PATH 미설정 | `export PATH="$(npm config get prefix)/bin:$PATH"` |
|
||
| MCP 서버 연결 실패 | 환경변수 미설정 | `.env` 확인, `source .env` |
|
||
| 컨텍스트 초과 오류 | MCP 데이터 과다 | 조회 필드/범위 제한 |
|
||
| Redmine 인증 실패 | API Key 만료 | Redmine에서 키 재발급 |
|
||
| Jenkins 403 | CSRF 설정 | Crumb 토큰 추가 필요 |
|
||
| Gitea SSL 오류 | 자체 서명 인증서 | `PYTHONHTTPSVERIFY=0` 또는 cert 등록 |
|
||
|
||
### Jenkins CSRF (Crumb) 처리
|
||
```python
|
||
def get_crumb():
|
||
r = requests.get(f"{JENKINS_URL}/crumbIssuer/api/json", headers=auth())
|
||
data = r.json()
|
||
return {data["crumbRequestField"]: data["crumb"]}
|
||
|
||
# POST 요청 시 crumb 헤더 추가
|
||
headers = {**auth(), **get_crumb()}
|
||
requests.post(url, headers=headers, ...)
|
||
```
|
||
|
||
---
|
||
|
||
## 금기 사항 (AI 포함 모든 기여자 준수)
|
||
|
||
- `main` 브랜치 직접 푸시 **절대 금지**
|
||
- API Key, 비밀번호 등 시크릿 하드코딩 **절대 금지**
|
||
- `TODO` 주석은 반드시 Redmine 이슈 번호와 함께 작성 (`# TODO(#123): 설명`)
|
||
- 테스트 없이 핵심 비즈니스 로직 변경 금지
|
||
- `print()` 디버그 코드를 프로덕션 코드에 남기지 말 것 (logger 사용)
|
||
|
||
---
|
||
|
||
## 주요 명령어
|
||
|
||
```bash
|
||
# 개발 서버 시작 (backend + frontend 동시 실행)
|
||
make dev
|
||
|
||
# 이슈 기반 브랜치 자동 생성
|
||
make start-issue # Redmine 이슈 번호 + 브랜치 설명 입력 → 브랜치 생성
|
||
|
||
# PR 전 체크 (lint + test)
|
||
make pr-ready
|
||
|
||
# 테스트 실행
|
||
make test
|
||
|
||
# 특정 테스트만 실행
|
||
pytest tests/unit/ -v
|
||
|
||
# 린트 검사 / 자동 수정
|
||
make lint
|
||
make lint-fix
|
||
|
||
# DB 마이그레이션 생성 / 적용
|
||
alembic revision --autogenerate -m "description"
|
||
alembic upgrade head
|
||
```
|
||
|
||
### Makefile
|
||
```makefile
|
||
.PHONY: dev test lint lint-fix pr-ready start-issue draft-pr
|
||
|
||
start-issue:
|
||
@read -p "프로젝트명 (/Users/joungmin/workspaces/ 내): " PROJ; \
|
||
read -p "Redmine 이슈 번호: " RM_NUM; \
|
||
read -p "브랜치 설명 (영어 kebab-case): " DESC; \
|
||
cd /Users/joungmin/workspaces/$$PROJ; \
|
||
git checkout develop; \
|
||
git pull origin develop; \
|
||
git checkout -b "feature/RM-$$RM_NUM-$$DESC"
|
||
|
||
pr-ready:
|
||
make lint
|
||
make test
|
||
@echo "✅ 린트 & 테스트 완료. PR 생성 준비됨."
|
||
|
||
draft-pr:
|
||
claude -p "현재 브랜치의 git diff를 분석해서 PR 본문 초안을 한국어로 작성해줘. Conventional Commit 형식 준수."
|
||
```
|
||
|
||
---
|
||
|
||
## 참조 문서
|
||
|
||
| 문서 | 경로 | 내용 |
|
||
|------|------|------|
|
||
| 디자인 패턴 가이드 | [`SOFTWARE_GUIDE.md`](./SOFTWARE_GUIDE.md) | 생성·구조·행위 패턴 정의, 빠른 선택 가이드 포함 |
|
||
|
||
> 새 모듈·클래스 설계 시 `SOFTWARE_GUIDE.md`의 **빠른 선택 가이드**를 먼저 확인하세요.
|
||
|
||
---
|
||
|
||
## Claude Code 활용 극대화 전략
|
||
|
||
> Claude Code를 단순 질문 도구가 아니라 **여러 명의 유능한 직원**처럼 구조화하여 운용하는 방법입니다.
|
||
|
||
### 1. 병렬 멀티 세션 운용
|
||
|
||
터미널 창을 여러 개 띄워 각기 다른 도메인을 동시에 처리합니다.
|
||
|
||
```
|
||
터미널 1: feature/RM-342 구현 (auth 도메인)
|
||
터미널 2: feature/RM-338 버그 수정 (payment 도메인)
|
||
터미널 3: 문서 작성 / Obsidian 정리
|
||
터미널 4: 테스트 커버리지 보완
|
||
터미널 5: 코드 리뷰 초안 생성
|
||
```
|
||
|
||
완료 알림을 설정하면 화면을 계속 볼 필요 없이 다른 업무에 집중할 수 있습니다.
|
||
|
||
```bash
|
||
# macOS 완료 알림 (CLAUDE.md 또는 ~/.zshrc에 추가)
|
||
# Claude Code 작업 끝날 때 소리 알림
|
||
alias claude-notify='claude "$@" && afplay /System/Library/Sounds/Glass.aiff'
|
||
```
|
||
|
||
### 2. Plan Mode 우선 원칙
|
||
|
||
코드를 바로 짜게 하지 말고, **먼저 계획을 세우고 검토**한 뒤 구현합니다.
|
||
|
||
```bash
|
||
# Step 1: 계획 수립 (Plan Mode)
|
||
"RM-342 이슈를 읽고 구현 계획만 세워줘. 코드는 아직 작성하지 마."
|
||
|
||
# Step 2: 계획 비판적 검토 (다른 세션 또는 이어서)
|
||
"방금 세운 계획의 문제점과 리스크를 비판적으로 검토해줘.
|
||
보안 취약점, 엣지 케이스, 성능 이슈 중심으로."
|
||
|
||
# Step 3: 검토 결과 반영 후 구현
|
||
"검토 결과를 반영해서 이제 구현해줘."
|
||
```
|
||
|
||
### 3. 자기 검증 (Self-Verification)
|
||
|
||
작업 완료 후 Claude가 **직접 결과를 실행하거나 확인**하도록 지시합니다.
|
||
이 단계를 거치면 결과물 품질이 2~3배 향상됩니다.
|
||
|
||
```bash
|
||
# 구현 후 자기 검증 요청
|
||
"구현이 끝나면 직접 테스트를 실행하고 통과 여부를 확인해줘."
|
||
"API 엔드포인트를 만들었으면 curl로 직접 호출해서 응답을 확인해줘."
|
||
"UI를 수정했으면 브라우저에서 직접 열어서 렌더링을 확인해줘."
|
||
```
|
||
|
||
### 4. 복리 학습 메모장 운영
|
||
|
||
실수가 발생하면 즉시 이 파일(CLAUDE.md)을 업데이트합니다.
|
||
같은 실수가 반복되지 않도록 **누적 학습** 구조를 만듭니다.
|
||
|
||
```bash
|
||
# 실수 발생 시 즉시 기록
|
||
"방금 발생한 실수를 CLAUDE.md의 '자주 하는 실수' 항목에 추가해줘."
|
||
```
|
||
|
||
**자주 하는 실수 목록** ← 실수 발생 시 여기에 추가
|
||
- (발생 시 항목 추가)
|
||
|
||
### 5. SDD (Specification Driven Development)
|
||
|
||
코드 작성 전 **설계서를 먼저 작성**합니다. 명확한 기준이 있으면 수십 번의 수정을 방지합니다.
|
||
|
||
```bash
|
||
# 구현 전 설계서 작성
|
||
"RM-342 이슈를 바탕으로 구현 전에 설계서를 먼저 작성해줘.
|
||
포함 항목: API 명세, 데이터 모델, 엣지 케이스, 수락 기준.
|
||
Obsidian Requirements/RM-342-spec.md에 저장해줘."
|
||
|
||
# 설계서 기반 구현
|
||
"Obsidian Requirements/RM-342-spec.md의 설계서를 읽고 구현해줘."
|
||
```
|
||
|
||
### 6. 세션 인수인계 (컨텍스트 이어받기)
|
||
|
||
새 세션을 시작하면 이전 대화를 잊기 때문에, **진행 상황을 요약 파일로 저장**합니다.
|
||
|
||
```bash
|
||
# 세션 종료 전 저장
|
||
"지금까지 작업한 내용, 결정사항, 미완료 항목을 요약해서
|
||
/Users/joungmin/workspaces/{프로젝트}/SESSION_HANDOFF.md에 저장해줘."
|
||
|
||
# 새 세션 시작 시
|
||
"SESSION_HANDOFF.md를 읽고 이전 작업을 이어서 진행해줘."
|
||
```
|
||
|
||
### 7. 도메인별 Claude 분리
|
||
|
||
큰 프로젝트는 **영역별로 별도 세션**을 운용하여 간섭과 혼선을 줄입니다.
|
||
|
||
```
|
||
/Users/joungmin/workspaces/{프로젝트}/
|
||
├── backend/auth/ → 터미널 1 전담 (인증/인가)
|
||
├── backend/payment/ → 터미널 2 전담 (결제)
|
||
├── backend/admin/ → 터미널 3 전담 (관리자)
|
||
└── frontend/ → 터미널 4 전담 (UI)
|
||
```
|
||
|
||
각 도메인 폴더에 별도 `CLAUDE.md`를 두면 도메인 특화 지침을 적용할 수 있습니다.
|
||
|
||
### 8. 단축 명령어 / 스킬 등록
|
||
|
||
자주 반복하는 작업 순서를 **명령어 하나**로 저장합니다.
|
||
|
||
```bash
|
||
# ~/.zshrc 또는 Makefile에 등록
|
||
alias cc-start='claude -p "SESSION_HANDOFF.md를 읽고 오늘 할 작업을 정리해줘"'
|
||
alias cc-end='claude -p "오늘 작업 내용을 SESSION_HANDOFF.md에 업데이트해줘"'
|
||
alias cc-review='claude -p "현재 브랜치 변경사항을 보안·성능·컨벤션 관점으로 리뷰해줘"'
|
||
alias cc-standup='claude -p "Redmine 내 이슈와 Jenkins 빌드 상태를 가져와서 스탠드업 요약을 만들어줘"'
|
||
```
|
||
|
||
---
|
||
|
||
## AI 작업 지침
|
||
|
||
> AI가 이 저장소에서 코드를 생성하거나 수정할 때 반드시 따라야 할 규칙입니다.
|
||
|
||
1. **기존 패턴 우선**: 새 코드 작성 전 인접 파일의 구조와 패턴을 파악하고 일관성 유지
|
||
2. **최소 변경 원칙**: 요청된 변경 범위를 벗어나는 수정은 하지 말 것
|
||
3. **테스트 동반 작성**: 새 함수/로직 작성 시 대응하는 단위 테스트 함께 제안
|
||
4. **불확실 시 질문**: 요구사항이 모호하면 임의로 결정하지 말고 반드시 확인 요청
|
||
5. **보안 우선**: 인증/인가 로직은 임의로 우회하거나 단순화하지 말 것
|
||
6. **Plan Mode 우선**: 복잡한 작업은 계획 수립 → 비판적 검토 → 구현 순서로 진행
|
||
7. **자기 검증**: 구현 완료 후 직접 테스트 실행하여 결과 확인
|
||
8. **실수 기록**: 오류 발생 시 CLAUDE.md의 '자주 하는 실수 목록' 즉시 업데이트
|
||
|
||
---
|
||
|
||
## 팀 연락처
|
||
|
||
| 역할 | 담당자 |
|
||
|------|--------|
|
||
| PM / Tech Lead | JM |
|