## 주요 변경사항 ### 신규 기능 - POST /recommend: 기술 스택 기반 인스턴스 추천 API - 아시아 리전 필터링 (Seoul, Tokyo, Osaka, Singapore) - 매칭 점수 알고리즘 (메모리 40%, vCPU 30%, 가격 20%, 스토리지 10%) ### 보안 강화 (Security 9.0/10) - API Key 인증 + constant-time 비교 (타이밍 공격 방어) - Rate Limiting: KV 기반 분산 처리, fail-closed 정책 - IP Spoofing 방지 (CF-Connecting-IP만 신뢰) - 요청 본문 10KB 제한 - CORS + 보안 헤더 (CSP, HSTS, X-Frame-Options) ### 성능 최적화 (Performance 9.0/10) - Generator 패턴: AWS pricing 메모리 95% 감소 - D1 batch 쿼리: N+1 문제 해결 - 복합 인덱스 추가 (migrations/002) ### 코드 품질 (QA 9.0/10) - 127개 테스트 (vitest) - 구조화된 로깅 (민감정보 마스킹) - 상수 중앙화 (constants.ts) - 입력 검증 유틸리티 (utils/validation.ts) ### Vultr 연동 수정 - relay 서버 헤더: Authorization: Bearer → X-API-Key Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
143 lines
4.7 KiB
Markdown
143 lines
4.7 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## ⚠️ MANDATORY: Agent-First Execution Rule
|
||
|
||
**모든 작업 시작 전, 반드시 아래 절차를 따를 것:**
|
||
|
||
1. **작업 유형 파악** → 어떤 종류의 작업인지 분류
|
||
2. **적절한 에이전트 확인** → 아래 테이블에서 매칭되는 에이전트 찾기
|
||
3. **에이전트에게 위임** → Task 도구로 해당 에이전트 실행
|
||
4. **결과 수신 및 통합** → 에이전트 결과를 사용자에게 요약 전달
|
||
|
||
**직접 작업 금지**: 에이전트가 처리할 수 있는 작업은 반드시 에이전트에게 위임할 것.
|
||
|
||
### Agent Routing Table
|
||
|
||
| Task Type | Agent | Persona | Tools | Notes |
|
||
|-----------|-------|---------|-------|-------|
|
||
| 탐색/분석 | `explorer` | domain-specific | Read, Grep, Glob | Read-only |
|
||
| 설계/계획 | `planner` | architect | Read, Grep, Glob | Read-only |
|
||
| 코드 작성/수정 | `coder` | backend/frontend | Read, Write, Edit, Bash | Write access |
|
||
| 코드 리뷰 | `reviewer` | qa/security/performance | Read, Grep, Glob | ×3 병렬 실행 권장 |
|
||
| UI 작업 | `ui-ux` | frontend | Read, Write, Edit | Write access |
|
||
| 복합 작업 | `orchestrator` | - | Task | Sub-agent 조율 |
|
||
|
||
### 병렬 리뷰 패턴 (코드 리뷰 시 필수)
|
||
```
|
||
reviewer + qa-persona ─┐
|
||
reviewer + security-persona ─┼─→ 통합 리포트
|
||
reviewer + performance-persona─┘
|
||
```
|
||
|
||
## Project Overview
|
||
|
||
**Name**: cloud-instances-api
|
||
**Type**: Cloudflare Workers API (TypeScript)
|
||
**Purpose**: Multi-cloud VM instance pricing aggregator for Linode, Vultr, AWS
|
||
**Database**: Cloudflare D1 (SQLite)
|
||
**URL**: https://cloud-instances-api.kappa-d8e.workers.dev
|
||
|
||
## Build Commands
|
||
|
||
```bash
|
||
npm run dev # Local development with hot reload
|
||
npm run test # Run vitest tests
|
||
npm run test:coverage # Coverage report
|
||
npm run deploy # Deploy to Cloudflare Workers
|
||
|
||
# Database
|
||
npm run db:init:remote # Initialize schema on remote
|
||
npm run db:migrate:remote # Run migrations on remote
|
||
```
|
||
|
||
## Architecture
|
||
|
||
```
|
||
HTTP Request
|
||
↓
|
||
src/index.ts (Worker entry)
|
||
├─→ middleware/ (auth, rateLimit, CORS)
|
||
├─→ routes/ (health, instances, sync, recommend)
|
||
│ ↓
|
||
├─→ services/ (query, sync, recommendation, cache)
|
||
│ ↓
|
||
├─→ repositories/ (providers, regions, instances, pricing)
|
||
│ ↓
|
||
└─→ connectors/ (vault, linode, vultr, aws)
|
||
```
|
||
|
||
### Key Layers
|
||
|
||
- **routes/**: HTTP handlers - parse params, call services, format response
|
||
- **middleware/**: Auth (X-API-Key), Rate limiting (KV-based token bucket)
|
||
- **services/**: Business logic - QueryService, SyncOrchestrator, RecommendationService
|
||
- **repositories/**: D1 database access - BaseRepository pattern with RepositoryFactory singleton
|
||
- **connectors/**: External APIs - CloudConnector base class, VaultClient for credentials
|
||
|
||
## API Endpoints
|
||
|
||
| Method | Path | Auth | Rate Limit | Description |
|
||
|--------|------|------|------------|-------------|
|
||
| GET | /health | Optional | - | Health check |
|
||
| GET | /instances | Required | 100/min | Query instances with filters |
|
||
| POST | /sync | Required | 10/min | Trigger provider sync |
|
||
| POST | /recommend | Required | - | Tech stack recommendations |
|
||
|
||
## Environment & Bindings
|
||
|
||
```yaml
|
||
# wrangler.toml
|
||
DB: D1 database (cloud-instances-db)
|
||
RATE_LIMIT_KV: KV namespace for rate limiting
|
||
VAULT_URL: https://vault.anvil.it.com
|
||
API_KEY: (secret) Required for authentication
|
||
```
|
||
|
||
## Cron Triggers
|
||
|
||
- `0 0 * * *` - Daily full sync (00:00 UTC)
|
||
- `0 */6 * * *` - Pricing update (every 6 hours)
|
||
|
||
## Key Patterns
|
||
|
||
1. **Repository Pattern**: BaseRepository<T> with lazy singleton via RepositoryFactory
|
||
2. **Connector Pattern**: CloudConnector base with provider-specific implementations
|
||
3. **Middleware Chain**: CORS → Auth → RateLimit → Route handler
|
||
4. **Structured Logging**: createLogger('[Context]') with LOG_LEVEL env var
|
||
5. **Type Safety**: All types in src/types.ts, Input types auto-derived from entities
|
||
|
||
## Naming Conventions
|
||
|
||
- Functions: camelCase
|
||
- Classes/Types: PascalCase
|
||
- Constants: UPPER_SNAKE_CASE
|
||
- Database: snake_case
|
||
- Private members: _underscore prefix
|
||
|
||
## Testing
|
||
|
||
```bash
|
||
npm run test # All tests
|
||
npm run test -- auth.test.ts # Single file
|
||
```
|
||
|
||
Test files: `src/**/*.test.ts` (94 tests total)
|
||
|
||
## Security
|
||
|
||
- API Key auth with constant-time comparison (SHA-256)
|
||
- Token bucket rate limiting via KV
|
||
- Parameterized queries (no SQL injection)
|
||
- Sensitive data masking in logs
|
||
- Security headers (CSP, HSTS, X-Frame-Options)
|
||
|
||
## Vault Secrets
|
||
|
||
```
|
||
secret/linode → api_token
|
||
secret/vultr → api_key
|
||
secret/aws → aws_access_key_id, aws_secret_access_key
|
||
```
|