Compare commits
No commits in common. "b9c0b70e0602ee73269c27ed5c08917964c6c9cf" and "12258aa0754f307869b5d6855a46f037b460e2a3" have entirely different histories.
b9c0b70e06
...
12258aa075
@ -1,69 +0,0 @@
|
|||||||
# TypeScript/React 코드 스타일 규칙
|
|
||||||
|
|
||||||
## TypeScript 일반
|
|
||||||
- strict 모드 필수 (`tsconfig.json`)
|
|
||||||
- `any` 사용 금지 (불가피한 경우 주석으로 사유 명시)
|
|
||||||
- 타입 정의: `interface` 우선 (type은 유니온/인터섹션에만)
|
|
||||||
- 들여쓰기: 2 spaces
|
|
||||||
- 세미콜론: 사용
|
|
||||||
- 따옴표: single quote
|
|
||||||
- trailing comma: 사용
|
|
||||||
|
|
||||||
## React 규칙
|
|
||||||
|
|
||||||
### 컴포넌트
|
|
||||||
- 함수형 컴포넌트 + hooks 패턴만 사용
|
|
||||||
- 클래스 컴포넌트 사용 금지
|
|
||||||
- 컴포넌트 파일 당 하나의 export default 컴포넌트
|
|
||||||
- Props 타입은 interface로 정의 (ComponentNameProps)
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
interface UserCardProps {
|
|
||||||
name: string;
|
|
||||||
email: string;
|
|
||||||
onEdit?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const UserCard = ({ name, email, onEdit }: UserCardProps) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h3>{name}</h3>
|
|
||||||
<p>{email}</p>
|
|
||||||
{onEdit && <button onClick={onEdit}>편집</button>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default UserCard;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Hooks
|
|
||||||
- 커스텀 훅은 `use` 접두사 (예: `useAuth`, `useFetch`)
|
|
||||||
- 훅은 `src/hooks/` 디렉토리에 분리
|
|
||||||
- 복잡한 상태 로직은 커스텀 훅으로 추출
|
|
||||||
|
|
||||||
### 상태 관리
|
|
||||||
- 컴포넌트 로컬 상태: `useState`
|
|
||||||
- 공유 상태: Context API 또는 Zustand
|
|
||||||
- 서버 상태: React Query (TanStack Query) 권장
|
|
||||||
|
|
||||||
### 이벤트 핸들러
|
|
||||||
- `handle` 접두사: `handleClick`, `handleSubmit`
|
|
||||||
- Props로 전달 시 `on` 접두사: `onClick`, `onSubmit`
|
|
||||||
|
|
||||||
## 스타일링
|
|
||||||
- CSS Modules 또는 Tailwind CSS (프로젝트 설정에 따름)
|
|
||||||
- 인라인 스타일 지양
|
|
||||||
- !important 사용 금지
|
|
||||||
|
|
||||||
## API 호출
|
|
||||||
- API 호출 로직은 `src/services/`에 분리
|
|
||||||
- Axios 또는 fetch wrapper 사용
|
|
||||||
- 에러 처리: try-catch + 사용자 친화적 에러 메시지
|
|
||||||
- 환경별 API URL은 `.env`에서 관리
|
|
||||||
|
|
||||||
## 기타
|
|
||||||
- console.log 커밋 금지 (디버깅 후 제거)
|
|
||||||
- 매직 넘버/문자열 → 상수 파일로 추출
|
|
||||||
- 사용하지 않는 import, 변수 제거 (ESLint로 검증)
|
|
||||||
- 이미지/아이콘은 `src/assets/`에 관리
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
# Git 워크플로우 규칙
|
|
||||||
|
|
||||||
## 브랜치 전략
|
|
||||||
|
|
||||||
### 브랜치 구조
|
|
||||||
```
|
|
||||||
main ← 배포 가능한 안정 브랜치 (보호됨)
|
|
||||||
└── develop ← 개발 통합 브랜치
|
|
||||||
├── feature/ISSUE-123-기능설명
|
|
||||||
├── bugfix/ISSUE-456-버그설명
|
|
||||||
└── hotfix/ISSUE-789-긴급수정
|
|
||||||
```
|
|
||||||
|
|
||||||
### 브랜치 네이밍
|
|
||||||
- feature 브랜치: `feature/ISSUE-번호-간단설명` (예: `feature/ISSUE-42-user-login`)
|
|
||||||
- bugfix 브랜치: `bugfix/ISSUE-번호-간단설명`
|
|
||||||
- hotfix 브랜치: `hotfix/ISSUE-번호-간단설명`
|
|
||||||
- 이슈 번호가 없는 경우: `feature/간단설명` (예: `feature/add-swagger-docs`)
|
|
||||||
|
|
||||||
### 브랜치 규칙
|
|
||||||
- main, develop 브랜치에 직접 커밋/푸시 금지
|
|
||||||
- feature 브랜치는 develop에서 분기
|
|
||||||
- hotfix 브랜치는 main에서 분기
|
|
||||||
- 머지는 반드시 MR(Merge Request)을 통해 수행
|
|
||||||
|
|
||||||
## 커밋 메시지 규칙
|
|
||||||
|
|
||||||
### Conventional Commits 형식
|
|
||||||
```
|
|
||||||
type(scope): subject
|
|
||||||
|
|
||||||
body (선택)
|
|
||||||
|
|
||||||
footer (선택)
|
|
||||||
```
|
|
||||||
|
|
||||||
### type (필수)
|
|
||||||
| type | 설명 |
|
|
||||||
|------|------|
|
|
||||||
| feat | 새로운 기능 추가 |
|
|
||||||
| fix | 버그 수정 |
|
|
||||||
| docs | 문서 변경 |
|
|
||||||
| style | 코드 포맷팅 (기능 변경 없음) |
|
|
||||||
| refactor | 리팩토링 (기능 변경 없음) |
|
|
||||||
| test | 테스트 추가/수정 |
|
|
||||||
| chore | 빌드, 설정 변경 |
|
|
||||||
| ci | CI/CD 설정 변경 |
|
|
||||||
| perf | 성능 개선 |
|
|
||||||
|
|
||||||
### scope (선택)
|
|
||||||
- 변경 범위를 나타내는 짧은 단어
|
|
||||||
- 한국어, 영어 모두 허용 (예: `feat(인증): 로그인 기능`, `fix(auth): token refresh`)
|
|
||||||
|
|
||||||
### subject (필수)
|
|
||||||
- 변경 내용을 간결하게 설명
|
|
||||||
- 한국어, 영어 모두 허용
|
|
||||||
- 72자 이내
|
|
||||||
- 마침표(.) 없이 끝냄
|
|
||||||
|
|
||||||
### 예시
|
|
||||||
```
|
|
||||||
feat(auth): JWT 기반 로그인 구현
|
|
||||||
fix(배치): 야간 배치 타임아웃 수정
|
|
||||||
docs: README에 빌드 방법 추가
|
|
||||||
refactor(user-service): 중복 로직 추출
|
|
||||||
test(결제): 환불 로직 단위 테스트 추가
|
|
||||||
chore: Gradle 의존성 버전 업데이트
|
|
||||||
```
|
|
||||||
|
|
||||||
## MR(Merge Request) 규칙
|
|
||||||
|
|
||||||
### MR 생성
|
|
||||||
- 제목: 커밋 메시지와 동일한 Conventional Commits 형식
|
|
||||||
- 본문: 변경 내용 요약, 테스트 방법, 관련 이슈 번호
|
|
||||||
- 라벨: 적절한 라벨 부착 (feature, bugfix, hotfix 등)
|
|
||||||
|
|
||||||
### MR 리뷰
|
|
||||||
- 최소 1명의 리뷰어 승인 필수
|
|
||||||
- CI 검증 통과 필수 (설정된 경우)
|
|
||||||
- 리뷰 코멘트 모두 해결 후 머지
|
|
||||||
|
|
||||||
### MR 머지
|
|
||||||
- Squash Merge 권장 (깔끔한 히스토리)
|
|
||||||
- 머지 후 소스 브랜치 삭제
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
# TypeScript/React 네이밍 규칙
|
|
||||||
|
|
||||||
## 파일명
|
|
||||||
|
|
||||||
| 항목 | 규칙 | 예시 |
|
|
||||||
|------|------|------|
|
|
||||||
| 컴포넌트 | PascalCase | `UserCard.tsx`, `LoginForm.tsx` |
|
|
||||||
| 페이지 | PascalCase | `Dashboard.tsx`, `UserList.tsx` |
|
|
||||||
| 훅 | camelCase + use 접두사 | `useAuth.ts`, `useFetch.ts` |
|
|
||||||
| 서비스 | camelCase | `userService.ts`, `authApi.ts` |
|
|
||||||
| 유틸리티 | camelCase | `formatDate.ts`, `validation.ts` |
|
|
||||||
| 타입 정의 | camelCase | `user.types.ts`, `api.types.ts` |
|
|
||||||
| 상수 | camelCase | `routes.ts`, `constants.ts` |
|
|
||||||
| 스타일 | 컴포넌트명 + .module | `UserCard.module.css` |
|
|
||||||
| 테스트 | 대상 + .test | `UserCard.test.tsx` |
|
|
||||||
|
|
||||||
## 변수/함수
|
|
||||||
|
|
||||||
| 항목 | 규칙 | 예시 |
|
|
||||||
|------|------|------|
|
|
||||||
| 변수 | camelCase | `userName`, `isLoading` |
|
|
||||||
| 함수 | camelCase | `getUserList`, `formatDate` |
|
|
||||||
| 상수 | UPPER_SNAKE_CASE | `MAX_RETRY`, `API_BASE_URL` |
|
|
||||||
| boolean 변수 | is/has/can/should 접두사 | `isActive`, `hasPermission` |
|
|
||||||
| 이벤트 핸들러 | handle 접두사 | `handleClick`, `handleSubmit` |
|
|
||||||
| 이벤트 Props | on 접두사 | `onClick`, `onSubmit` |
|
|
||||||
|
|
||||||
## 타입/인터페이스
|
|
||||||
|
|
||||||
| 항목 | 규칙 | 예시 |
|
|
||||||
|------|------|------|
|
|
||||||
| interface | PascalCase | `UserProfile`, `ApiResponse` |
|
|
||||||
| Props | 컴포넌트명 + Props | `UserCardProps`, `ButtonProps` |
|
|
||||||
| 응답 타입 | 도메인 + Response | `UserResponse`, `LoginResponse` |
|
|
||||||
| 요청 타입 | 동작 + Request | `CreateUserRequest` |
|
|
||||||
| Enum | PascalCase | `UserStatus`, `HttpMethod` |
|
|
||||||
| Enum 값 | UPPER_SNAKE_CASE | `ACTIVE`, `PENDING` |
|
|
||||||
| Generic | 단일 대문자 | `T`, `K`, `V` |
|
|
||||||
|
|
||||||
## 디렉토리
|
|
||||||
|
|
||||||
- 모두 kebab-case 또는 camelCase (프로젝트 통일)
|
|
||||||
- 예: `src/components/common/`, `src/hooks/`, `src/services/`
|
|
||||||
|
|
||||||
## 컴포넌트 구조 예시
|
|
||||||
|
|
||||||
```
|
|
||||||
src/components/user-card/
|
|
||||||
├── UserCard.tsx # 컴포넌트
|
|
||||||
├── UserCard.module.css # 스타일
|
|
||||||
├── UserCard.test.tsx # 테스트
|
|
||||||
└── index.ts # re-export
|
|
||||||
```
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
# 팀 정책 (Team Policy)
|
|
||||||
|
|
||||||
이 규칙은 조직 전체에 적용되는 필수 정책입니다.
|
|
||||||
프로젝트별 `.claude/rules/`에 추가 규칙을 정의할 수 있으나, 이 정책을 위반할 수 없습니다.
|
|
||||||
|
|
||||||
## 보안 정책
|
|
||||||
|
|
||||||
### 금지 행위
|
|
||||||
- `.env`, `.env.*`, `secrets/` 파일 읽기 및 내용 출력 금지
|
|
||||||
- 비밀번호, API 키, 토큰 등 민감 정보를 코드에 하드코딩 금지
|
|
||||||
- `git push --force`, `git reset --hard`, `git clean -fd` 실행 금지
|
|
||||||
- `rm -rf /`, `rm -rf ~`, `rm -rf .git` 등 파괴적 명령 실행 금지
|
|
||||||
- main/develop 브랜치에 직접 push 금지 (MR을 통해서만 머지)
|
|
||||||
|
|
||||||
### 인증 정보 관리
|
|
||||||
- 환경변수 또는 외부 설정 파일(`.env`, `application-local.yml`)로 관리
|
|
||||||
- 설정 파일은 `.gitignore`에 반드시 포함
|
|
||||||
- 예시 파일(`.env.example`, `application.yml.example`)만 커밋
|
|
||||||
|
|
||||||
## 코드 품질 정책
|
|
||||||
|
|
||||||
### 필수 검증
|
|
||||||
- 커밋 전 빌드(컴파일) 성공 확인
|
|
||||||
- 린트 경고 0개 유지 (CI에서도 검증)
|
|
||||||
- 테스트 코드가 있는 프로젝트는 테스트 통과 필수
|
|
||||||
|
|
||||||
### 코드 리뷰
|
|
||||||
- main 브랜치 머지 시 최소 1명 리뷰 필수
|
|
||||||
- 리뷰어 승인 없이 머지 불가
|
|
||||||
|
|
||||||
## 문서화 정책
|
|
||||||
- 공개 API(controller endpoint)에는 반드시 설명 주석 작성
|
|
||||||
- 복잡한 비즈니스 로직에는 의도를 설명하는 주석 작성
|
|
||||||
- README.md에 프로젝트 빌드/실행 방법 유지
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
# TypeScript/React 테스트 규칙
|
|
||||||
|
|
||||||
## 테스트 프레임워크
|
|
||||||
- Vitest (Vite 프로젝트) 또는 Jest
|
|
||||||
- React Testing Library (컴포넌트 테스트)
|
|
||||||
- MSW (Mock Service Worker, API 모킹)
|
|
||||||
|
|
||||||
## 테스트 구조
|
|
||||||
|
|
||||||
### 단위 테스트
|
|
||||||
- 유틸리티 함수, 커스텀 훅 테스트
|
|
||||||
- 외부 의존성 없이 순수 로직 검증
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
describe('formatDate', () => {
|
|
||||||
it('날짜를 YYYY-MM-DD 형식으로 변환한다', () => {
|
|
||||||
const result = formatDate(new Date('2026-02-14'));
|
|
||||||
expect(result).toBe('2026-02-14');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('유효하지 않은 날짜는 빈 문자열을 반환한다', () => {
|
|
||||||
const result = formatDate(new Date('invalid'));
|
|
||||||
expect(result).toBe('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 컴포넌트 테스트
|
|
||||||
- React Testing Library 사용
|
|
||||||
- 사용자 관점에서 테스트 (구현 세부사항이 아닌 동작 테스트)
|
|
||||||
- `getByRole`, `getByText` 등 접근성 기반 쿼리 우선
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
describe('UserCard', () => {
|
|
||||||
it('사용자 이름과 이메일을 표시한다', () => {
|
|
||||||
render(<UserCard name="홍길동" email="hong@test.com" />);
|
|
||||||
expect(screen.getByText('홍길동')).toBeInTheDocument();
|
|
||||||
expect(screen.getByText('hong@test.com')).toBeInTheDocument();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('편집 버튼 클릭 시 onEdit 콜백을 호출한다', async () => {
|
|
||||||
const onEdit = vi.fn();
|
|
||||||
render(<UserCard name="홍길동" email="hong@test.com" onEdit={onEdit} />);
|
|
||||||
await userEvent.click(screen.getByRole('button', { name: '편집' }));
|
|
||||||
expect(onEdit).toHaveBeenCalledOnce();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### 테스트 패턴
|
|
||||||
- **Arrange-Act-Assert** 구조
|
|
||||||
- 테스트 설명은 한국어로 작성 (`it('사용자 이름을 표시한다')`)
|
|
||||||
- 하나의 테스트에 하나의 검증
|
|
||||||
|
|
||||||
## 테스트 커버리지
|
|
||||||
- 새로 작성하는 유틸리티 함수: 테스트 필수
|
|
||||||
- 컴포넌트: 주요 상호작용 테스트 권장
|
|
||||||
- API 호출: MSW로 모킹하여 에러/성공 시나리오 테스트
|
|
||||||
|
|
||||||
## 금지 사항
|
|
||||||
- 구현 세부사항 테스트 금지 (state 값 직접 확인 등)
|
|
||||||
- `getByTestId` 남용 금지 (접근성 쿼리 우선)
|
|
||||||
- 스냅샷 테스트 남용 금지 (변경에 취약)
|
|
||||||
- `setTimeout`으로 비동기 대기 금지 → `waitFor`, `findBy` 사용
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
||||||
"permissions": {
|
|
||||||
"allow": [
|
|
||||||
"Bash(yarn *)",
|
|
||||||
"Bash(npm *)",
|
|
||||||
"Bash(npx *)",
|
|
||||||
"Bash(node *)",
|
|
||||||
"Bash(git status)",
|
|
||||||
"Bash(git diff*)",
|
|
||||||
"Bash(git log*)",
|
|
||||||
"Bash(git branch*)",
|
|
||||||
"Bash(git checkout*)",
|
|
||||||
"Bash(git add*)",
|
|
||||||
"Bash(git commit*)",
|
|
||||||
"Bash(git pull*)",
|
|
||||||
"Bash(git fetch*)",
|
|
||||||
"Bash(git merge*)",
|
|
||||||
"Bash(git stash*)",
|
|
||||||
"Bash(git remote*)",
|
|
||||||
"Bash(git config*)",
|
|
||||||
"Bash(git rev-parse*)",
|
|
||||||
"Bash(git show*)",
|
|
||||||
"Bash(git tag*)",
|
|
||||||
"Bash(curl -s *)",
|
|
||||||
"Bash(fnm *)"
|
|
||||||
],
|
|
||||||
"deny": [
|
|
||||||
"Bash(git push --force*)",
|
|
||||||
"Bash(git reset --hard*)",
|
|
||||||
"Bash(git clean -fd*)",
|
|
||||||
"Bash(git checkout -- .)",
|
|
||||||
"Bash(rm -rf /)",
|
|
||||||
"Bash(rm -rf ~)",
|
|
||||||
"Bash(rm -rf .git*)",
|
|
||||||
"Bash(rm -rf /*)",
|
|
||||||
"Read(./**/.env*)",
|
|
||||||
"Read(./**/secrets/**)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hooks": {
|
|
||||||
"SessionStart": [
|
|
||||||
{
|
|
||||||
"matcher": "compact",
|
|
||||||
"hooks": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"command": "bash .claude/scripts/on-post-compact.sh",
|
|
||||||
"timeout": 10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PreCompact": [
|
|
||||||
{
|
|
||||||
"hooks": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"command": "bash .claude/scripts/on-pre-compact.sh",
|
|
||||||
"timeout": 30
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PostToolUse": [
|
|
||||||
{
|
|
||||||
"matcher": "Bash",
|
|
||||||
"hooks": [
|
|
||||||
{
|
|
||||||
"type": "command",
|
|
||||||
"command": "bash .claude/scripts/on-commit.sh",
|
|
||||||
"timeout": 15
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
---
|
|
||||||
name: create-mr
|
|
||||||
description: 현재 브랜치에서 Gitea MR(Merge Request)을 생성합니다
|
|
||||||
allowed-tools: "Bash, Read, Grep"
|
|
||||||
argument-hint: "[target-branch: develop|main] (기본: develop)"
|
|
||||||
---
|
|
||||||
|
|
||||||
현재 브랜치의 변경 사항을 기반으로 Gitea에 MR을 생성합니다.
|
|
||||||
타겟 브랜치: $ARGUMENTS (기본: develop)
|
|
||||||
|
|
||||||
## 수행 단계
|
|
||||||
|
|
||||||
### 1. 사전 검증
|
|
||||||
- 현재 브랜치가 main/develop이 아닌지 확인
|
|
||||||
- 커밋되지 않은 변경 사항 확인 (있으면 경고)
|
|
||||||
- 리모트에 현재 브랜치가 push되어 있는지 확인 (안 되어 있으면 push)
|
|
||||||
|
|
||||||
### 2. 변경 내역 분석
|
|
||||||
```bash
|
|
||||||
git log develop..HEAD --oneline
|
|
||||||
git diff develop..HEAD --stat
|
|
||||||
```
|
|
||||||
- 커밋 목록과 변경된 파일 목록 수집
|
|
||||||
- 주요 변경 사항 요약 작성
|
|
||||||
|
|
||||||
### 3. MR 정보 구성
|
|
||||||
- **제목**: 브랜치의 첫 커밋 메시지 또는 브랜치명에서 추출
|
|
||||||
- `feature/ISSUE-42-user-login` → `feat: ISSUE-42 user-login`
|
|
||||||
- **본문**:
|
|
||||||
```markdown
|
|
||||||
## 변경 사항
|
|
||||||
- (커밋 기반 자동 생성)
|
|
||||||
|
|
||||||
## 관련 이슈
|
|
||||||
- closes #이슈번호 (브랜치명에서 추출)
|
|
||||||
|
|
||||||
## 테스트
|
|
||||||
- [ ] 빌드 성공 확인
|
|
||||||
- [ ] 기존 테스트 통과
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Gitea API로 MR 생성
|
|
||||||
```bash
|
|
||||||
# Gitea remote URL에서 owner/repo 추출
|
|
||||||
REMOTE_URL=$(git remote get-url origin)
|
|
||||||
|
|
||||||
# Gitea API 호출
|
|
||||||
curl -X POST "GITEA_URL/api/v1/repos/{owner}/{repo}/pulls" \
|
|
||||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"title": "MR 제목",
|
|
||||||
"body": "MR 본문",
|
|
||||||
"head": "현재브랜치",
|
|
||||||
"base": "타겟브랜치"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 결과 출력
|
|
||||||
- MR URL 출력
|
|
||||||
- 리뷰어 지정 안내
|
|
||||||
- 다음 단계: 리뷰 대기 → 승인 → 머지
|
|
||||||
|
|
||||||
## 필요 환경변수
|
|
||||||
- `GITEA_TOKEN`: Gitea API 접근 토큰 (없으면 안내)
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
---
|
|
||||||
name: fix-issue
|
|
||||||
description: Gitea 이슈를 분석하고 수정 브랜치를 생성합니다
|
|
||||||
allowed-tools: "Bash, Read, Write, Edit, Glob, Grep"
|
|
||||||
argument-hint: "<issue-number>"
|
|
||||||
---
|
|
||||||
|
|
||||||
Gitea 이슈 #$ARGUMENTS 를 분석하고 수정 작업을 시작합니다.
|
|
||||||
|
|
||||||
## 수행 단계
|
|
||||||
|
|
||||||
### 1. 이슈 조회
|
|
||||||
```bash
|
|
||||||
curl -s "GITEA_URL/api/v1/repos/{owner}/{repo}/issues/$ARGUMENTS" \
|
|
||||||
-H "Authorization: token ${GITEA_TOKEN}"
|
|
||||||
```
|
|
||||||
- 이슈 제목, 본문, 라벨, 담당자 정보 확인
|
|
||||||
- 이슈 내용을 사용자에게 요약하여 보여줌
|
|
||||||
|
|
||||||
### 2. 브랜치 생성
|
|
||||||
이슈 라벨에 따라 브랜치 타입 결정:
|
|
||||||
- `bug` 라벨 → `bugfix/ISSUE-번호-설명`
|
|
||||||
- 그 외 → `feature/ISSUE-번호-설명`
|
|
||||||
- 긴급 → `hotfix/ISSUE-번호-설명`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git checkout develop
|
|
||||||
git pull origin develop
|
|
||||||
git checkout -b {type}/ISSUE-{number}-{slug}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 이슈 분석
|
|
||||||
이슈 내용을 바탕으로:
|
|
||||||
- 관련 파일 탐색 (Grep, Glob 활용)
|
|
||||||
- 영향 범위 파악
|
|
||||||
- 수정 방향 제안
|
|
||||||
|
|
||||||
### 4. 수정 계획 제시
|
|
||||||
사용자에게 수정 계획을 보여주고 승인을 받은 후 작업 진행:
|
|
||||||
- 수정할 파일 목록
|
|
||||||
- 변경 내용 요약
|
|
||||||
- 예상 영향
|
|
||||||
|
|
||||||
### 5. 작업 완료 후
|
|
||||||
- 변경 사항 요약
|
|
||||||
- `/create-mr` 실행 안내
|
|
||||||
|
|
||||||
## 필요 환경변수
|
|
||||||
- `GITEA_TOKEN`: Gitea API 접근 토큰
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
---
|
|
||||||
name: init-project
|
|
||||||
description: 팀 표준 워크플로우로 프로젝트를 초기화합니다
|
|
||||||
allowed-tools: "Bash, Read, Write, Edit, Glob, Grep"
|
|
||||||
argument-hint: "[project-type: java-maven|java-gradle|react-ts|auto]"
|
|
||||||
---
|
|
||||||
|
|
||||||
팀 표준 워크플로우에 따라 프로젝트를 초기화합니다.
|
|
||||||
프로젝트 타입: $ARGUMENTS (기본: auto — 자동 감지)
|
|
||||||
|
|
||||||
## 프로젝트 타입 자동 감지
|
|
||||||
|
|
||||||
$ARGUMENTS가 "auto"이거나 비어있으면 다음 순서로 감지:
|
|
||||||
1. `pom.xml` 존재 → **java-maven**
|
|
||||||
2. `build.gradle` 또는 `build.gradle.kts` 존재 → **java-gradle**
|
|
||||||
3. `package.json` + `tsconfig.json` 존재 → **react-ts**
|
|
||||||
4. 감지 실패 → 사용자에게 타입 선택 요청
|
|
||||||
|
|
||||||
## 수행 단계
|
|
||||||
|
|
||||||
### 1. 프로젝트 분석
|
|
||||||
- 빌드 파일, 설정 파일, 디렉토리 구조 파악
|
|
||||||
- 사용 중인 프레임워크, 라이브러리 감지
|
|
||||||
- 기존 `.claude/` 디렉토리 존재 여부 확인
|
|
||||||
|
|
||||||
### 2. CLAUDE.md 생성
|
|
||||||
프로젝트 루트에 CLAUDE.md를 생성하고 다음 내용 포함:
|
|
||||||
- 프로젝트 개요 (이름, 타입, 주요 기술 스택)
|
|
||||||
- 빌드/실행 명령어 (감지된 빌드 도구 기반)
|
|
||||||
- 테스트 실행 명령어
|
|
||||||
- 프로젝트 디렉토리 구조 요약
|
|
||||||
- 팀 컨벤션 참조 (`.claude/rules/` 안내)
|
|
||||||
|
|
||||||
### 3. .claude/ 디렉토리 구성
|
|
||||||
이미 팀 표준 파일이 존재하면 건너뜀. 없는 경우:
|
|
||||||
- `.claude/settings.json` — 프로젝트 타입별 표준 권한 설정
|
|
||||||
- `.claude/rules/` — 팀 규칙 파일 (team-policy, git-workflow, code-style, naming, testing)
|
|
||||||
- `.claude/skills/` — 팀 스킬 (create-mr, fix-issue, sync-team-workflow)
|
|
||||||
|
|
||||||
### 4. Git Hooks 설정
|
|
||||||
```bash
|
|
||||||
git config core.hooksPath .githooks
|
|
||||||
```
|
|
||||||
`.githooks/` 디렉토리에 실행 권한 부여:
|
|
||||||
```bash
|
|
||||||
chmod +x .githooks/*
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 프로젝트 타입별 추가 설정
|
|
||||||
|
|
||||||
#### java-maven
|
|
||||||
- `.sdkmanrc` 생성 (java=17.0.18-amzn 또는 프로젝트에 맞는 버전)
|
|
||||||
- `.mvn/settings.xml` Nexus 미러 설정 확인
|
|
||||||
- `mvn compile` 빌드 성공 확인
|
|
||||||
|
|
||||||
#### java-gradle
|
|
||||||
- `.sdkmanrc` 생성
|
|
||||||
- `gradle.properties.example` Nexus 설정 확인
|
|
||||||
- `./gradlew compileJava` 빌드 성공 확인
|
|
||||||
|
|
||||||
#### react-ts
|
|
||||||
- `.node-version` 생성 (프로젝트에 맞는 Node 버전)
|
|
||||||
- `.npmrc` Nexus 레지스트리 설정 확인
|
|
||||||
- `npm install && npm run build` 성공 확인
|
|
||||||
|
|
||||||
### 6. .gitignore 확인
|
|
||||||
다음 항목이 .gitignore에 포함되어 있는지 확인하고, 없으면 추가:
|
|
||||||
```
|
|
||||||
.claude/settings.local.json
|
|
||||||
.claude/CLAUDE.local.md
|
|
||||||
.env
|
|
||||||
.env.*
|
|
||||||
*.local
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7. workflow-version.json 생성
|
|
||||||
`.claude/workflow-version.json` 파일을 생성하여 현재 글로벌 워크플로우 버전 기록:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"applied_global_version": "1.0.0",
|
|
||||||
"applied_date": "현재날짜",
|
|
||||||
"project_type": "감지된타입"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8. 검증 및 요약
|
|
||||||
- 생성/수정된 파일 목록 출력
|
|
||||||
- `git config core.hooksPath` 확인
|
|
||||||
- 빌드 명령 실행 가능 확인
|
|
||||||
- 다음 단계 안내 (개발 시작, 첫 커밋 방법 등)
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
---
|
|
||||||
name: sync-team-workflow
|
|
||||||
description: 팀 글로벌 워크플로우를 현재 프로젝트에 동기화합니다
|
|
||||||
allowed-tools: "Bash, Read, Write, Edit, Glob, Grep"
|
|
||||||
---
|
|
||||||
|
|
||||||
팀 글로벌 워크플로우의 최신 버전을 현재 프로젝트에 적용합니다.
|
|
||||||
|
|
||||||
## 수행 절차
|
|
||||||
|
|
||||||
### 1. 글로벌 버전 조회
|
|
||||||
Gitea API로 template-common 리포의 workflow-version.json 조회:
|
|
||||||
```bash
|
|
||||||
GITEA_URL=$(python3 -c "import json; print(json.load(open('.claude/workflow-version.json')).get('gitea_url', 'http://211.208.115.83:3000'))" 2>/dev/null || echo "http://211.208.115.83:3000")
|
|
||||||
|
|
||||||
curl -sf "${GITEA_URL}/api/v1/repos/gcsc/template-common/raw/workflow-version.json"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 버전 비교
|
|
||||||
로컬 `.claude/workflow-version.json`과 비교:
|
|
||||||
- 버전 일치 → "최신 버전입니다" 안내 후 종료
|
|
||||||
- 버전 불일치 → 미적용 변경 항목 추출하여 표시
|
|
||||||
|
|
||||||
### 3. 프로젝트 타입 감지
|
|
||||||
자동 감지 순서:
|
|
||||||
1. `.claude/workflow-version.json`의 `project_type` 필드 확인
|
|
||||||
2. 없으면: `pom.xml` → java-maven, `build.gradle` → java-gradle, `package.json` → react-ts
|
|
||||||
|
|
||||||
### 4. 파일 다운로드 및 적용
|
|
||||||
Gitea API로 해당 타입 + common 템플릿 파일 다운로드:
|
|
||||||
|
|
||||||
#### 4-1. 규칙 파일 (덮어쓰기)
|
|
||||||
팀 규칙은 로컬 수정 불가 — 항상 글로벌 최신으로 교체:
|
|
||||||
```
|
|
||||||
.claude/rules/team-policy.md
|
|
||||||
.claude/rules/git-workflow.md
|
|
||||||
.claude/rules/code-style.md (타입별)
|
|
||||||
.claude/rules/naming.md (타입별)
|
|
||||||
.claude/rules/testing.md (타입별)
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4-2. settings.json (부분 갱신)
|
|
||||||
- `deny` 목록: 글로벌 최신으로 교체
|
|
||||||
- `allow` 목록: 기존 사용자 커스텀 유지 + 글로벌 기본값 병합
|
|
||||||
- `hooks`: 글로벌 최신으로 교체
|
|
||||||
|
|
||||||
#### 4-3. 스킬 파일 (덮어쓰기)
|
|
||||||
```
|
|
||||||
.claude/skills/create-mr/SKILL.md
|
|
||||||
.claude/skills/fix-issue/SKILL.md
|
|
||||||
.claude/skills/sync-team-workflow/SKILL.md
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4-4. Git Hooks (덮어쓰기 + 실행 권한)
|
|
||||||
```bash
|
|
||||||
chmod +x .githooks/*
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 로컬 버전 업데이트
|
|
||||||
`.claude/workflow-version.json` 갱신:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"applied_global_version": "새버전",
|
|
||||||
"applied_date": "오늘날짜",
|
|
||||||
"project_type": "감지된타입"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. 변경 보고
|
|
||||||
- `git diff`로 변경 내역 확인
|
|
||||||
- 업데이트된 파일 목록 출력
|
|
||||||
- 변경 로그(글로벌 workflow-version.json의 changes) 표시
|
|
||||||
- 필요한 추가 조치 안내 (빌드 확인, 의존성 업데이트 등)
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{"applied_global_version": "1.2.0"}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
||||||
[*.{java,kt}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.{js,jsx,ts,tsx,json,yml,yaml,css,scss,html}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
[*.{sh,bash}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[Makefile]
|
|
||||||
indent_style = tab
|
|
||||||
|
|
||||||
[*.{gradle,groovy}]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.xml]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
||||||
16
.env
16
.env
@ -1,16 +0,0 @@
|
|||||||
# ============================================
|
|
||||||
# 프로덕션 환경 (Production)
|
|
||||||
# - 빌드: yarn build:prod (또는 yarn build)
|
|
||||||
# ============================================
|
|
||||||
|
|
||||||
# 배포 경로
|
|
||||||
VITE_BASE_URL=/
|
|
||||||
|
|
||||||
# API 서버 (SNP-Batch API)
|
|
||||||
VITE_API_URL=http://211.208.115.83:8041/snp-api
|
|
||||||
|
|
||||||
# 선박 데이터 쓰로틀링 (ms, 0=무제한)
|
|
||||||
VITE_SHIP_THROTTLE=0
|
|
||||||
|
|
||||||
# 인증 우회 (민간 데모)
|
|
||||||
VITE_DEV_SKIP_AUTH=true
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
# ============================================
|
|
||||||
# 로컬 개발 환경 (Local Development)
|
|
||||||
# - 서버: yarn dev
|
|
||||||
# ============================================
|
|
||||||
|
|
||||||
# 배포 경로
|
|
||||||
VITE_BASE_URL=/
|
|
||||||
|
|
||||||
# API 서버 (SNP-Batch API)
|
|
||||||
VITE_API_URL=http://211.208.115.83:8041/snp-api
|
|
||||||
|
|
||||||
# 선박 데이터 쓰로틀링 (ms, 0=무제한)
|
|
||||||
VITE_SHIP_THROTTLE=0
|
|
||||||
|
|
||||||
# 인증 우회 (민간 데모)
|
|
||||||
VITE_DEV_SKIP_AUTH=true
|
|
||||||
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,3 +0,0 @@
|
|||||||
# 오프라인 캐시 바이너리 보호 (Windows autocrlf 변환 방지)
|
|
||||||
*.tgz binary
|
|
||||||
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#==============================================================================
|
|
||||||
# commit-msg hook
|
|
||||||
# Conventional Commits 형식 검증 (한/영 혼용 지원)
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
COMMIT_MSG_FILE="$1"
|
|
||||||
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
|
|
||||||
|
|
||||||
# Merge 커밋은 검증 건너뜀
|
|
||||||
if echo "$COMMIT_MSG" | head -1 | grep -qE "^Merge "; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Revert 커밋은 검증 건너뜀
|
|
||||||
if echo "$COMMIT_MSG" | head -1 | grep -qE "^Revert "; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Conventional Commits 정규식
|
|
||||||
# type(scope): subject
|
|
||||||
# - type: feat|fix|docs|style|refactor|test|chore|ci|perf (필수)
|
|
||||||
# - scope: 영문, 숫자, 한글, 점, 밑줄, 하이픈 허용 (선택)
|
|
||||||
# - subject: 1~72자, 한/영 혼용 허용 (필수)
|
|
||||||
PATTERN='^(feat|fix|docs|style|refactor|test|chore|ci|perf)(\([a-zA-Z0-9가-힣._-]+\))?: .{1,72}$'
|
|
||||||
|
|
||||||
FIRST_LINE=$(head -1 "$COMMIT_MSG_FILE")
|
|
||||||
|
|
||||||
if ! echo "$FIRST_LINE" | grep -qE "$PATTERN"; then
|
|
||||||
echo ""
|
|
||||||
echo "╔══════════════════════════════════════════════════════════════╗"
|
|
||||||
echo "║ 커밋 메시지가 Conventional Commits 형식에 맞지 않습니다 ║"
|
|
||||||
echo "╚══════════════════════════════════════════════════════════════╝"
|
|
||||||
echo ""
|
|
||||||
echo " 올바른 형식: type(scope): subject"
|
|
||||||
echo ""
|
|
||||||
echo " type (필수):"
|
|
||||||
echo " feat — 새로운 기능"
|
|
||||||
echo " fix — 버그 수정"
|
|
||||||
echo " docs — 문서 변경"
|
|
||||||
echo " style — 코드 포맷팅"
|
|
||||||
echo " refactor — 리팩토링"
|
|
||||||
echo " test — 테스트"
|
|
||||||
echo " chore — 빌드/설정 변경"
|
|
||||||
echo " ci — CI/CD 변경"
|
|
||||||
echo " perf — 성능 개선"
|
|
||||||
echo ""
|
|
||||||
echo " scope (선택): 한/영 모두 가능"
|
|
||||||
echo " subject (필수): 1~72자, 한/영 모두 가능"
|
|
||||||
echo ""
|
|
||||||
echo " 예시:"
|
|
||||||
echo " feat(auth): JWT 기반 로그인 구현"
|
|
||||||
echo " fix(배치): 야간 배치 타임아웃 수정"
|
|
||||||
echo " docs: README 업데이트"
|
|
||||||
echo " chore: Gradle 의존성 업데이트"
|
|
||||||
echo ""
|
|
||||||
echo " 현재 메시지: $FIRST_LINE"
|
|
||||||
echo ""
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#==============================================================================
|
|
||||||
# post-checkout hook
|
|
||||||
# 브랜치 체크아웃 시 core.hooksPath 자동 설정
|
|
||||||
# clone/checkout 후 .githooks 디렉토리가 있으면 자동으로 hooksPath 설정
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
# post-checkout 파라미터: prev_HEAD, new_HEAD, branch_flag
|
|
||||||
# branch_flag=1: 브랜치 체크아웃, 0: 파일 체크아웃
|
|
||||||
BRANCH_FLAG="$3"
|
|
||||||
|
|
||||||
# 파일 체크아웃은 건너뜀
|
|
||||||
if [ "$BRANCH_FLAG" = "0" ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# .githooks 디렉토리 존재 확인
|
|
||||||
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
||||||
if [ -d "${REPO_ROOT}/.githooks" ]; then
|
|
||||||
CURRENT_HOOKS_PATH=$(git config core.hooksPath 2>/dev/null || echo "")
|
|
||||||
if [ "$CURRENT_HOOKS_PATH" != ".githooks" ]; then
|
|
||||||
git config core.hooksPath .githooks
|
|
||||||
chmod +x "${REPO_ROOT}/.githooks/"* 2>/dev/null
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#==============================================================================
|
|
||||||
# pre-commit hook (React JavaScript)
|
|
||||||
# ESLint 검증 — 실패 시 커밋 차단
|
|
||||||
#==============================================================================
|
|
||||||
|
|
||||||
# npm 확인
|
|
||||||
if ! command -v npx &>/dev/null; then
|
|
||||||
echo "경고: npx가 설치되지 않았습니다. 검증을 건너뜁니다."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# node_modules 확인
|
|
||||||
if [ ! -d "node_modules" ]; then
|
|
||||||
echo "경고: node_modules가 없습니다. 'yarn install' 실행 후 다시 시도하세요."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ESLint 검증 (설정 파일이 있는 경우만)
|
|
||||||
if [ -f ".eslintrc.js" ] || [ -f ".eslintrc.json" ] || [ -f ".eslintrc.cjs" ] || [ -f "eslint.config.js" ] || [ -f "eslint.config.mjs" ]; then
|
|
||||||
echo "pre-commit: ESLint 검증 중..."
|
|
||||||
npx eslint src/ --ext .js,.jsx --quiet 2>&1
|
|
||||||
LINT_RESULT=$?
|
|
||||||
|
|
||||||
if [ $LINT_RESULT -ne 0 ]; then
|
|
||||||
echo ""
|
|
||||||
echo "╔══════════════════════════════════════════════════════════╗"
|
|
||||||
echo "║ ESLint 에러! 커밋이 차단되었습니다. ║"
|
|
||||||
echo "║ 'npx eslint src/ --fix'로 자동 수정을 시도해보세요. ║"
|
|
||||||
echo "╚══════════════════════════════════════════════════════════╝"
|
|
||||||
echo ""
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "pre-commit: ESLint 통과"
|
|
||||||
fi
|
|
||||||
38
.gitignore
vendored
38
.gitignore
vendored
@ -1,38 +0,0 @@
|
|||||||
# Dependencies
|
|
||||||
node_modules
|
|
||||||
package-lock.json
|
|
||||||
|
|
||||||
# Build
|
|
||||||
dist/
|
|
||||||
build/
|
|
||||||
|
|
||||||
# Environment (production secrets)
|
|
||||||
.env.local
|
|
||||||
.env.*.local
|
|
||||||
|
|
||||||
# IDE
|
|
||||||
.idea/
|
|
||||||
.vscode/
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
**/.DS_Store
|
|
||||||
|
|
||||||
# Logs
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
||||||
# OS
|
|
||||||
Thumbs.db
|
|
||||||
ehthumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
|
|
||||||
# Claude Code (개인 파일만 무시, 팀 파일은 추적)
|
|
||||||
.claude/settings.local.json
|
|
||||||
.claude/scripts/
|
|
||||||
|
|
||||||
# TypeScript files (메인 프로젝트 참조용, 빌드/커밋 제외)
|
|
||||||
**/*.ts
|
|
||||||
**/*.tsx
|
|
||||||
# tracking VesselListManager (참조용)
|
|
||||||
src/tracking/components/VesselListManager/
|
|
||||||
@ -1 +0,0 @@
|
|||||||
24
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
불러오는 중...
Reference in New Issue
Block a user