# ๐Ÿ›ก๏ธ SCAManager **GitHub pushยทPR ๋งˆ๋‹ค ์ •์  ๋ถ„์„ + Claude AI ๋ฆฌ๋ทฐ โ€” ์ ์ˆ˜ํ™”ยท์•Œ๋ฆผยท๊ฒŒ์ดํŠธ.** [![CI](https://github.com/xzawed/SCAManager/actions/workflows/ci.yml/badge.svg)](https://github.com/xzawed/SCAManager/actions/workflows/ci.yml) [![CodeQL](https://github.com/xzawed/SCAManager/actions/workflows/codeql.yml/badge.svg)](https://github.com/xzawed/SCAManager/actions/workflows/codeql.yml) [![Tests](https://img.shields.io/badge/Tests-9436%2B_total_(9229_unit_%2B_207_integration)-brightgreen?style=flat-square&logo=pytest&logoColor=white)](tests/) [![E2E](https://img.shields.io/badge/E2E-554_in_CI-brightgreen?style=flat-square&logo=playwright&logoColor=white)](e2e/) [![pylint](https://img.shields.io/badge/pylint-9.99%2F10-brightgreen?style=flat-square&logo=python&logoColor=white)](src/) [![FastAPI](https://img.shields.io/badge/FastAPI-0.141-009688?style=flat-square&logo=fastapi&logoColor=white)](https://fastapi.tiangolo.com/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE) [๐Ÿ‡บ๐Ÿ‡ธ English](README.md)
## ์–ด๋–ค ๋„๊ตฌ์ธ๊ฐ€์š”? SCAManager ๋Š” GitHub ์ €์žฅ์†Œ๋ฅผ ์ง€์ผœ๋ด…๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€ ์ปค๋ฐ‹์„ ํ‘ธ์‹œํ•˜๊ฑฐ๋‚˜ Pull Request ๋ฅผ ์—ด๋ฉด, ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ์— ์ •์  ๋ถ„์„๊ธฐ๋ฅผ ๋Œ๋ฆฌ๊ณ  Claude ์—๊ฒŒ diff ๋ฆฌ๋ทฐ๋ฅผ ๋งก๊น๋‹ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ•ฉ์ณ 100์  ๋งŒ์ ์˜ ์ ์ˆ˜ ํ•˜๋‚˜๋กœ ๋งŒ๋“ค๊ณ , ๊ฒฐ๊ณผ๋ฅผ ์•Œ๋ ค ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ์›ํ•˜์‹ ๋‹ค๋ฉด ๊ทธ ์ ์ˆ˜์— ๋”ฐ๋ผ ์ง์ ‘ ํ–‰๋™ํ•˜๊ฒŒ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. PR ์Šน์ธ, ๋ณ€๊ฒฝ ์š”์ฒญ, squash ๋จธ์ง€๊นŒ์ง€ ๋งก๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. **์ง์ ‘ ์šด์˜ํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.** ๊ฐ€์ž…ํ•  ์„œ๋น„์Šค๋„, ๋งŒ๋“ค ๊ณ„์ •๋„ ์—†์Šต๋‹ˆ๋‹ค. ๋…ธํŠธ๋ถ์ด๋“  ์„œ๋ฒ„๋“  ๋ณธ์ธ์˜ Railway ํ”„๋กœ์ ํŠธ๋“  ์›ํ•˜๋Š” ๊ณณ์—์„œ ๋Œ์•„๊ฐ€๋ฉฐ, GitHub ๊ณผ Anthropic ์—๋Š” **๋ณธ์ธ์˜ ์ž๊ฒฉ์ฆ๋ช…**์œผ๋กœ ์ ‘์†ํ•ฉ๋‹ˆ๋‹ค. Claude ์‚ฌ์šฉ๋ฃŒ๋„ ๋ณธ์ธ Anthropic ๊ณ„์ •์— ์ฒญ๊ตฌ๋ฉ๋‹ˆ๋‹ค. **์ด๋Ÿฐ ๋ถ„๊ป˜ ๋งž์Šต๋‹ˆ๋‹ค.** GitHub ์—์„œ PR ์„ ๋ฆฌ๋ทฐํ•˜์‹œ๊ณ , ๋ชจ๋“  PR ์— ์ผ๊ด€๋œ 2์ฐจ ์˜๊ฒฌ์„ ๋ฐ›๊ณ  ์‹ถ์ง€๋งŒ, ๊ทธ๋Ÿฌ์ž๊ณ  ์ฝ”๋“œ๋ฅผ ๋‚จ์˜ ํ˜ธ์ŠคํŒ… ์„œ๋น„์Šค์— ๋„˜๊ธฐ๊ณ  ์‹ถ์ง€๋Š” ์•Š์€ ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค.
![SCAManager ๋Œ€์‹œ๋ณด๋“œ](docs/readme/dashboard.ko.png) 7์ผ์น˜ ์ด๋ ฅ์„ ๋ฏธ๋ฆฌ ๋„ฃ์–ด ๋‘” ๋กœ์ปฌ ์ธ์Šคํ„ด์Šค์ž…๋‹ˆ๋‹ค โ€” ์ฒ˜์Œ ๋„์› ์„ ๋•Œ ๋ณด์ด๋Š” ํ™”๋ฉด์€ ์•„๋‹™๋‹ˆ๋‹ค. AI ๋น„์šฉ ์นด๋“œ๊ฐ€ 0 ์ธ ๊ฒƒ์€ ์‹œ๋“œ ๋ฐ์ดํ„ฐ๊ฐ€ ์‹ค์ œ API ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
## ๋‚ด ์ €์žฅ์†Œ์— ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๋‚˜์š”? ์„ค์น˜ ์ „์— ์ฝ์–ด ๋‘์‹ค ๋งŒํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ €์žฅ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ˆœ๊ฐ„ ์‹œ์ž‘๋˜๋Š” ๋™์ž‘์ด ์žˆ๊ณ , ์ง์ ‘ ์ผœ๊ธฐ ์ „๊นŒ์ง€๋Š” ๊บผ์ ธ ์žˆ๋Š” ๋™์ž‘์ด ์žˆ์Šต๋‹ˆ๋‹ค. | | ๋™์ž‘ | ๊ธฐ๋ณธ๊ฐ’ | |---|---|---| | **๋ถ„์„ยท์ฑ„์ ** | ๋ชจ๋“  ํ‘ธ์‹œ์™€ PR ์„ ๋ถ„์„ํ•ด ์ ์ˆ˜๋ฅผ ๋งค๊น๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ๋Š” ์ €์žฅ๋˜๊ณ  ์›น UI ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. | **์ผœ์ง** | | **AI ๋ฆฌ๋ทฐ** | Claude ๊ฐ€ diff ๋ฅผ ๋ฆฌ๋ทฐํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋ทฐ ํ•œ ๋ฒˆ์ด Claude API ํ˜ธ์ถœ ํ•œ ๋ฒˆ์ด๊ณ  ์š”๊ธˆ์€ ๋ณธ์ธ Anthropic ๊ณ„์ •์— ์ฒญ๊ตฌ๋ฉ๋‹ˆ๋‹ค. API ํ‚ค๊ฐ€ ์—†๊ฑฐ๋‚˜ ๊ธฐ๋Šฅ์„ ๊ป๊ฑฐ๋‚˜ diff ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. | **์ผœ์ง** | | **PR ๋ฆฌ๋ทฐ ์ฝ”๋ฉ˜ํŠธ** | ๋ฆฌ๋ทฐ ๋‚ด์šฉ์„ PR ์ฝ”๋ฉ˜ํŠธ๋กœ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค. | **์ผœ์ง** | | **์•Œ๋ฆผ** | Telegram ยท Discord ยท Slack ยท Email ยท webhook ยท n8n ยท GitHub ์ปค๋ฐ‹ ์ฝ”๋ฉ˜ํŠธ ยท GitHub ์ด์Šˆ. | ๊บผ์ง โ€” ๋‹จ, Telegram ์€ ๋ด‡ ํ† ํฐ๊ณผ chat ID ๊ฐ€ ์žˆ์œผ๋ฉด ๋ฐ”๋กœ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค | | **์Šน์ธ / ๋ณ€๊ฒฝ ์š”์ฒญ** | ์ ์ˆ˜์— ๋”ฐ๋ผ GitHub ์—์„œ ๋Œ€์‹  ํ–‰๋™ํ•ฉ๋‹ˆ๋‹ค. | **๊บผ์ง** | | **Squash ๋จธ์ง€** | ์ ์ˆ˜๊ฐ€ ๊ธฐ์ค€์„ ๋„˜์œผ๋ฉด PR ์„ ๋จธ์ง€ํ•ฉ๋‹ˆ๋‹ค. | **๊บผ์ง** | ๋ถ„์„ยท์ฑ„์ ์€ ํ•ญ์ƒ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ํ•ญ๋ชฉ์€ ์ €์žฅ์†Œ๋งˆ๋‹ค ๋”ฐ๋กœ, ํ•ด๋‹น ์ €์žฅ์†Œ์˜ **โš™๏ธ ์„ค์ •** ํŽ˜์ด์ง€์—์„œ ์ •ํ•ฉ๋‹ˆ๋‹ค. ์„ค์ •๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ, ์ €์žฅ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ๋‘ ๊ฐ€์ง€๊ฐ€ ํ•œ ๋ฒˆ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ์ €์žฅ์†Œ์— **์›นํ›…์ด ์„ค์น˜**๋˜๊ณ , **๋น„๊ณต๊ฐœ ์ €์žฅ์†Œ์— ํ•œํ•ด** ์ž‘์€ `.scamanager/` ๋””๋ ‰ํ„ฐ๋ฆฌ(์„ค์ • ํŒŒ์ผ๊ณผ CLI ํ›… ์Šคํฌ๋ฆฝํŠธ)๊ฐ€ **์ปค๋ฐ‹**๋ฉ๋‹ˆ๋‹ค. ๊ณต๊ฐœ ์ €์žฅ์†Œ์—๋Š” ์ด ์ปค๋ฐ‹์ด ๋“ค์–ด๊ฐ€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ## GitHub ์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ  ๋จผ์ € ์จ ๋ณด๊ธฐ ๋ฌด์—‡์„ ์—ฐ๊ฒฐํ•˜๊ธฐ ์ „์—, ๊ฐ™์€ ๋ถ„์„์„ ์ž‘์—… ํŠธ๋ฆฌ์— ๋Œ€ํ•ด ์ปค๋งจ๋“œ๋ผ์ธ์—์„œ ๋Œ๋ ค ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ์ปฌ ํŒŒ์ผ๋งŒ ์ฝ๊ณ  GitHub ์€ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ```bash cp .env.example .env # ๊ทธ๋ฆฌ๊ณ  SESSION_SECRET ์„ ์ฑ„์›๋‹ˆ๋‹ค โ€” ์•„๋ž˜ ์ฐธ๊ณ  python -m src.cli review --base main # ํŠน์ • ๋ธŒ๋žœ์น˜์™€ ๋น„๊ต python -m src.cli review --staged # ๋˜๋Š” staged ๋ณ€๊ฒฝ๋งŒ python -m src.cli review --no-ai # Claude ํ˜ธ์ถœ ์ƒ๋žต โ€” API ํ‚ค ์—†์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค ``` CLI ๋„ ์„œ๋ฒ„์™€ ๊ฐ™์€ `.env` ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค โ€” ์„ค์ •์ด ์ž„ํฌํŠธ ์‹œ์ ์— ๊ฒ€์ฆ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋Œ์•„๊ฐ€๋Š” DB ๋„, GitHub ์•ฑ๋„, Anthropic ํ‚ค๋„ ํ•„์š” ์—†์ง€๋งŒ, `SESSION_SECRET` ์ด ์—†์œผ๋ฉด `--help` ์กฐ์ฐจ ๊ฒ€์ฆ ์˜ค๋ฅ˜๋กœ ๋ฉˆ์ถฅ๋‹ˆ๋‹ค. Windows ์—์„œ๋Š” `python` ๋Œ€์‹  `py -3` ์„ ์“ฐ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ## ์„œ๋ฒ„ ์‹คํ–‰ํ•˜๊ธฐ ### ๋จผ์ € ์ค€๋น„ํ•  ๊ฒƒ | | | |---|---| | **Python 3.12** | CI ๊ฐ€ ์“ฐ๋Š” ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. ์ƒ์œ„ ๋ฒ„์ „๋„ ๋Œ€๊ฐœ ๋™์ž‘ํ•˜์ง€๋งŒ, ๊ฒ€์ฆ๋œ ๊ฒƒ์€ 3.12 ์ž…๋‹ˆ๋‹ค. | | **Node.js 20** | CSS ๋ฒˆ๋“ค์„ ํ•œ ๋ฒˆ ๋นŒ๋“œํ•  ๋•Œ๋งŒ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. | | **PostgreSQL** | ์ ‘์† ๊ฐ€๋Šฅํ•œ DB ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. SQLite ๋Š” ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ๊ฐ€ ์“ฐ๊ณ , ์•ฑ์€ PostgreSQL ๋กœ ๋Œ๋ฆฌ์„ธ์š”. | | **GitHub OAuth ์•ฑ** | ์›น UI ๋กœ๊ทธ์ธ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์œ„์˜ CLI ๋งŒ ์“ฐ์‹ ๋‹ค๋ฉด ์—†์–ด๋„ ๋ฉ๋‹ˆ๋‹ค. | | **Anthropic API ํ‚ค** | ์„ ํƒ์ด์ง€๋งŒ, ์—†์œผ๋ฉด AI ๋ฆฌ๋ทฐ๊ฐ€ ๋Œ์ง€ ์•Š์•„ ์–ด๋–ค ์ ์ˆ˜๋„ 89์ ์„ ๋„˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. | ### ์„ค์น˜์™€ ์‹คํ–‰ ```bash git clone https://github.com/xzawed/SCAManager.git && cd SCAManager make install # pip install -r requirements-dev.txt + npm install make css-build # Tailwind ๋ฒˆ๋“ค ๋นŒ๋“œ (gitignore ๋Œ€์ƒ์ด๋ผ ํ•œ ๋ฒˆ ๋งŒ๋“ค์–ด ๋‘ก๋‹ˆ๋‹ค) cp .env.example .env make run # uvicorn :8000, ๋ถ€ํŒ… ์‹œ DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹คํ–‰ ``` Windows ์ฒ˜๋Ÿผ `make` ๊ฐ€ ์—†๋Š” ํ™˜๊ฒฝ์ด๋ผ๋ฉด, ์œ„ ํƒ€๊นƒ์€ ๊ฐ๊ฐ ํ•œ๋‘ ์ค„์งœ๋ฆฌ ๋ช…๋ น์ž…๋‹ˆ๋‹ค. [Makefile](Makefile) ์„ ์—ด์–ด ๋„ค ์ค„์„ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰ํ•˜์‹œ๊ณ , `python` ์€ `py -3` ์œผ๋กœ ๋ฐ”๊ฟ” ์ฃผ์„ธ์š”. ### `.env` ์ฑ„์šฐ๊ธฐ `.env.example` ์—๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์„ค์ •์— ๋™์ž‘ํ•˜๋Š” ์˜ˆ์‹œ๊ฐ’์ด ๋“ค์–ด ์žˆ์ง€๋งŒ, **`SESSION_SECRET` ์€ ์ผ๋ถ€๋Ÿฌ ๋น„์›Œ ๋‘์—ˆ๊ณ  ์ฑ„์šฐ๊ธฐ ์ „๊นŒ์ง€๋Š” ์•ฑ์ด ๋œจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค** โ€” ํ”„๋กœ๋•์…˜๋งŒ์ด ์•„๋‹ˆ๋ผ ๋ชจ๋“  ํ™˜๊ฒฝ์—์„œ ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์„ ์ฑ„์šฐ๊ณ  `DATABASE_URL` ์„ ์‹ค์ œ DB ๋กœ ๋ฐ”๊พธ๋ฉด ๋œน๋‹ˆ๋‹ค. - **`SESSION_SECRET`** โ€” `openssl rand -hex 32` ๋กœ ํ•˜๋‚˜ ๋งŒ๋“œ์„ธ์š”. ์„ค์ •ํ•˜๊ธฐ ์ „๊นŒ์ง€๋Š” `SESSION_SECRET must be at least 32 characters long` ์œผ๋กœ ๊ธฐ๋™์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์šฉ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ฒฝ๋กœ๋Š” ์—†์Šต๋‹ˆ๋‹ค. - **`ANTHROPIC_API_KEY`** โ€” ์—†์œผ๋ฉด AI ๋ฆฌ๋ทฐ๊ฐ€ ๋Œ์ง€ ์•Š์•„ ์–ด๋–ค ์ ์ˆ˜๋„ 89์ ์„ ๋„˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. - **`GITHUB_CLIENT_ID` ยท `GITHUB_CLIENT_SECRET`** โ€” GitHub OAuth ์•ฑ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์Šต๋‹ˆ๋‹ค. ์›น UI ๋กœ๊ทธ์ธ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ํ•ญ๋ชฉ์€ [docs/reference/env-vars.md](docs/reference/env-vars.md) ์— ์ •๋ฆฌ๋ผ ์žˆ์Šต๋‹ˆ๋‹ค. ### ์ฒซ ์ €์žฅ์†Œ ๋“ฑ๋กํ•˜๊ธฐ ์„ ์—ด๊ณ  GitHub ์œผ๋กœ ๋กœ๊ทธ์ธํ•œ ๋’ค **+ ๋ฆฌํฌ ์ถ”๊ฐ€**๋ฅผ ์„ ํƒํ•˜์„ธ์š”. ํ•ด๋‹น ์ €์žฅ์†Œ์— ์›นํ›…์ด ์„ค์น˜๋˜๊ณ (๋น„๊ณต๊ฐœ ์ €์žฅ์†Œ๋ผ๋ฉด ์œ„์—์„œ ๋งํ•œ `.scamanager/` ํŒŒ์ผ๋„ ์ปค๋ฐ‹๋ฉ๋‹ˆ๋‹ค), ๊ทธ๋‹ค์Œ ํ‘ธ์‹œ๋ถ€ํ„ฐ ๋ถ„์„์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์ดํ›„์—๋Š” ์ €์žฅ์†Œ์˜ **โš™๏ธ ์„ค์ •** ํŽ˜์ด์ง€์—์„œ ์–ด๋–ค ์•Œ๋ฆผ ์ฑ„๋„์„ ์“ธ์ง€, ๊ฒŒ์ดํŠธ๊ฐ€ GitHub ์—์„œ ๋Œ€์‹  ํ–‰๋™ํ•ด๋„ ๋˜๋Š”์ง€๋ฅผ ์ •ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ## ์ ์ˆ˜๋Š” ์–ด๋–ป๊ฒŒ ๋งค๊ฒจ์ง€๋‚˜์š”? ์ปค๋ฐ‹์€ 100์ ์—์„œ ์ถœ๋ฐœํ•ด ๋‹ค์„ฏ ํ•ญ๋ชฉ์œผ๋กœ ํ‰๊ฐ€๋ฉ๋‹ˆ๋‹ค. | ํ•ญ๋ชฉ | ๋ฐฐ์  | ์ถœ์ฒ˜ | |---|---|---| | ์ฝ”๋“œ ํ’ˆ์งˆ | 25 | ์ •์  ๋ถ„์„๊ธฐ โ€” error ํ•˜๋‚˜๋‹น 3์ , warning ํ•˜๋‚˜๋‹น 1์  ๊ฐ์  | | ๋ณด์•ˆ | 20 | ์ •์  ๋ถ„์„๊ธฐ โ€” HIGH ํ•˜๋‚˜๋‹น 7์ , LOWยทMEDIUM ํ•˜๋‚˜๋‹น 2์  ๊ฐ์  | | ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ | 15 | Claude | | ๊ตฌํ˜„ ๋ฐฉํ–ฅ์„ฑ | 25 | Claude โ€” ๋ณ€๊ฒฝ์ด ํ‘œ๋ฐฉํ•œ ์ผ์„ ์‹ค์ œ๋กœ ํ•˜๋Š”์ง€, ๊ทธ ๋ฐฉ์‹์ด ํƒ€๋‹นํ•œ์ง€ | | ํ…Œ์ŠคํŠธ ์ฝ”๋“œ | 15 | Claude | ๋“ฑ๊ธ‰์€ **A** 90์  ์ด์ƒ ยท **B** 75 ยท **C** 60 ยท **D** 45 ์ด๊ณ , ๊ทธ ์•„๋ž˜๋Š” **F** ์ž…๋‹ˆ๋‹ค. 100์  ์ค‘ 55์ ์„ Claude ๊ฐ€ ๋งก์Šต๋‹ˆ๋‹ค. ์“ธ ๋งŒํ•œ AI ๋ฆฌ๋ทฐ๊ฐ€ ์—†์„ ๋•Œ โ€” API ํ‚ค๊ฐ€ ์—†๊ฑฐ๋‚˜, ๊ธฐ๋Šฅ์„ ๊ป๊ฑฐ๋‚˜, diff ๊ฐ€ ๋น„์—ˆ์„ ๋•Œ โ€” ์ด ์„ธ ํ•ญ๋ชฉ์ด 0์ ์ด ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  55์  ์ค‘ 44์ ์— ํ•ด๋‹นํ•˜๋Š” ๊ณ ์ • ์ค‘๋ฆฝ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ •์  ๋ถ„์„์ด ๋งŒ์ ์ด์–ด๋„ ์ด์ ์€ **89์ **์—์„œ ๋ฉˆ์ถฅ๋‹ˆ๋‹ค. A ๊ฐ€ ์•„๋‹ˆ๋ผ B ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์‹คํ–‰์—๋Š” ยซ๊ฒ€์ฆ๋˜์ง€ ์•Š์Œยป ํ‘œ์‹œ๊ฐ€ ๋‚จ์•„์„œ, AI ๋ฆฌ๋ทฐ๋ฅผ ๊ฑฐ์นœ ์ ์ˆ˜์™€ ๊ตฌ๋ถ„๋ฉ๋‹ˆ๋‹ค. AI ํ˜ธ์ถœ์ด ์‹ค์ œ๋กœ ์‹คํŒจํ–ˆ๋‹ค๋ฉด โ€” API ์˜ค๋ฅ˜์ด๊ฑฐ๋‚˜ ์‘๋‹ต์„ ํŒŒ์‹ฑํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ โ€” ์ ์ˆ˜๋ฅผ ์•„์˜ˆ ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •์  ๋ถ„์„ ์ชฝ๋„ ๊ฐ™์€ ์›์น™์ž…๋‹ˆ๋‹ค. ๋ฐฐํฌ๋ณธ์—๋Š” ๋ถ„์„๊ธฐ 16์ข…์ด ๋ฐ˜๋“œ์‹œ ์„ค์น˜๋˜๋„๋ก ์ •ํ•ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์ค‘ ํ•˜๋‚˜๊ฐ€ ์—†๋Š”๋ฐ ๋งˆ์นจ ์ด๋ฒˆ ๋ณ€๊ฒฝ์˜ ์–ด๋–ค ํŒŒ์ผ์ด ๊ทธ ๋ถ„์„๊ธฐ์˜ ๋Œ€์ƒ์ด๋ผ๋ฉด, ํ•ด๋‹น ๋ถ„์„์„ **๋ฏธ์™„๋ฃŒ(incomplete)** ๋กœ ํ‘œ์‹œํ•˜๊ณ  ๊ฒŒ์ดํŠธ๊ฐ€ ์ž๋™ ์Šน์ธ๊ณผ ์ž๋™ ๋จธ์ง€๋ฅผ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ์ฝ”๋“œ๋ฅผ ์ œ๋Œ€๋กœ ๋ถ„์„ํ•˜์ง€ ๋ชปํ•œ ์‹คํ–‰์ด ์ข‹์€ ์ ์ˆ˜๋ฅผ ๋ฐ›์•„์„œ๋Š” ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์–ธ์–ด ์ง€์› ๋ฒ”์œ„ โ€” AI ๋ฆฌ๋ทฐ 49๊ฐœ, ์ •์  ๋ถ„์„ 27๊ฐœ
Claude ๋Š” **49๊ฐœ ์–ธ์–ด**๋ฅผ ๊ฐ๊ฐ์˜ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋กœ ๋ฆฌ๋ทฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ์ค‘ **27๊ฐœ**๋Š” ์ •์  ๋ถ„์„๊ธฐ๊นŒ์ง€ ๋ถ™์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋“ฑ๋ก๋œ ๋ถ„์„๊ธฐ๋Š” ๋ชจ๋‘ **24์ข…**์ด๊ณ , ๊ทธ์ค‘ **16์ข…**์ด ์œ„์—์„œ ๋งํ•œ ํ•„์ˆ˜ ์„ค์น˜๋ถ„์ž…๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€๋Š” ํ•ด๋‹น ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ `PATH` ์— ์žˆ์„ ๋•Œ๋งŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ์—์„œ `make run` ํ•˜์‹œ๋ฉด 24์ข…์ด ๋ชจ๋‘ ์žˆ์ง€๋Š” ์•Š์„ ํ…๋ฐ, ๊ทธ๋ž˜๋„ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ์„ ํƒ ๋ถ„์„๊ธฐ๊ฐ€ ์—†์œผ๋ฉด ์กฐ์šฉํžˆ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ˆ˜์น˜๋Š” [docs/STATE.md](docs/STATE.md) ์— ์žˆ์Šต๋‹ˆ๋‹ค. ์ •์  ๋ถ„์„์ด ์ง€์›ํ•˜๋Š” ์–ธ์–ด: `c ยท clojure ยท cpp ยท csharp ยท css ยท dart ยท dockerfile ยท elixir ยท go ยท html ยท java ยท javascript ยท kotlin ยท php ยท powershell ยท protobuf ยท python ยท ruby ยท rust ยท scala ยท shell ยท solidity ยท sql ยท swift ยท terraform ยท typescript ยท yaml`
## ๊ฒŒ์ดํŠธ ๊ฒŒ์ดํŠธ๋Š” GitHub ์—์„œ ๋Œ€์‹  ํ–‰๋™ํ•˜๋Š” ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ์ €์žฅ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•œ ์‹œ์ ์—๋Š” ๊บผ์ ธ ์žˆ๊ณ , ์„ค์ • ํŽ˜์ด์ง€์—์„œ ์ง์ ‘ ์ผœ๊ธฐ ์ „๊นŒ์ง€ ๊ทธ๋Œ€๋กœ ๊บผ์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผœ๋ฉด ๊ธฐ๋ณธ๊ฐ’์€ 75์  ์ด์ƒ ์Šน์ธ ยท 50์  ๋ฏธ๋งŒ ๋ณ€๊ฒฝ ์š”์ฒญ ยท 75์  ์ด์ƒ squash ๋จธ์ง€์ž…๋‹ˆ๋‹ค. ์Šน์ธ์—๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. `auto` ๋Š” GitHub ์— ์ฆ‰์‹œ ๋ฐ˜์˜ํ•˜๊ณ , `semi-auto` ๋Š” Telegram ์œผ๋กœ ๋ฒ„ํŠผ์ด ๋‹ฌ๋ฆฐ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด ๋‹ต์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. CI ๊ฐ€ ์•„์ง ๋Œ๊ณ  ์žˆ์–ด GitHub ์ด ๊ฑฐ์ ˆํ•œ ๋จธ์ง€๋Š” ๋ฒ„๋ฆฌ์ง€ ์•Š๊ณ  ํ์— ๋„ฃ์–ด ๋‹ค์‹œ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ์•Œ๋ฆผ ์ฑ„๋„์€ ์„œ๋กœ ๋…๋ฆฝ์ ์ด๋ผ, ์›นํ›… ํ•˜๋‚˜๊ฐ€ ์‹คํŒจํ•˜๊ธฐ ์‹œ์ž‘ํ•ด๋„ ๋‚˜๋จธ์ง€ ์ฑ„๋„์€ ์ •์ƒ์ ์œผ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ## ๋ฐฐํฌ **Railway** โ€” ์ €์žฅ์†Œ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  PostgreSQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ ๋’ค, ์œ„์˜ ๋ณ€์ˆ˜๋“ค๊ณผ ํ•จ๊ป˜ `ANTHROPIC_API_KEY` ยท `APP_BASE_URL` ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด URL ์€ ๋ฐ˜๋“œ์‹œ `https://` ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. `http://` ๋กœ ๋‘๋ฉด OAuth ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ์™€ GitHub ์›นํ›… ์ „๋‹ฌ์ด ๋‘˜ ๋‹ค ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์ ˆ์ฐจ๋Š” [๋Ÿฐ๋ถ](docs/runbooks/railway.md)์— ์žˆ์Šต๋‹ˆ๋‹ค. **๊ทธ ๋ฐ–์˜ ํ™˜๊ฒฝ** โ€” ํ‰๋ฒ”ํ•œ ASGI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค. ```bash uvicorn src.main:app --host 0.0.0.0 --port 8000 --proxy-headers ``` ## ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๋‚˜์š”? ์ง์ ‘ ์šด์˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ด ๊ณง ๋„คํŠธ์›Œํฌ ๋ฐ–์œผ๋กœ ์•„๋ฌด๊ฒƒ๋„ ๋‚˜๊ฐ€์ง€ ์•Š๋Š”๋‹ค๋Š” ๋œป์€ ์•„๋‹™๋‹ˆ๋‹ค. diff ์™€ ์ ์ˆ˜๋Š” ๋‹ค์Œ์œผ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. - **GitHub** โ€” ๋ฆฌ๋ทฐ ์ฝ”๋ฉ˜ํŠธ, ๋น„๊ณต๊ฐœ ์ €์žฅ์†Œ์˜ `.scamanager/` ์ปค๋ฐ‹, ๊ทธ๋ฆฌ๊ณ  ์ผœ ๋‘์‹  ๊ฒฝ์šฐ ์Šน์ธยท๋จธ์ง€ - **๋ณธ์ธ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค** โ€” ์ ์ˆ˜, diff ์—์„œ ๋ฝ‘์•„๋‚ธ ์ง€์ ์‚ฌํ•ญ, AI ๋ฆฌ๋ทฐ ๋ณธ๋ฌธ - **Anthropic** โ€” ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ›๊ธฐ ์œ„ํ•œ diff ์ž์ฒด - **์ผœ ๋‘์‹  ์•Œ๋ฆผ ์ฑ„๋„** โ€” ์ ์ˆ˜ ์š”์•ฝ - **OpenAI** โ€” ์„ ํƒ ๊ธฐ๋Šฅ์ธ 2์ฐจ ๊ฒ€์ฆ๊ธฐ๋ฅผ ์ผœ์‹  ๊ฒฝ์šฐ์—๋งŒ ์ „์ฒด ํ‘œ์™€ ๊ฐ๊ฐ์„ ๋„๋Š” ๋ฐฉ๋ฒ•์€ [SECURITY.md](SECURITY.md#data-egress) ์— ์žˆ์Šต๋‹ˆ๋‹ค. ## ๋ฌธ์„œ [์•„ํ‚คํ…์ฒ˜](docs/architecture.md) ยท [ํ™˜๊ฒฝ๋ณ€์ˆ˜](docs/reference/env-vars.md) ยท [๋Ÿฐ๋ถ](docs/runbooks/) ยท [๊ธฐ์—ฌ ์•ˆ๋‚ด](CONTRIBUTING.md) ยท [ํ˜„์žฌ ์ˆ˜์น˜](docs/STATE.md) ์ทจ์•ฝ์ ์„ ๋ฐœ๊ฒฌํ•˜์…จ๋‹ค๋ฉด ๊ณต๊ฐœ ์ด์Šˆ ๋Œ€์‹  [๋น„๊ณต๊ฐœ advisory](https://github.com/xzawed/SCAManager/security/advisories/new) ๋กœ ์•Œ๋ ค ์ฃผ์„ธ์š”. [MIT](LICENSE) ยฉ xzawed