-
Notifications
You must be signed in to change notification settings - Fork 1
[Chore] AI 에이전트 설정 보완 #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
feae3c3
docs: AI 작업 기준 정리
KyeongJooni 31d9393
chore: GitHub 협업 자동화 구성
KyeongJooni ff6fa6c
chore: 생성 파일 관리 체계 추가
KyeongJooni f36df7a
chore: 개발 검증 설정 정비
KyeongJooni 0f292fa
refactor: 초기 앱 구조 정리
KyeongJooni 43bbd3f
docs: PR 본문 작성 기준 정리
KyeongJooni a564915
chore: 브랜치 네이밍 형식을 type/slug-{number}로 변경
KyeongJooni 87dbb3d
chore: ci 워크플로우 수정
KyeongJooni 7229a9d
chore: GitHub Actions 보안 취약점 수정
KyeongJooni 40fc8fa
chore: 가드 훅 오탐 방지 로직 강화
KyeongJooni b9d3213
Merge branch 'main' into chore/init-agent-setup-1
KyeongJooni File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # Decision History | ||
|
|
||
| 이 폴더는 AI 에이전트와 개발자가 프로젝트의 중요한 결정 맥락을 잃지 않도록 관리하는 기록입니다. | ||
|
|
||
| ## 기록 대상 | ||
|
|
||
| 아래 중 하나에 해당할 때만 decision 문서를 추가합니다. | ||
|
|
||
| - 디렉터리 구조, 레이어 경계, 파일 배치 기준을 바꿀 때 | ||
| - API client, 상태 관리, form 처리, 테스트 전략 같은 반복 패턴을 정할 때 | ||
| - 라이브러리를 추가하거나 기존 선택지를 바꿀 때 | ||
| - 기존 규칙과 다른 예외를 허용할 때 | ||
| - 나중에 다시 논쟁할 가능성이 높은 trade-off가 있을 때 | ||
|
|
||
| 아래 작업은 기록하지 않습니다. | ||
|
|
||
| - 단순 버그 수정 | ||
| - 오타, 문구, 스타일만 바꾸는 변경 | ||
| - 기존 규칙을 그대로 따르는 CRUD 구현 | ||
| - 한 번 쓰고 끝나는 페이지 내부 구현 세부사항 | ||
|
|
||
| ## 파일명 | ||
|
|
||
| ```text | ||
| NNN-short-title.md | ||
| ``` | ||
|
|
||
| 예시: | ||
|
|
||
| ```text | ||
| 001-admin-api-reference.md | ||
| 002-query-key-policy.md | ||
| 003-page-folder-boundary.md | ||
| ``` | ||
|
|
||
| ## 작성 형식 | ||
|
|
||
| 새 decision은 `.claude/decisions/template.md`를 복사한 형식으로 작성합니다. | ||
|
|
||
| 문서는 길게 쓰지 않습니다. 결정 이유, 버린 대안, 이후 수정자가 지켜야 할 점만 남깁니다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # NNN. 결정 제목 | ||
|
|
||
| ## 상태 | ||
|
|
||
| - Proposed | Accepted | Superseded | ||
|
|
||
| ## 맥락 | ||
|
|
||
| 어떤 문제를 해결하려는지, 어떤 제약이 있었는지 적습니다. | ||
|
|
||
| ## 결정 | ||
|
|
||
| 선택한 방향을 짧게 적습니다. | ||
|
|
||
| ## 근거 | ||
|
|
||
| - 이 선택이 프로젝트에 맞는 이유를 적습니다. | ||
| - 중요한 trade-off가 있다면 함께 적습니다. | ||
|
|
||
| ## 대안 | ||
|
|
||
| - 검토했지만 선택하지 않은 대안과 이유를 적습니다. | ||
|
|
||
| ## 영향 | ||
|
|
||
| - 앞으로 코드를 작성할 때 따라야 하는 기준을 적습니다. | ||
| - 관련 파일이나 규칙이 있으면 링크합니다. | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| $inputText = $env:CLAUDE_TOOL_INPUT | ||
| if (-not $inputText) { | ||
| exit 0 | ||
| } | ||
|
|
||
| $filePath = '' | ||
| $content = $inputText | ||
|
|
||
| try { | ||
| $parsed = $inputText | ConvertFrom-Json | ||
| if ($parsed.file_path) { $filePath = $parsed.file_path } | ||
| if ($parsed.new_string) { $content = $parsed.new_string } | ||
| elseif ($parsed.content) { $content = $parsed.content } | ||
| } catch { } | ||
|
|
||
| $isCodeFile = $filePath -match '\.(ts|tsx|js|jsx)$' | ||
|
|
||
| if ($isCodeFile -and ($content -match 'console\.log')) { | ||
| Write-Error 'Avoid console.log. Use the project logging/debugging approach instead.' | ||
| exit 1 | ||
| } | ||
|
|
||
| if ($isCodeFile -and ($content -match ':\s*any([^A-Za-z]|$)|<any>|as any')) { | ||
| Write-Error 'Avoid explicit any. Use a specific type or unknown.' | ||
| exit 1 | ||
| } | ||
|
|
||
| if ($content -match '(^|\s)(npm|yarn)\s') { | ||
| Write-Error 'Use pnpm in this project.' | ||
| exit 1 | ||
| } | ||
|
|
||
| if ($filePath -match 'tailwind\.config\.') { | ||
| Write-Error 'This is a Tailwind CSS v4 project. Do not create tailwind.config unless explicitly requested.' | ||
| exit 1 | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| $toolInput = $env:TOOL_INPUT | ||
| if (-not $toolInput) { | ||
| exit 0 | ||
| } | ||
|
|
||
| try { | ||
| $json = $toolInput | ConvertFrom-Json | ||
| $filePath = $json.file_path | ||
| } catch { | ||
| exit 0 | ||
| } | ||
|
|
||
| if ($filePath -and ($filePath.EndsWith('.ts') -or $filePath.EndsWith('.tsx'))) { | ||
| pnpm exec eslint --quiet "$filePath" 2>&1 | Select-Object -Last 5 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| $prompt = $env:CLAUDE_USER_PROMPT | ||
| if (-not $prompt) { | ||
| exit 0 | ||
| } | ||
|
|
||
| $prompt = $prompt.ToLowerInvariant() | ||
| $suggestions = New-Object System.Collections.Generic.List[string] | ||
|
|
||
| if ($prompt -match 'commit|staged|push') { | ||
| $suggestions.Add('/commit-kr - create a Korean commit message') | ||
| } | ||
|
|
||
| if ($prompt -match '\bpr\b|pull request') { | ||
| $suggestions.Add('/create-pr - create a PR title and body draft') | ||
| } | ||
|
|
||
| if ($prompt -match 'refactor|cleanup|dedupe|simplify') { | ||
| $suggestions.Add('/refactor - analyze refactoring candidates') | ||
| } | ||
|
|
||
| if ($prompt -match 'test|vitest|tdd|coverage') { | ||
| $suggestions.Add('/gen-test - generate tests') | ||
| } | ||
|
|
||
| if ($prompt -match 'swagger|openapi|api generate|api client|api scaffold|admin api') { | ||
| $suggestions.Add('/scaffold-api - generate API functions and Query hooks') | ||
| } | ||
|
|
||
| if ($prompt -match 'figma|design|screen|layout|component') { | ||
| $suggestions.Add('/figma-to-component - implement a Figma-based component') | ||
| } | ||
|
|
||
| if ($prompt -match 'review') { | ||
| $suggestions.Add('/code-review - review changed code') | ||
| } | ||
|
|
||
| if ($suggestions.Count -gt 0) { | ||
| Write-Output 'Suggested local skills:' | ||
| foreach ($suggestion in $suggestions) { | ||
| Write-Output " $suggestion" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| # Claude Manifest | ||
|
|
||
| 이 문서는 AI 코딩 에이전트가 `kusitms-admin`에서 작업하기 전에 어떤 지침을 읽어야 하는지 정의합니다. | ||
|
|
||
| ## 부트 순서 | ||
|
|
||
| 1. `CLAUDE.md` 또는 `AGENTS.md`에서 프로젝트 개요를 읽습니다. | ||
| 2. 이 manifest를 읽습니다. | ||
| 3. 코드 변경 작업에서는 Tier 1 규칙을 로드합니다. | ||
| 4. Tier 2 규칙과 admin API/domain reference는 작업에 필요한 경우에만 로드합니다. | ||
|
|
||
| ## Tier 1: 기본 로드 | ||
|
|
||
| | 파일 | 목적 | | ||
| | --- | --- | | ||
| | `.claude/rules/code-quality.md` | 코드 품질 원칙 | | ||
| | `.claude/rules/project-constraints.md` | 프로젝트 금지/제약 조건 | | ||
| | `.claude/rules/workflow.md` | 기본 inspect-edit-verify 작업 흐름 | | ||
| | `.claude/rules/verification.md` | 검증 명령 선택 기준 | | ||
|
|
||
| Tier 1은 코드 변경, 리뷰, 리팩터링처럼 실제 작업이 시작될 때만 로드합니다. 단순 질문이나 설명 요청에서는 `CLAUDE.md`와 이 manifest만으로 답합니다. | ||
|
|
||
| ## Tier 2: 필요 시 로드 | ||
|
|
||
| | 작업 | 로드할 문서 | | ||
| | --- | --- | | ||
| | 파일 배치, import, 구조 판단 | `.claude/rules/architecture.md` | | ||
| | TypeScript, React, 네이밍, 스타일 판단 | `.claude/rules/code-style.md` | | ||
| | 재사용 UI 생성 또는 수정 | `.claude/rules/component-guide.md`, `.claude/references/component-patterns.md` | | ||
| | 서버 상태, API client, form 작업 | `.claude/rules/data-fetching.md` | | ||
| | 테스트 추가 또는 수정 | `.claude/rules/testing.md` | | ||
| | SVG 아이콘 또는 barrel index 생성물 작업 | `.claude/rules/generated-workflows.md` | | ||
| | 어드민 API 연동 추가 | `.claude/references/api/admin.md`와 관련 admin API/domain 문서 | | ||
| | 폼 또는 검증 로직 추가 | `.claude/rules/data-fetching.md`와 관련 domain 문서 | | ||
| | PR/커밋 문구 작성 | `.claude/rules/workflow.md`, `.claude/rules/commit-convention.md` | | ||
| | 구조, 라이브러리, 규칙 변경 결정 | `.claude/decisions/README.md` | | ||
|
|
||
| ## Skills | ||
|
|
||
| | Skill | 용도 | | ||
| | --- | --- | | ||
| | `/scaffold-api` | Swagger 기반 API 함수와 TanStack Query hook 생성 | | ||
| | `/gen-test` | Vitest + Testing Library 테스트 생성 | | ||
| | `/code-review` | 변경 코드 리뷰 | | ||
| | `/commit-kr` | 한국어 커밋 메시지 제안 | | ||
| | `/create-pr` | PR 제목과 본문 초안 작성 | | ||
| | `/figma-to-component` | Figma 디자인을 프로젝트 컴포넌트로 구현 | | ||
| | `/refactor` | 동작 변경 없는 리팩터링 후보 분석과 적용 | | ||
|
|
||
| ## Hooks | ||
|
|
||
| Claude Code 환경에서는 `.claude/settings.json`이 아래 hook을 사용합니다. | ||
|
|
||
| - `guard-rules.ps1`: `console.log`, 명시적 `any`, `npm`/`yarn`, Tailwind v3 설정 생성을 차단합니다. | ||
| - `lint-check.ps1`: TypeScript 파일 수정 후 가능한 경우 `pnpm exec eslint --quiet <file>`을 실행합니다. | ||
| - `skill-suggest.ps1`: 사용자 프롬프트 키워드에 맞는 local skill을 제안합니다. | ||
|
|
||
| ## API Reference | ||
|
|
||
| 관련 admin 파일만 로드합니다. 엔드포인트가 아직 문서화되지 않았다면 Swagger에서 admin 관련 endpoint만 확인하고 reference를 업데이트한 뒤 구현합니다. | ||
|
|
||
| | 영역 | 파일 | 트리거 키워드 | | ||
| | --- | --- | --- | | ||
| | 어드민 API 개요 | `.claude/references/api/admin.md` | admin, swagger, API client, axios, fetch | | ||
| | 어드민 인증 | `.claude/references/api/admin-auth.md` | auth, login, token, session | | ||
| | 어드민 멤버 승인 | `.claude/references/api/admin-members.md` | member, pending, approve, reject | | ||
| | 어드민 프로젝트 | `.claude/references/api/admin-projects.md` | project, meetup, corporate | | ||
| | 어드민 학회원 후기 | `.claude/references/api/admin-reviews.md` | review, member review | | ||
| | 어드민 블로그 후기 | `.claude/references/api/admin-blog-reviews.md` | blog review, blog | | ||
| | 어드민 학회 소개 | `.claude/references/api/admin-introductions.md` | introduction, intro, banner | | ||
|
|
||
| ## Domain Reference | ||
|
|
||
| | 도메인 | 파일 | 트리거 키워드 | | ||
| | --- | --- | --- | | ||
| | 멤버 승인 | `.claude/references/domain/members.md` | pending member, approve, reject | | ||
| | 프로젝트 관리 | `.claude/references/domain/projects.md` | project, meetup, corporate | | ||
| | 학회원 후기 관리 | `.claude/references/domain/reviews.md` | review, member review | | ||
| | 블로그 후기 관리 | `.claude/references/domain/blog-reviews.md` | blog review | | ||
| | 학회 소개 관리 | `.claude/references/domain/introductions.md` | introduction, intro, banner | | ||
|
|
||
| ## Decision History | ||
|
|
||
| 프로젝트 구조, 라이브러리, API 처리 방식, 공통 규칙처럼 나중에 반복 논쟁이 생길 수 있는 결정은 `.claude/decisions/`에 기록합니다. | ||
|
|
||
| - 단순 구현, 오타 수정, 일회성 UI 조정은 기록하지 않습니다. | ||
| - 새 decision을 만들기 전 `.claude/decisions/README.md`를 먼저 확인합니다. | ||
| - 파일명은 `NNN-short-title.md` 형식을 사용합니다. | ||
|
|
||
| ## 금지 패턴 | ||
|
|
||
| - 모든 reference 파일을 기본으로 로드하지 않습니다. | ||
| - Swagger 전체를 일반 API 기준으로 해석하지 않고, admin 기능에 필요한 endpoint만 사용합니다. | ||
| - 엔드포인트 경로, request body, response shape를 추측해서 만들지 않습니다. | ||
| - `src/services` 또는 `src/views`를 만들지 않고 기존 구조를 사용합니다. | ||
| - 새 UI 라이브러리나 패키지 매니저를 도입하지 않습니다. | ||
| - Tailwind v4 프로젝트에 Tailwind v3 설정을 추가하지 않습니다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # 어드민 인증 API Reference | ||
|
|
||
| 관리자 로그인, 토큰, 세션, 권한 확인 endpoint 작업에는 이 파일을 사용합니다. | ||
|
|
||
| ## 구현 전 확인 | ||
|
|
||
| - Swagger에서 관리자 인증 endpoint인지 확인합니다. | ||
| - 일반 사용자 인증 API를 관리자 인증으로 대체 사용하지 않습니다. | ||
| - 관리자 API가 Bearer token, cookie session, 또는 다른 인증 방식을 요구하는지 확인합니다. | ||
|
|
||
| ## 문서화할 항목 | ||
|
|
||
| - 관리자 로그인 endpoint path와 method | ||
| - request body | ||
| - response body | ||
| - token refresh 또는 logout endpoint | ||
| - error response shape | ||
|
|
||
| ## 구현 메모 | ||
|
|
||
| - 인증 API 함수는 `src/api/auth.ts` 또는 admin 인증 도메인 파일에 둡니다. | ||
| - 서버 상태는 필요한 경우 TanStack Query로 관리합니다. | ||
| - token 저장 방식은 구현 전 명확히 확인합니다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # 어드민 블로그 후기 API Reference | ||
|
|
||
| Swagger 출처: `https://kusitms.herokuapp.com/api-docs/json` | ||
|
|
||
| 블로그 후기 CRUD에는 이 파일을 사용합니다. | ||
|
|
||
| ## Endpoints | ||
|
|
||
| | Method | Path | Operation ID | Request | Response | | ||
| | --- | --- | --- | --- | --- | | ||
| | `GET` | `/admin/blog-review` | `getBlogReviews` | 없음 | `BaseResponseObject` | | ||
| | `POST` | `/admin/blog-review` | `addBlogReview` | `BlogReviewRequest` multipart | `BaseResponseObject` | | ||
| | `PUT` | `/admin/blog-review` | `updateBlogReview` | `BlogReviewRequest` multipart | `BaseResponseObject` | | ||
| | `DELETE` | `/admin/blog-review/{id}` | `deleteBlogReview` | path: `id` | `BaseResponseObject` | | ||
|
|
||
| ## 구현 메모 | ||
|
|
||
| - API 함수는 `src/api/blogReviews.ts`에 둡니다. | ||
| - query key는 `['admin', 'blog-reviews']`를 우선합니다. | ||
| - 등록/수정은 `multipart/form-data`입니다. | ||
| - 등록/수정/삭제 이후 list query를 invalidate합니다. | ||
|
|
||
| ## Request Fields | ||
|
|
||
| ### `BlogReviewRequest` | ||
|
|
||
| | Field | Type | | ||
| | --- | --- | | ||
| | `blogReviewId` | `number` | | ||
| | `cardinal` | `number` | | ||
| | `part` | `string` | | ||
| | `activity` | `string` | | ||
| | `thumbnailFile` | `File` | | ||
| | `title` | `string` | | ||
| | `previewText` | `string` | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # 어드민 학회 소개 API Reference | ||
|
|
||
| Swagger 출처: `https://kusitms.herokuapp.com/api-docs/json` | ||
|
|
||
| 학회 소개 페이지의 관리자 조회/수정에는 이 파일을 사용합니다. | ||
|
|
||
| ## Endpoints | ||
|
|
||
| | Method | Path | Operation ID | Request | Response | | ||
| | --- | --- | --- | --- | --- | | ||
| | `GET` | `/admin/introductions` | `getIntroduction_1` | 없음 | `BaseResponseObject` | | ||
| | `PUT` | `/admin/introductions` | `updateIntroduction` | `IntroRequest` multipart | `BaseResponseObject` | | ||
|
|
||
| ## 구현 메모 | ||
|
|
||
| - API 함수는 `src/api/introductions.ts`에 둡니다. | ||
| - query key는 `['admin', 'introductions']`를 우선합니다. | ||
| - 수정은 `multipart/form-data`입니다. | ||
| - 수정 이후 소개 조회 query를 invalidate합니다. | ||
|
|
||
| ## Request Fields | ||
|
|
||
| ### `IntroRequest` | ||
|
|
||
| | Field | Type | | ||
| | --- | --- | | ||
| | `bannerCardinal` | `number` | | ||
| | `bannerStatus` | `string` | | ||
| | `slogan` | `string` | | ||
| | `bannerImageFile` | `File` | | ||
| | `memberCount` | `number` | | ||
| | `projectCount` | `number` | | ||
| | `universityCount` | `number` | | ||
| | `introYoutubeLink` | `string` | | ||
| | `planningImage` | `File` | | ||
| | `designImage` | `File` | | ||
| | `frontendImage` | `File` | | ||
| | `backendImage` | `File` | | ||
| | `teams` | `ManagementTeamRequest[]` | | ||
| | `expertLecture` | `ExpertLectureRequest[]` | | ||
| | `obLecture` | `OBLectureRequest[]` | | ||
| | `partnerLogoFiles` | `string[]` 또는 파일 배열, Swagger schema 재확인 필요 | | ||
| | `meetupImages` | `string[]` 또는 파일 배열, Swagger schema 재확인 필요 | | ||
| | `activities` | `ActivityRequest[]` | | ||
| | `sponsors` | `string[]` 또는 파일 배열, Swagger schema 재확인 필요 | |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: kusitms-com/makers-admin-fe
Length of output: 2461
입력 payload env var 계약이 어긋납니다.
guard-rules.ps1는CLAUDE_TOOL_INPUT만 읽는데, 같은 훅 계열과 등록 설정은TOOL_INPUT기준입니다. 입력이 비면 바로 종료되어 guard가 무력화되므로 둘 다 fallback으로 받게 해주세요.🤖 Prompt for AI Agents