diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..aaa6604 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,139 @@ +name: ๐Ÿ”ง Claude ์ˆ˜์ • ์ž‘์—… +description: Claude Code์—๊ฒŒ ๋ฌธ์ œ ํ•ด๊ฒฐ์ด๋‚˜ ์ˆ˜์ • ์ž‘์—…์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. +title: "[FIX] " +labels: ["fix", "claude"] +body: + - type: markdown + attributes: + value: | + ## ๐Ÿ”ง Claude Code ์ˆ˜์ • ์ž‘์—… ์ง€์‹œ์„œ + + Claude Code์—๊ฒŒ ๋ฌธ์ œ ํ•ด๊ฒฐ์ด๋‚˜ ๊ธฐ์กด ์ฝ”๋“œ ์ˆ˜์ • ์ž‘์—…์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. + ๊ตฌ์ฒด์ ์ธ ๋ฌธ์ œ ์ƒํ™ฉ๊ณผ ํ•ด๊ฒฐ ๋ฐฉํ–ฅ์„ ์ œ์‹œํ•ด์ฃผ์„ธ์š”. + + - type: textarea + id: problem_description + attributes: + label: ๐Ÿ› ๋ฌธ์ œ ์ƒํ™ฉ + description: ํ˜„์žฌ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ๋Š” ๋ฌธ์ œ๋‚˜ ์ˆ˜์ •์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ์ƒ์„ธํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ๋ชจ๋ฐ”์ผ์—์„œ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด๊ฐ€ ์ œ๋Œ€๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š์Œ + - ๋‹คํฌ๋ชจ๋“œ์—์„œ ํ…์ŠคํŠธ ์ƒ‰์ƒ์ด ๋ณด์ด์ง€ ์•Š์Œ + - ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ๋กœ๋”ฉ ์†๋„๊ฐ€ ๋„ˆ๋ฌด ๋А๋ฆผ + - ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์ •ํ™•ํ•˜์ง€ ์•Š์Œ + - ํŠน์ • ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ ˆ์ด์•„์›ƒ์ด ๊นจ์ง + validations: + required: true + + - type: textarea + id: current_behavior + attributes: + label: โŒ ํ˜„์žฌ ๋™์ž‘ + description: ํ˜„์žฌ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๊ณ  ์žˆ๋Š”์ง€ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ๋ชจ๋ฐ”์ผ์—์„œ ํ–„๋ฒ„๊ฑฐ ๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ•ด๋„ ์•„๋ฌด ๋ฐ˜์‘์ด ์—†์Œ + - ๋‹คํฌ๋ชจ๋“œ์—์„œ ์ œ๋ชฉ ํ…์ŠคํŠธ๊ฐ€ ๊ฒ€์€์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜์–ด ๋ณด์ด์ง€ ์•Š์Œ + - ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ๊ฐ„์ด 5์ดˆ ์ด์ƒ ์†Œ์š”๋จ + validations: + required: true + + - type: textarea + id: expected_behavior + attributes: + label: โœ… ์›ํ•˜๋Š” ๋™์ž‘ + description: ์–ด๋–ป๊ฒŒ ์ˆ˜์ •๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ๋ชจ๋ฐ”์ผ์—์„œ ํ–„๋ฒ„๊ฑฐ ๋ฉ”๋‰ด ํด๋ฆญ ์‹œ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด๊ฐ€ ํŽผ์ณ์ ธ์•ผ ํ•จ + - ๋‹คํฌ๋ชจ๋“œ์—์„œ ์ œ๋ชฉ ํ…์ŠคํŠธ๊ฐ€ ํฐ์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋˜์–ด์•ผ ํ•จ + - ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ๊ฐ„์ด 2์ดˆ ์ด๋‚ด๋กœ ๋‹จ์ถ•๋˜์–ด์•ผ ํ•จ + validations: + required: true + + - type: textarea + id: reproduction_steps + attributes: + label: ๐Ÿ”„ ์žฌํ˜„ ๋ฐฉ๋ฒ• + description: ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ๊ณ„๋ฅผ ์ƒ์„ธํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + 1. ์‚ฌ์ดํŠธ ์ ‘์† + 2. ๋ชจ๋ฐ”์ผ ํ™”๋ฉด ํฌ๊ธฐ๋กœ ๋ณ€๊ฒฝ + 3. ํ–„๋ฒ„๊ฑฐ ๋ฉ”๋‰ด ํด๋ฆญ + 4. ๋ฌธ์ œ ํ™•์ธ + validations: + required: true + + - type: dropdown + id: fix_type + attributes: + label: ๐Ÿท๏ธ ์ˆ˜์ • ์œ ํ˜• + description: ์–ด๋–ค ์ข…๋ฅ˜์˜ ์ˆ˜์ • ์ž‘์—…์ธ๊ฐ€์š”? + options: + - ๋ฒ„๊ทธ ์ˆ˜์ • + - ์Šคํƒ€์ผ/๋ ˆ์ด์•„์›ƒ ์ˆ˜์ • + - ์„ฑ๋Šฅ ์ตœ์ ํ™” + - ๊ธฐ๋Šฅ ๊ฐœ์„  + - ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ ํ•ด๊ฒฐ + - ๋ณด์•ˆ ์ทจ์•ฝ์  ์ˆ˜์ • + - ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง + - ๊ธฐํƒ€ + default: 0 + validations: + required: true + + - type: dropdown + id: urgency + attributes: + label: ๐Ÿšจ ๊ธด๊ธ‰๋„ + description: ์ˆ˜์ • ์ž‘์—…์˜ ๊ธด๊ธ‰๋„๋ฅผ ์„ ํƒํ•ด์ฃผ์„ธ์š”. + options: + - ๐Ÿ”ด ๊ธด๊ธ‰ (์ฆ‰์‹œ ์ˆ˜์ • ํ•„์š”) + - ๐ŸŸก ๋ณดํ†ต (์ผ๋ฐ˜์ ์ธ ์ˆ˜์ •) + - ๐ŸŸข ๋‚ฎ์Œ (์‹œ๊ฐ„ ์—ฌ์œ  ์žˆ์Œ) + default: 1 + validations: + required: true + + - type: textarea + id: affected_files + attributes: + label: ๐Ÿ“ ๊ด€๋ จ ํŒŒ์ผ + description: ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ํŒŒ์ผ์ด๋‚˜ ์ˆ˜์ •์ด ํ•„์š”ํ•œ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๋ช…์‹œํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - src/app/_components/Navigation.tsx + - src/app/globals.css + - src/app/layout.tsx + + - type: textarea + id: error_logs + attributes: + label: ๐Ÿ“‹ ์—๋Ÿฌ ๋กœ๊ทธ + description: ์ฝ˜์†” ์—๋Ÿฌ๋‚˜ ๋กœ๊ทธ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ถ™์—ฌ๋„ฃ์–ด ์ฃผ์„ธ์š”. + placeholder: | + ์ฝ˜์†” ์—๋Ÿฌ, ๋นŒ๋“œ ์—๋Ÿฌ, ๋˜๋Š” ๊ธฐํƒ€ ๊ด€๋ จ ๋กœ๊ทธ๋ฅผ ์—ฌ๊ธฐ์— ๋ถ™์—ฌ๋„ฃ์–ด ์ฃผ์„ธ์š”. + + - type: textarea + id: environment_info + attributes: + label: ๐ŸŒ ํ™˜๊ฒฝ ์ •๋ณด + description: ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ํ™˜๊ฒฝ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ๋ธŒ๋ผ์šฐ์ €: Chrome 120.0.0.0 + - ์šด์˜์ฒด์ œ: macOS 14.0 + - ๋””๋ฐ”์ด์Šค: iPhone 15 Pro + - ํ™”๋ฉด ํฌ๊ธฐ: 375x812 + + - type: textarea + id: additional_context + attributes: + label: ๐Ÿ“ ์ถ”๊ฐ€ ์ •๋ณด + description: ๋ฌธ์ œ ํ•ด๊ฒฐ์— ๋„์›€์ด ๋  ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๊ฐ€ ์žˆ๋‚˜์š”? + placeholder: | + - ์ตœ๊ทผ ๋ณ€๊ฒฝ์‚ฌํ•ญ + - ๊ด€๋ จ ์ด์Šˆ๋‚˜ PR + - ์ฐธ๊ณ ํ•  ๋งŒํ•œ ์ž๋ฃŒ + - ๊ธฐํƒ€ ์ปจํ…์ŠคํŠธ ์ •๋ณด \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..90219d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,4 @@ +blank_issues_enabled: false +contact_links: + - name: ๐Ÿ“– ๋ธ”๋กœ๊ทธ ๋ฐฉ๋ฌธ + url: https://kickbelldev.github.io/blog \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..c36e69f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,110 @@ +name: ๐Ÿค– Claude ์ž‘์—… ์ง€์‹œ +description: Claude Code์—๊ฒŒ ์ž‘์—…์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. +title: "[TASK] " +labels: ["task", "claude"] +body: + - type: markdown + attributes: + value: | + ## ๐Ÿ’ก Claude Code ์ž‘์—… ์ง€์‹œ์„œ + + Claude Code์—๊ฒŒ ๊ฐœ๋ฐœ ์ž‘์—…์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. + ๊ตฌ์ฒด์ ์ด๊ณ  ๋ช…ํ™•ํ•œ ์ง€์‹œ๋ฅผ ํ†ตํ•ด ํšจ๊ณผ์ ์ธ ์ž‘์—…์„ ์ง„ํ–‰ํ•ด๋ณด์„ธ์š”. + + - type: textarea + id: task_description + attributes: + label: ๐Ÿ“‹ ์ž‘์—… ๋‚ด์šฉ + description: Claude์—๊ฒŒ ์ˆ˜ํ–‰์‹œํ‚ค๊ณ  ์‹ถ์€ ์ž‘์—…์„ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ๋ธ”๋กœ๊ทธ์— ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•ด์ค˜ + - ๋‹คํฌ๋ชจ๋“œ ํ† ๊ธ€ ๋ฒ„ํŠผ ๊ตฌํ˜„ + - ๋ฐ˜์‘ํ˜• ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด ๋งŒ๋“ค๊ธฐ + - ํฌ์ŠคํŠธ ํŽ˜์ด์ง€๋„ค์ด์…˜ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ + - ์ฝ”๋“œ ๋ธ”๋ก ๋ณต์‚ฌ ๋ฒ„ํŠผ ์ถ”๊ฐ€ + validations: + required: true + + - type: textarea + id: requirements + attributes: + label: ๐Ÿ“Œ ์š”๊ตฌ์‚ฌํ•ญ + description: ์ž‘์—… ์‹œ ๊ณ ๋ คํ•ด์•ผ ํ•  ์กฐ๊ฑด์ด๋‚˜ ์ œ์•ฝ์‚ฌํ•ญ์ด ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - TypeScript ์‚ฌ์šฉํ•ด์„œ ์ž‘์„ฑ + - ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ๋„ ์ž˜ ์ž‘๋™ํ•ด์•ผ ํ•จ + - ๊ธฐ์กด UI/UX์™€ ์ผ๊ด€์„ฑ ์œ ์ง€ + - ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ณ ๋ ค + - ์ ‘๊ทผ์„ฑ ๊ณ ๋ ค์‚ฌํ•ญ + + - type: dropdown + id: task_type + attributes: + label: ๐Ÿท๏ธ ์ž‘์—… ์œ ํ˜• + description: ์–ด๋–ค ์ข…๋ฅ˜์˜ ์ž‘์—…์ธ๊ฐ€์š”? + options: + - ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ๊ตฌํ˜„ + - ๊ธฐ์กด ๊ธฐ๋Šฅ ๊ฐœ์„  + - ๋ฒ„๊ทธ ์ˆ˜์ • + - ๋ฆฌํŒฉํ† ๋ง + - UI/UX ๊ฐœ์„  + - ์„ฑ๋Šฅ ์ตœ์ ํ™” + - ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ + - ๋ฌธ์„œ ์ž‘์„ฑ + - ๊ธฐํƒ€ + default: 0 + validations: + required: true + + - type: dropdown + id: priority + attributes: + label: ๐Ÿ”ฅ ์šฐ์„ ์ˆœ์œ„ + description: ์ž‘์—…์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์„ ํƒํ•ด์ฃผ์„ธ์š”. + options: + - ๐Ÿ”ด ๋†’์Œ (์ฆ‰์‹œ ์ฒ˜๋ฆฌ ํ•„์š”) + - ๐ŸŸก ๋ณดํ†ต (์ผ๋ฐ˜์ ์ธ ์ž‘์—…) + - ๐ŸŸข ๋‚ฎ์Œ (์‹œ๊ฐ„ ์—ฌ์œ  ์žˆ์Œ) + default: 1 + validations: + required: true + + - type: textarea + id: technical_details + attributes: + label: ๐Ÿ”ง ๊ธฐ์ˆ ์  ์„ธ๋ถ€์‚ฌํ•ญ + description: ๊ตฌํ˜„์— ํ•„์š”ํ•œ ๊ธฐ์ˆ ์  ์ •๋ณด๋‚˜ ์ฐธ๊ณ ์‚ฌํ•ญ์ด ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ํŒจํ‚ค์ง€ ์‚ฌ์šฉ + - API ์—”๋“œํฌ์ธํŠธ ์ •๋ณด + - ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋‚˜ ์Šคํ‚ค๋งˆ + - ๊ด€๋ จ ํŒŒ์ผ ๊ฒฝ๋กœ + - ์ฐธ๊ณ ํ•  ๊ธฐ์กด ์ฝ”๋“œ + + - type: textarea + id: acceptance_criteria + attributes: + label: โœ… ์™„๋ฃŒ ์กฐ๊ฑด + description: ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด๋“ค์„ ๋ช…์‹œํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - [ ] ๊ฒ€์ƒ‰์ฐฝ์—์„œ ํ‚ค์›Œ๋“œ ์ž…๋ ฅ ์‹œ ๊ด€๋ จ ํฌ์ŠคํŠธ ํ‘œ์‹œ + - [ ] ๋ชจ๋ฐ”์ผ์—์„œ๋„ ์ •์ƒ ์ž‘๋™ ํ™•์ธ + - [ ] ๋นŒ๋“œ ๋ฐ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ + - [ ] ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฒ€์‚ฌ ํ†ต๊ณผ + - [ ] ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ ํ™•์ธ + + - type: textarea + id: references + attributes: + label: ๐Ÿ“š ์ฐธ๊ณ  ์ž๋ฃŒ + description: ์ž‘์—…์— ๋„์›€์ด ๋  ์ฐธ๊ณ  ์ž๋ฃŒ๋‚˜ ๋งํฌ๊ฐ€ ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - ๊ด€๋ จ ๋ฌธ์„œ๋‚˜ ๊ฐ€์ด๋“œ ๋งํฌ + - ์ฐธ๊ณ ํ•  ์‚ฌ์ดํŠธ๋‚˜ ์˜ˆ์‹œ + - ๊ด€๋ จ GitHub ์ด์Šˆ๋‚˜ PR + - ๋””์ž์ธ ์‹œ์•ˆ์ด๋‚˜ ๋ชฉ์—… \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/refactor.yml b/.github/ISSUE_TEMPLATE/refactor.yml new file mode 100644 index 0000000..7e0446a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/refactor.yml @@ -0,0 +1,140 @@ +name: โ™ป๏ธ Claude ๋ฆฌํŒฉํ† ๋ง ์ž‘์—… +description: Claude Code์—๊ฒŒ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง ์ž‘์—…์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. +title: "[REFACTOR] " +labels: ["refactor", "claude"] +body: + - type: markdown + attributes: + value: | + ## โ™ป๏ธ Claude Code ๋ฆฌํŒฉํ† ๋ง ์ž‘์—… ์ง€์‹œ์„œ + + Claude Code์—๊ฒŒ ์ฝ”๋“œ ๊ตฌ์กฐ ๊ฐœ์„ , ์ตœ์ ํ™”, ์ •๋ฆฌ ์ž‘์—…์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. + ํ˜„์žฌ ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ๊ณผ ๊ฐœ์„  ๋ฐฉํ–ฅ์„ ๋ช…ํ™•ํžˆ ์ œ์‹œํ•ด์ฃผ์„ธ์š”. + + - type: textarea + id: current_code_issues + attributes: + label: ๐Ÿ” ํ˜„์žฌ ์ฝ”๋“œ ๋ฌธ์ œ์  + description: ๋ฆฌํŒฉํ† ๋ง์ด ํ•„์š”ํ•œ ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ์„ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ์ค‘๋ณต๋œ ์ฝ”๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ˜๋ณต๋จ + - ๋„ˆ๋ฌด ๊ธด ํ•จ์ˆ˜๋กœ ์ธํ•ด ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง + - ๋ณต์žกํ•œ ์กฐ๊ฑด๋ฌธ์œผ๋กœ ์ธํ•œ ์œ ์ง€๋ณด์ˆ˜ ์–ด๋ ค์›€ + - ๋ถˆํ•„์š”ํ•œ ์˜์กด์„ฑ์ด๋‚˜ import๊ฐ€ ๋งŽ์Œ + - ๋„ค์ด๋ฐ์ด ์ผ๊ด€๋˜์ง€ ์•Š์Œ + - ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ์ฑ…์ž„์„ ๊ฐ€์ง + validations: + required: true + + - type: textarea + id: target_files + attributes: + label: ๐Ÿ“ ๋Œ€์ƒ ํŒŒ์ผ/ํด๋” + description: ๋ฆฌํŒฉํ† ๋งํ•  ํŒŒ์ผ์ด๋‚˜ ํด๋” ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - src/app/_components/Navigation.tsx + - src/app/blog/_components/ + - src/app/_lib/utils.ts + - src/app/globals.css + validations: + required: true + + - type: dropdown + id: refactor_type + attributes: + label: ๐Ÿท๏ธ ๋ฆฌํŒฉํ† ๋ง ์œ ํ˜• + description: ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ฆฌํŒฉํ† ๋ง์ธ๊ฐ€์š”? + options: + - ์ฝ”๋“œ ์ค‘๋ณต ์ œ๊ฑฐ + - ํ•จ์ˆ˜/์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ + - ๋„ค์ด๋ฐ ๊ฐœ์„  + - ๊ตฌ์กฐ ์žฌ์กฐ์ง + - ์„ฑ๋Šฅ ์ตœ์ ํ™” + - ํƒ€์ž… ์•ˆ์ „์„ฑ ๊ฐœ์„  + - ์Šคํƒ€์ผ ํ†ต์ผ + - ์˜์กด์„ฑ ์ •๋ฆฌ + - ๊ธฐํƒ€ + default: 0 + validations: + required: true + + - type: textarea + id: refactor_goals + attributes: + label: ๐ŸŽฏ ๋ฆฌํŒฉํ† ๋ง ๋ชฉํ‘œ + description: ๋ฆฌํŒฉํ† ๋ง์„ ํ†ตํ•ด ๋‹ฌ์„ฑํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชฉํ‘œ๋ฅผ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ + - ์œ ์ง€๋ณด์ˆ˜์„ฑ ๊ฐœ์„  + - ์„ฑ๋Šฅ ์ตœ์ ํ™” + - ํƒ€์ž… ์•ˆ์ „์„ฑ ๊ฐ•ํ™” + - ์žฌ์‚ฌ์šฉ์„ฑ ์ฆ๋Œ€ + - ์ฝ”๋“œ ์ผ๊ด€์„ฑ ํ™•๋ณด + validations: + required: true + + - type: textarea + id: specific_requirements + attributes: + label: ๐Ÿ“‹ ๊ตฌ์ฒด์  ์š”๊ตฌ์‚ฌํ•ญ + description: ๋ฆฌํŒฉํ† ๋ง ์‹œ ์ง€์ผœ์•ผ ํ•  ์กฐ๊ฑด์ด๋‚˜ ํŠน๋ณ„ํ•œ ์š”๊ตฌ์‚ฌํ•ญ์ด ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - ๊ธฐ์กด API ํ˜ธํ™˜์„ฑ ์œ ์ง€ + - ํŠน์ • ๋””์ž์ธ ํŒจํ„ด ์ ์šฉ + - ์„ฑ๋Šฅ ์ €ํ•˜ ์—†์ด ์ง„ํ–‰ + - ๊ธฐ์กด ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ๋ณด์žฅ + - ํŠน์ • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ/์ œ๊ฑฐ + + - type: dropdown + id: complexity + attributes: + label: ๐Ÿ“Š ๋ณต์žก๋„ + description: ๋ฆฌํŒฉํ† ๋ง ์ž‘์—…์˜ ์˜ˆ์ƒ ๋ณต์žก๋„๋Š” ์–ด๋А ์ •๋„์ธ๊ฐ€์š”? + options: + - ๐ŸŸข ๊ฐ„๋‹จ (๋‹จ์ˆœํ•œ ์ •๋ฆฌ ์ž‘์—…) + - ๐ŸŸก ๋ณดํ†ต (๊ตฌ์กฐ์  ๋ณ€๊ฒฝ ํฌํ•จ) + - ๐Ÿ”ด ๋ณต์žก (๋Œ€๊ทœ๋ชจ ์žฌ๊ตฌ์„ฑ ํ•„์š”) + default: 1 + validations: + required: true + + - type: textarea + id: expected_outcome + attributes: + label: โœ… ์˜ˆ์ƒ ๊ฒฐ๊ณผ + description: ๋ฆฌํŒฉํ† ๋ง ์™„๋ฃŒ ํ›„ ์–ด๋–ค ๋ชจ์Šต์ด ๋˜์–ด์•ผ ํ•˜๋Š”์ง€ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - [ ] ์ค‘๋ณต ์ฝ”๋“œ๊ฐ€ ๊ณตํ†ต ์œ ํ‹ธ๋ฆฌํ‹ฐ๋กœ ๋ถ„๋ฆฌ๋จ + - [ ] ์ปดํฌ๋„ŒํŠธ ํฌ๊ธฐ๊ฐ€ 50์ค„ ์ดํ•˜๋กœ ์ค„์–ด๋“ฆ + - [ ] ๋ชจ๋“  ํ•จ์ˆ˜์— ๋ช…ํ™•ํ•œ ํƒ€์ž… ์ •์˜ + - [ ] ์ผ๊ด€๋œ ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜ ์ ์šฉ + - [ ] ๋นŒ๋“œ ๋ฐ ํ…Œ์ŠคํŠธ ํ†ต๊ณผ + + - type: textarea + id: breaking_changes + attributes: + label: โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ + description: ๋ฆฌํŒฉํ† ๋ง ์‹œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์ด๋‚˜ ์˜ํ–ฅ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ ์ค‘์ธ props ๋ณ€๊ฒฝ ๊ธˆ์ง€ + - ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€์˜ ํ˜ธํ™˜์„ฑ ์œ ์ง€ + - ๊ธฐ์กด ์Šคํƒ€์ผ๋ง ๊นจํŠธ๋ฆฌ์ง€ ์•Š๊ธฐ + - ํŠน์ • ๊ธฐ๋Šฅ์˜ ๋™์ž‘ ๋ฐฉ์‹ ์œ ์ง€ + + - type: textarea + id: references + attributes: + label: ๐Ÿ“š ์ฐธ๊ณ  ์ž๋ฃŒ + description: ๋ฆฌํŒฉํ† ๋ง์— ๋„์›€์ด ๋  ์ฐธ๊ณ  ์ž๋ฃŒ๋‚˜ ๊ฐ€์ด๋“œ๋ผ์ธ์ด ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - ์ฝ”๋”ฉ ์ปจ๋ฒค์…˜ ๊ฐ€์ด๋“œ + - ๋””์ž์ธ ํŒจํ„ด ์ฐธ๊ณ  ์ž๋ฃŒ + - ๊ด€๋ จ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ๋‚˜ ๋ฌธ์„œ + - ๋น„์Šทํ•œ ๋ฆฌํŒฉํ† ๋ง ์‚ฌ๋ก€ \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/testing.yml b/.github/ISSUE_TEMPLATE/testing.yml new file mode 100644 index 0000000..7cfacf4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/testing.yml @@ -0,0 +1,175 @@ +name: ๐Ÿงช Claude ํ…Œ์ŠคํŠธ ์ž‘์„ฑ +description: Claude Code์—๊ฒŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. +title: "[TEST] " +labels: ["test", "claude"] +body: + - type: markdown + attributes: + value: | + ## ๐Ÿงช Claude Code ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ์ง€์‹œ์„œ + + Claude Code์—๊ฒŒ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์ด๋‚˜ ํ…Œ์ŠคํŠธ ๊ฐœ์„  ์ž‘์—…์„ ์ง€์‹œํ•˜๊ธฐ ์œ„ํ•œ ํ…œํ”Œ๋ฆฟ์ž…๋‹ˆ๋‹ค. + ํ…Œ์ŠคํŠธํ•  ๋Œ€์ƒ๊ณผ ๋ฒ”์œ„๋ฅผ ๋ช…ํ™•ํžˆ ์ œ์‹œํ•ด์ฃผ์„ธ์š”. + + - type: textarea + id: test_target + attributes: + label: ๐ŸŽฏ ํ…Œ์ŠคํŠธ ๋Œ€์ƒ + description: ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ๋Œ€์ƒ ์ฝ”๋“œ๋ฅผ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - src/app/_components/Navigation.tsx์˜ ๋ฉ”๋‰ด ํ† ๊ธ€ ๊ธฐ๋Šฅ + - src/api/posts.ts์˜ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ fetching ํ•จ์ˆ˜ + - src/app/_lib/utils.ts์˜ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋“ค + - src/app/blog/[slug]/page.tsx์˜ ๋™์  ๋ผ์šฐํŒ… ํŽ˜์ด์ง€ + - ์ „์ฒด ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ๋ Œ๋”๋ง ํ”Œ๋กœ์šฐ + validations: + required: true + + - type: dropdown + id: test_type + attributes: + label: ๐Ÿท๏ธ ํ…Œ์ŠคํŠธ ์œ ํ˜• + description: ์–ด๋–ค ์ข…๋ฅ˜์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ๋‚˜์š”? + options: + - ๋‹จ์œ„ ํ…Œ์ŠคํŠธ (Unit Test) + - ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ (Integration Test) + - ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ (Component Test) + - E2E ํ…Œ์ŠคํŠธ (End-to-End Test) + - ์Šค๋ƒ…์ƒท ํ…Œ์ŠคํŠธ (Snapshot Test) + - ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ (Performance Test) + - ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ (Accessibility Test) + - ๊ธฐํƒ€ + default: 0 + validations: + required: true + + - type: textarea + id: test_scenarios + attributes: + label: ๐Ÿ“ ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค + description: ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•  ๊ตฌ์ฒด์ ์ธ ์‹œ๋‚˜๋ฆฌ์˜ค๋“ค์„ ๋‚˜์—ดํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ์‚ฌ์šฉ์ž๊ฐ€ ํ–„๋ฒ„๊ฑฐ ๋ฉ”๋‰ด๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋„ค๋น„๊ฒŒ์ด์…˜์ด ์—ด๋ฆฌ๋Š”์ง€ ํ™•์ธ + - ์ž˜๋ชป๋œ slug๋กœ ์ ‘๊ทผํ–ˆ์„ ๋•Œ 404 ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธ + - ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํŒŒ์‹ฑ๋˜๋Š”์ง€ ํ™•์ธ + - ๋‹คํฌ๋ชจ๋“œ ํ† ๊ธ€์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธ + - ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ ๋ ˆ์ด์•„์›ƒ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธ + validations: + required: true + + - type: textarea + id: test_cases + attributes: + label: โœ… ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค + description: ๊ฒ€์ฆํ•ด์•ผ ํ•  ๊ตฌ์ฒด์ ์ธ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋“ค์„ ๋ช…์‹œํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - [ ] ์ •์ƒ์ ์ธ ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜ + - [ ] ๋นˆ ๊ฐ’์ด๋‚˜ null ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ์ฒ˜๋ฆฌ + - [ ] ์ž˜๋ชป๋œ ํ˜•์‹์˜ ์ž…๋ ฅ์— ๋Œ€ํ•œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ + - [ ] ๊ฒฝ๊ณ„๊ฐ’ ํ…Œ์ŠคํŠธ (์ตœ๋Œ€/์ตœ์†Œ๊ฐ’) + - [ ] ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์„ฑ๊ณต/์‹คํŒจ ์ฒ˜๋ฆฌ + - [ ] ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์— ๋Œ€ํ•œ ์ ์ ˆํ•œ ๋ฐ˜์‘ + validations: + required: true + + - type: textarea + id: existing_tests + attributes: + label: ๐Ÿ“‹ ๊ธฐ์กด ํ…Œ์ŠคํŠธ ํ˜„ํ™ฉ + description: ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ…Œ์ŠคํŠธ๋‚˜ ํ…Œ์ŠคํŠธ ์„ค์ •์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - Jest ์„ค์ •์ด ์ด๋ฏธ ๋˜์–ด์žˆ์Œ + - React Testing Library ์‚ฌ์šฉ ์ค‘ + - __tests__ ํด๋”์— ์ผ๋ถ€ ํ…Œ์ŠคํŠธ ์กด์žฌ + - package.json์— ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ ์„ค์ •๋จ + - ํŠน์ • ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋ฏธ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ๋จ + + - type: dropdown + id: test_framework + attributes: + label: ๐Ÿ› ๏ธ ์„ ํ˜ธํ•˜๋Š” ํ…Œ์ŠคํŠธ ๋„๊ตฌ + description: ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ๋‚˜ ๋„๊ตฌ๊ฐ€ ์žˆ๋‚˜์š”? + options: + - Jest + React Testing Library + - Vitest + Testing Library + - Cypress (E2E) + - Playwright (E2E) + - Storybook (Component) + - ๊ธฐ์กด ์„ค์ • ์‚ฌ์šฉ + - ์ถ”์ฒœํ•ด์ฃผ์„ธ์š” + default: 0 + validations: + required: true + + - type: textarea + id: test_data + attributes: + label: ๐Ÿ“Š ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ + description: ํ…Œ์ŠคํŠธ์— ํ•„์š”ํ•œ ๋ชฉ ๋ฐ์ดํ„ฐ๋‚˜ ํ”ฝ์Šค์ฒ˜๊ฐ€ ์žˆ๋‹ค๋ฉด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ + - ์‚ฌ์šฉ์ž ์ธ์ฆ ์ •๋ณด ๋ชฉ + - API ์‘๋‹ต ๋ฐ์ดํ„ฐ ๋ชฉ + - ํŒŒ์ผ ์‹œ์Šคํ…œ ๋ชฉ + - ์™ธ๋ถ€ ์„œ๋น„์Šค ์‘๋‹ต ๋ชฉ + + - type: dropdown + id: coverage_goal + attributes: + label: ๐Ÿ“ˆ ์ปค๋ฒ„๋ฆฌ์ง€ ๋ชฉํ‘œ + description: ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€ ๋ชฉํ‘œ๊ฐ€ ์žˆ๋‚˜์š”? + options: + - ๐ŸŸข ๊ธฐ๋ณธ (์ฃผ์š” ๊ธฐ๋Šฅ๋งŒ) + - ๐ŸŸก ๋ณดํ†ต (70-80%) + - ๐Ÿ”ด ๋†’์Œ (90%+) + - ํŠน์ • ๊ธฐ๋Šฅ๋งŒ ์ง‘์ค‘ + - ์ปค๋ฒ„๋ฆฌ์ง€ ์ƒ๊ด€์—†์Œ + default: 1 + validations: + required: true + + - type: textarea + id: test_requirements + attributes: + label: ๐Ÿ“‹ ํ…Œ์ŠคํŠธ ์š”๊ตฌ์‚ฌํ•ญ + description: ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ์‹œ ํŠน๋ณ„ํžˆ ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ์ด ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - ์‹ค์ œ API ํ˜ธ์ถœ ๋Œ€์‹  ๋ชฉ ์‚ฌ์šฉ + - ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ๋งŒ ๋™์ž‘ํ•˜๋Š” ๊ธฐ๋Šฅ ํ…Œ์ŠคํŠธ + - ์ ‘๊ทผ์„ฑ ํ…Œ์ŠคํŠธ ํฌํ•จ + - ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ํฌํ•จ + - ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ ํ…Œ์ŠคํŠธ + - ๋‹ค๊ตญ์–ด ์ง€์› ํ…Œ์ŠคํŠธ + + - type: textarea + id: success_criteria + attributes: + label: ๐ŸŽฏ ์„ฑ๊ณต ์กฐ๊ฑด + description: ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด๋“ค์„ ๋ช…์‹œํ•ด์ฃผ์„ธ์š”. + placeholder: | + ์˜ˆ์‹œ: + - [ ] ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•จ + - [ ] ์ปค๋ฒ„๋ฆฌ์ง€ ๋ชฉํ‘œ ๋‹ฌ์„ฑ + - [ ] CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ž๋™ ์‹คํ–‰ + - [ ] ์ฃผ์š” ๊ธฐ๋Šฅ๋ณ„ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ ์™„๋ฃŒ + - [ ] ์—๋Ÿฌ ์‹œ๋‚˜๋ฆฌ์˜ค ํ…Œ์ŠคํŠธ ํฌํ•จ + - [ ] ์ฝ”๋“œ ๋ฆฌ๋ทฐ ํ†ต๊ณผ + + - type: textarea + id: additional_notes + attributes: + label: ๐Ÿ“ ์ถ”๊ฐ€ ์ •๋ณด + description: ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์— ๋„์›€์ด ๋  ์ถ”๊ฐ€ ์ •๋ณด๋‚˜ ์ฐธ๊ณ ์‚ฌํ•ญ์ด ์žˆ๋‚˜์š”? + placeholder: | + ์˜ˆ์‹œ: + - ๊ด€๋ จ ๋ฌธ์„œ๋‚˜ ๊ฐ€์ด๋“œ ๋งํฌ + - ์ฐธ๊ณ ํ•  ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ + - ํŠน์ • ๋ฒ„๊ทธ๋‚˜ ์ด์Šˆ ํžˆ์Šคํ† ๋ฆฌ + - ์„ฑ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ + - ํŒ€ ๋‚ด ํ…Œ์ŠคํŠธ ์ปจ๋ฒค์…˜ \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..a38b773 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,18 @@ +## Summary + + +## Changes + +- +- +- + +## Test plan +- [ ] ๋กœ์ปฌ ๋นŒ๋“œ ํ…Œ์ŠคํŠธ +- [ ] ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ™•์ธ +- [ ] + +## Screenshots + + +๐Ÿค– Generated with [Claude Code](https://claude.ai/code) \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index dc4eaa2..955756a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,6 +14,120 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co This project uses Biome for formatting and linting. Always run `pnpm biome:check` before committing changes. The project has a pre-commit hook (lefthook) that automatically runs Biome on staged files. +## Git Workflow + +### Branch Strategy +- **Main branch**: `main` - production-ready code +- **Feature branches**: `feature/description` or `feat/short-name` for new features +- **Bug fixes**: `fix/description` or `bugfix/issue-number` for bug fixes +- **Documentation**: `docs/description` for documentation updates + +### Commit Message Convention +Follow conventional commits format for clear, searchable history: + +``` +: + +[optional body] + +๐Ÿค– Generated with [Claude Code](https://claude.ai/code) + +Co-Authored-By: Claude +``` + +**Types:** +- `feat:` - new features +- `fix:` - bug fixes +- `docs:` - documentation updates +- `config:` - configuration changes +- `refactor:` - code refactoring without feature changes +- `chore:` - maintenance tasks, dependency updates + +**Examples:** +- `feat: ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ์ถ”๊ฐ€` +- `fix: ๋ชจ๋ฐ”์ผ์—์„œ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฉ”๋‰ด ๊นจ์ง ์ˆ˜์ •` +- `docs: CLAUDE.md์— Git ์›Œํฌํ”Œ๋กœ์šฐ ๊ฐ€์ด๋“œ ์ถ”๊ฐ€` + +### Pull Request Process +1. Create feature branch from `main` +2. Implement changes with descriptive commits +3. Run `pnpm biome:check` and ensure build passes +4. Create PR with clear title and description +5. Link related issues if applicable +6. Merge after review (if working in team) or directly (if solo) + +### Pre-commit Hooks +The project uses lefthook to automatically run quality checks: +- Biome formatting and linting on staged files +- Prevents commits with linting errors +- Ensures consistent code style across the project + +## Claude Code Workflow Instructions + +**IMPORTANT**: Claude Code must follow this PR-based workflow for ALL development tasks: + +### 1. Before Starting Any Task +```bash +# Ensure you're on main and up to date +git checkout main +git pull origin main + +# Create a new feature branch +git checkout -b / +``` + +### 2. Branch Naming Convention +- `feat/๊ธฐ๋Šฅ๋ช…` - New features (e.g., `feat/search-functionality`) +- `fix/๋ฒ„๊ทธ๋ช…` - Bug fixes (e.g., `fix/mobile-nav-issue`) +- `docs/๋ฌธ์„œ๋ช…` - Documentation updates (e.g., `docs/readme-update`) +- `config/์„ค์ •๋ช…` - Configuration changes (e.g., `config/eslint-setup`) +- `refactor/๋ฆฌํŒฉํ„ฐ๋ช…` - Code refactoring (e.g., `refactor/component-structure`) +- `chore/์ž‘์—…๋ช…` - Maintenance tasks (e.g., `chore/dependency-update`) + +### 3. After Completing Work +```bash +# Stage and commit changes +git add . +git commit -m "conventional commit message" + +# Push to remote +git push -u origin + +# Create PR immediately +gh pr create --title "PR Title" --body "$(cat <<'EOF' +## Summary +- Brief description of changes +- Key implementation details + +## Test plan +- [ ] Checklist item 1 +- [ ] Checklist item 2 + +๐Ÿค– Generated with [Claude Code](https://claude.ai/code) +EOF +)" +``` + +### 4. PR Requirements +- **Always create PRs**: Never commit directly to main +- **Clear titles**: Use conventional commit format in PR titles +- **Detailed descriptions**: Include Summary and Test plan sections +- **Link issues**: Reference related GitHub issues when applicable +- **Quality checks**: Ensure CI passes before requesting review + +### 5. Work Scope Guidelines +- **One logical change per PR**: Keep PRs focused and reviewable +- **Complete features**: Don't leave work in broken state +- **Test your changes**: Run `pnpm biome:check` and `pnpm build` before committing +- **Document breaking changes**: Clearly explain any breaking changes + +### 6. After PR Creation +- Wait for CI checks to pass +- Address any review feedback +- Merge only after approval (if working in team) or when CI is green (if solo) + +**Remember**: This workflow ensures clean git history, proper code review, and CI validation for all changes. + ## Architecture Overview ### Next.js Blog with MDX @@ -24,15 +138,42 @@ This is a Next.js 15 blog application configured for static export with MDX supp - Next.js 15 with App Router - MDX for blog content with rehype-pretty-code syntax highlighting - Tailwind CSS for styling +- shadcn/ui for UI components - TypeScript - Biome for code formatting/linting ### Directory Structure -- `src/app/` - Next.js App Router pages and layouts +All client-side code is organized under `src/app/` following Next.js App Router conventions with a package-like structure: + +- `src/app/` - Next.js App Router root directory + - `_components/` - Global reusable React components (underscore prevents routing) + - `_hooks/` - Global custom React hooks (underscore prevents routing) + - `_fonts/` - Font configurations (underscore prevents routing) + - `_lib/` - Global utility functions and libraries (underscore prevents routing) + - `about/` - About page route + - `_components/` - Components specific to about page only + - `_hooks/` - Hooks specific to about page only + - `page.tsx` - About page component + - `blog/` - Blog routes + - `_components/` - Components specific to blog functionality + - `_hooks/` - Hooks specific to blog functionality + - `[slug]/` - Dynamic blog post pages + - `page.tsx` - Blog index page + - `layout.tsx` - Root layout component + - `page.tsx` - Home page + - `not-found.tsx` - 404 error page + - `globals.css` - Global styles +- `src/api/` - Server-side utilities (outside app directory) + - `posts.ts` - Blog post data fetching utilities - `src/contents/` - MDX blog posts (*.mdx files) -- `src/api/posts.ts` - Blog post data fetching utilities -- `src/app/blog/[slug]/` - Dynamic blog post pages + +**Naming Convention:** +- Use underscore prefix (`_`) for folders that should not be treated as routes by Next.js App Router +- Follow Java package-like structure: components and hooks are organized by their scope + - Global scope: `src/app/_components/`, `src/app/_hooks/` + - Page/Feature scope: `src/app/[route]/_components/`, `src/app/[route]/_hooks/` +- This ensures components and logic are co-located with their usage while maintaining clear boundaries ### Content Management @@ -50,9 +191,21 @@ The app is configured for static export (`output: 'export'` in next.config.ts) a ### Styling - Uses Tailwind CSS with custom configuration +- shadcn/ui components with "new-york" style and stone base color +- CSS variables for theming (light/dark mode support) - Noto Sans KR font for Korean language support - Prose styling for blog content rendering +### UI Components + +This project uses shadcn/ui for consistent, high-quality UI components: +- **Installation**: Use `npx shadcn@latest add ` to add new components +- **Location**: UI components are placed in `src/app/_components/ui/` +- **Style**: Configured with "new-york" style and stone base color +- **Theming**: Full CSS variables support for light/dark themes +- **Icons**: Uses Lucide React for icons +- **Utilities**: `cn()` function in `src/app/_lib/utils.ts` for conditional styling + ### Build Output Static files are generated in the `out/` directory during build. \ No newline at end of file