Skip to content

Commit bd38347

Browse files
authored
Merge pull request #3 from kusitms-com/chore/init-agent-setup-1
[Chore] AI 에이전트 설정 보완
2 parents 4d2038f + b9d3213 commit bd38347

84 files changed

Lines changed: 3834 additions & 334 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/decisions/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Decision History
2+
3+
이 폴더는 AI 에이전트와 개발자가 프로젝트의 중요한 결정 맥락을 잃지 않도록 관리하는 기록입니다.
4+
5+
## 기록 대상
6+
7+
아래 중 하나에 해당할 때만 decision 문서를 추가합니다.
8+
9+
- 디렉터리 구조, 레이어 경계, 파일 배치 기준을 바꿀 때
10+
- API client, 상태 관리, form 처리, 테스트 전략 같은 반복 패턴을 정할 때
11+
- 라이브러리를 추가하거나 기존 선택지를 바꿀 때
12+
- 기존 규칙과 다른 예외를 허용할 때
13+
- 나중에 다시 논쟁할 가능성이 높은 trade-off가 있을 때
14+
15+
아래 작업은 기록하지 않습니다.
16+
17+
- 단순 버그 수정
18+
- 오타, 문구, 스타일만 바꾸는 변경
19+
- 기존 규칙을 그대로 따르는 CRUD 구현
20+
- 한 번 쓰고 끝나는 페이지 내부 구현 세부사항
21+
22+
## 파일명
23+
24+
```text
25+
NNN-short-title.md
26+
```
27+
28+
예시:
29+
30+
```text
31+
001-admin-api-reference.md
32+
002-query-key-policy.md
33+
003-page-folder-boundary.md
34+
```
35+
36+
## 작성 형식
37+
38+
새 decision은 `.claude/decisions/template.md`를 복사한 형식으로 작성합니다.
39+
40+
문서는 길게 쓰지 않습니다. 결정 이유, 버린 대안, 이후 수정자가 지켜야 할 점만 남깁니다.

.claude/decisions/template.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# NNN. 결정 제목
2+
3+
## 상태
4+
5+
- Proposed | Accepted | Superseded
6+
7+
## 맥락
8+
9+
어떤 문제를 해결하려는지, 어떤 제약이 있었는지 적습니다.
10+
11+
## 결정
12+
13+
선택한 방향을 짧게 적습니다.
14+
15+
## 근거
16+
17+
- 이 선택이 프로젝트에 맞는 이유를 적습니다.
18+
- 중요한 trade-off가 있다면 함께 적습니다.
19+
20+
## 대안
21+
22+
- 검토했지만 선택하지 않은 대안과 이유를 적습니다.
23+
24+
## 영향
25+
26+
- 앞으로 코드를 작성할 때 따라야 하는 기준을 적습니다.
27+
- 관련 파일이나 규칙이 있으면 링크합니다.
28+

.claude/hooks/guard-rules.ps1

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
$inputText = $env:CLAUDE_TOOL_INPUT
2+
if (-not $inputText) {
3+
exit 0
4+
}
5+
6+
$filePath = ''
7+
$content = $inputText
8+
9+
try {
10+
$parsed = $inputText | ConvertFrom-Json
11+
if ($parsed.file_path) { $filePath = $parsed.file_path }
12+
if ($parsed.new_string) { $content = $parsed.new_string }
13+
elseif ($parsed.content) { $content = $parsed.content }
14+
} catch { }
15+
16+
$isCodeFile = $filePath -match '\.(ts|tsx|js|jsx)$'
17+
18+
if ($isCodeFile -and ($content -match 'console\.log')) {
19+
Write-Error 'Avoid console.log. Use the project logging/debugging approach instead.'
20+
exit 1
21+
}
22+
23+
if ($isCodeFile -and ($content -match ':\s*any([^A-Za-z]|$)|<any>|as any')) {
24+
Write-Error 'Avoid explicit any. Use a specific type or unknown.'
25+
exit 1
26+
}
27+
28+
if ($content -match '(^|\s)(npm|yarn)\s') {
29+
Write-Error 'Use pnpm in this project.'
30+
exit 1
31+
}
32+
33+
if ($filePath -match 'tailwind\.config\.') {
34+
Write-Error 'This is a Tailwind CSS v4 project. Do not create tailwind.config unless explicitly requested.'
35+
exit 1
36+
}

.claude/hooks/lint-check.ps1

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
$toolInput = $env:TOOL_INPUT
2+
if (-not $toolInput) {
3+
exit 0
4+
}
5+
6+
try {
7+
$json = $toolInput | ConvertFrom-Json
8+
$filePath = $json.file_path
9+
} catch {
10+
exit 0
11+
}
12+
13+
if ($filePath -and ($filePath.EndsWith('.ts') -or $filePath.EndsWith('.tsx'))) {
14+
pnpm exec eslint --quiet "$filePath" 2>&1 | Select-Object -Last 5
15+
}

.claude/hooks/skill-suggest.ps1

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
$prompt = $env:CLAUDE_USER_PROMPT
2+
if (-not $prompt) {
3+
exit 0
4+
}
5+
6+
$prompt = $prompt.ToLowerInvariant()
7+
$suggestions = New-Object System.Collections.Generic.List[string]
8+
9+
if ($prompt -match 'commit|staged|push') {
10+
$suggestions.Add('/commit-kr - create a Korean commit message')
11+
}
12+
13+
if ($prompt -match '\bpr\b|pull request') {
14+
$suggestions.Add('/create-pr - create a PR title and body draft')
15+
}
16+
17+
if ($prompt -match 'refactor|cleanup|dedupe|simplify') {
18+
$suggestions.Add('/refactor - analyze refactoring candidates')
19+
}
20+
21+
if ($prompt -match 'test|vitest|tdd|coverage') {
22+
$suggestions.Add('/gen-test - generate tests')
23+
}
24+
25+
if ($prompt -match 'swagger|openapi|api generate|api client|api scaffold|admin api') {
26+
$suggestions.Add('/scaffold-api - generate API functions and Query hooks')
27+
}
28+
29+
if ($prompt -match 'figma|design|screen|layout|component') {
30+
$suggestions.Add('/figma-to-component - implement a Figma-based component')
31+
}
32+
33+
if ($prompt -match 'review') {
34+
$suggestions.Add('/code-review - review changed code')
35+
}
36+
37+
if ($suggestions.Count -gt 0) {
38+
Write-Output 'Suggested local skills:'
39+
foreach ($suggestion in $suggestions) {
40+
Write-Output " $suggestion"
41+
}
42+
}

.claude/manifest.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Claude Manifest
2+
3+
이 문서는 AI 코딩 에이전트가 `kusitms-admin`에서 작업하기 전에 어떤 지침을 읽어야 하는지 정의합니다.
4+
5+
## 부트 순서
6+
7+
1. `CLAUDE.md` 또는 `AGENTS.md`에서 프로젝트 개요를 읽습니다.
8+
2. 이 manifest를 읽습니다.
9+
3. 코드 변경 작업에서는 Tier 1 규칙을 로드합니다.
10+
4. Tier 2 규칙과 admin API/domain reference는 작업에 필요한 경우에만 로드합니다.
11+
12+
## Tier 1: 기본 로드
13+
14+
| 파일 | 목적 |
15+
| --- | --- |
16+
| `.claude/rules/code-quality.md` | 코드 품질 원칙 |
17+
| `.claude/rules/project-constraints.md` | 프로젝트 금지/제약 조건 |
18+
| `.claude/rules/workflow.md` | 기본 inspect-edit-verify 작업 흐름 |
19+
| `.claude/rules/verification.md` | 검증 명령 선택 기준 |
20+
21+
Tier 1은 코드 변경, 리뷰, 리팩터링처럼 실제 작업이 시작될 때만 로드합니다. 단순 질문이나 설명 요청에서는 `CLAUDE.md`와 이 manifest만으로 답합니다.
22+
23+
## Tier 2: 필요 시 로드
24+
25+
| 작업 | 로드할 문서 |
26+
| --- | --- |
27+
| 파일 배치, import, 구조 판단 | `.claude/rules/architecture.md` |
28+
| TypeScript, React, 네이밍, 스타일 판단 | `.claude/rules/code-style.md` |
29+
| 재사용 UI 생성 또는 수정 | `.claude/rules/component-guide.md`, `.claude/references/component-patterns.md` |
30+
| 서버 상태, API client, form 작업 | `.claude/rules/data-fetching.md` |
31+
| 테스트 추가 또는 수정 | `.claude/rules/testing.md` |
32+
| SVG 아이콘 또는 barrel index 생성물 작업 | `.claude/rules/generated-workflows.md` |
33+
| 어드민 API 연동 추가 | `.claude/references/api/admin.md`와 관련 admin API/domain 문서 |
34+
| 폼 또는 검증 로직 추가 | `.claude/rules/data-fetching.md`와 관련 domain 문서 |
35+
| PR/커밋 문구 작성 | `.claude/rules/workflow.md`, `.claude/rules/commit-convention.md` |
36+
| 구조, 라이브러리, 규칙 변경 결정 | `.claude/decisions/README.md` |
37+
38+
## Skills
39+
40+
| Skill | 용도 |
41+
| --- | --- |
42+
| `/scaffold-api` | Swagger 기반 API 함수와 TanStack Query hook 생성 |
43+
| `/gen-test` | Vitest + Testing Library 테스트 생성 |
44+
| `/code-review` | 변경 코드 리뷰 |
45+
| `/commit-kr` | 한국어 커밋 메시지 제안 |
46+
| `/create-pr` | PR 제목과 본문 초안 작성 |
47+
| `/figma-to-component` | Figma 디자인을 프로젝트 컴포넌트로 구현 |
48+
| `/refactor` | 동작 변경 없는 리팩터링 후보 분석과 적용 |
49+
50+
## Hooks
51+
52+
Claude Code 환경에서는 `.claude/settings.json`이 아래 hook을 사용합니다.
53+
54+
- `guard-rules.ps1`: `console.log`, 명시적 `any`, `npm`/`yarn`, Tailwind v3 설정 생성을 차단합니다.
55+
- `lint-check.ps1`: TypeScript 파일 수정 후 가능한 경우 `pnpm exec eslint --quiet <file>`을 실행합니다.
56+
- `skill-suggest.ps1`: 사용자 프롬프트 키워드에 맞는 local skill을 제안합니다.
57+
58+
## API Reference
59+
60+
관련 admin 파일만 로드합니다. 엔드포인트가 아직 문서화되지 않았다면 Swagger에서 admin 관련 endpoint만 확인하고 reference를 업데이트한 뒤 구현합니다.
61+
62+
| 영역 | 파일 | 트리거 키워드 |
63+
| --- | --- | --- |
64+
| 어드민 API 개요 | `.claude/references/api/admin.md` | admin, swagger, API client, axios, fetch |
65+
| 어드민 인증 | `.claude/references/api/admin-auth.md` | auth, login, token, session |
66+
| 어드민 멤버 승인 | `.claude/references/api/admin-members.md` | member, pending, approve, reject |
67+
| 어드민 프로젝트 | `.claude/references/api/admin-projects.md` | project, meetup, corporate |
68+
| 어드민 학회원 후기 | `.claude/references/api/admin-reviews.md` | review, member review |
69+
| 어드민 블로그 후기 | `.claude/references/api/admin-blog-reviews.md` | blog review, blog |
70+
| 어드민 학회 소개 | `.claude/references/api/admin-introductions.md` | introduction, intro, banner |
71+
72+
## Domain Reference
73+
74+
| 도메인 | 파일 | 트리거 키워드 |
75+
| --- | --- | --- |
76+
| 멤버 승인 | `.claude/references/domain/members.md` | pending member, approve, reject |
77+
| 프로젝트 관리 | `.claude/references/domain/projects.md` | project, meetup, corporate |
78+
| 학회원 후기 관리 | `.claude/references/domain/reviews.md` | review, member review |
79+
| 블로그 후기 관리 | `.claude/references/domain/blog-reviews.md` | blog review |
80+
| 학회 소개 관리 | `.claude/references/domain/introductions.md` | introduction, intro, banner |
81+
82+
## Decision History
83+
84+
프로젝트 구조, 라이브러리, API 처리 방식, 공통 규칙처럼 나중에 반복 논쟁이 생길 수 있는 결정은 `.claude/decisions/`에 기록합니다.
85+
86+
- 단순 구현, 오타 수정, 일회성 UI 조정은 기록하지 않습니다.
87+
- 새 decision을 만들기 전 `.claude/decisions/README.md`를 먼저 확인합니다.
88+
- 파일명은 `NNN-short-title.md` 형식을 사용합니다.
89+
90+
## 금지 패턴
91+
92+
- 모든 reference 파일을 기본으로 로드하지 않습니다.
93+
- Swagger 전체를 일반 API 기준으로 해석하지 않고, admin 기능에 필요한 endpoint만 사용합니다.
94+
- 엔드포인트 경로, request body, response shape를 추측해서 만들지 않습니다.
95+
- `src/services` 또는 `src/views`를 만들지 않고 기존 구조를 사용합니다.
96+
- 새 UI 라이브러리나 패키지 매니저를 도입하지 않습니다.
97+
- Tailwind v4 프로젝트에 Tailwind v3 설정을 추가하지 않습니다.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# 어드민 인증 API Reference
2+
3+
관리자 로그인, 토큰, 세션, 권한 확인 endpoint 작업에는 이 파일을 사용합니다.
4+
5+
## 구현 전 확인
6+
7+
- Swagger에서 관리자 인증 endpoint인지 확인합니다.
8+
- 일반 사용자 인증 API를 관리자 인증으로 대체 사용하지 않습니다.
9+
- 관리자 API가 Bearer token, cookie session, 또는 다른 인증 방식을 요구하는지 확인합니다.
10+
11+
## 문서화할 항목
12+
13+
- 관리자 로그인 endpoint path와 method
14+
- request body
15+
- response body
16+
- token refresh 또는 logout endpoint
17+
- error response shape
18+
19+
## 구현 메모
20+
21+
- 인증 API 함수는 `src/api/auth.ts` 또는 admin 인증 도메인 파일에 둡니다.
22+
- 서버 상태는 필요한 경우 TanStack Query로 관리합니다.
23+
- token 저장 방식은 구현 전 명확히 확인합니다.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# 어드민 블로그 후기 API Reference
2+
3+
Swagger 출처: `https://kusitms.herokuapp.com/api-docs/json`
4+
5+
블로그 후기 CRUD에는 이 파일을 사용합니다.
6+
7+
## Endpoints
8+
9+
| Method | Path | Operation ID | Request | Response |
10+
| --- | --- | --- | --- | --- |
11+
| `GET` | `/admin/blog-review` | `getBlogReviews` | 없음 | `BaseResponseObject` |
12+
| `POST` | `/admin/blog-review` | `addBlogReview` | `BlogReviewRequest` multipart | `BaseResponseObject` |
13+
| `PUT` | `/admin/blog-review` | `updateBlogReview` | `BlogReviewRequest` multipart | `BaseResponseObject` |
14+
| `DELETE` | `/admin/blog-review/{id}` | `deleteBlogReview` | path: `id` | `BaseResponseObject` |
15+
16+
## 구현 메모
17+
18+
- API 함수는 `src/api/blogReviews.ts`에 둡니다.
19+
- query key는 `['admin', 'blog-reviews']`를 우선합니다.
20+
- 등록/수정은 `multipart/form-data`입니다.
21+
- 등록/수정/삭제 이후 list query를 invalidate합니다.
22+
23+
## Request Fields
24+
25+
### `BlogReviewRequest`
26+
27+
| Field | Type |
28+
| --- | --- |
29+
| `blogReviewId` | `number` |
30+
| `cardinal` | `number` |
31+
| `part` | `string` |
32+
| `activity` | `string` |
33+
| `thumbnailFile` | `File` |
34+
| `title` | `string` |
35+
| `previewText` | `string` |
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# 어드민 학회 소개 API Reference
2+
3+
Swagger 출처: `https://kusitms.herokuapp.com/api-docs/json`
4+
5+
학회 소개 페이지의 관리자 조회/수정에는 이 파일을 사용합니다.
6+
7+
## Endpoints
8+
9+
| Method | Path | Operation ID | Request | Response |
10+
| --- | --- | --- | --- | --- |
11+
| `GET` | `/admin/introductions` | `getIntroduction_1` | 없음 | `BaseResponseObject` |
12+
| `PUT` | `/admin/introductions` | `updateIntroduction` | `IntroRequest` multipart | `BaseResponseObject` |
13+
14+
## 구현 메모
15+
16+
- API 함수는 `src/api/introductions.ts`에 둡니다.
17+
- query key는 `['admin', 'introductions']`를 우선합니다.
18+
- 수정은 `multipart/form-data`입니다.
19+
- 수정 이후 소개 조회 query를 invalidate합니다.
20+
21+
## Request Fields
22+
23+
### `IntroRequest`
24+
25+
| Field | Type |
26+
| --- | --- |
27+
| `bannerCardinal` | `number` |
28+
| `bannerStatus` | `string` |
29+
| `slogan` | `string` |
30+
| `bannerImageFile` | `File` |
31+
| `memberCount` | `number` |
32+
| `projectCount` | `number` |
33+
| `universityCount` | `number` |
34+
| `introYoutubeLink` | `string` |
35+
| `planningImage` | `File` |
36+
| `designImage` | `File` |
37+
| `frontendImage` | `File` |
38+
| `backendImage` | `File` |
39+
| `teams` | `ManagementTeamRequest[]` |
40+
| `expertLecture` | `ExpertLectureRequest[]` |
41+
| `obLecture` | `OBLectureRequest[]` |
42+
| `partnerLogoFiles` | `string[]` 또는 파일 배열, Swagger schema 재확인 필요 |
43+
| `meetupImages` | `string[]` 또는 파일 배열, Swagger schema 재확인 필요 |
44+
| `activities` | `ActivityRequest[]` |
45+
| `sponsors` | `string[]` 또는 파일 배열, Swagger schema 재확인 필요 |

0 commit comments

Comments
 (0)