refactor: 파일 분리 리팩토링 (routes, services, tools, utils)

아키텍처 개선:
- index.ts: 921줄 → 205줄 (77% 감소)
- openai-service.ts: 1,356줄 → 148줄 (89% 감소)

새로운 디렉토리 구조:
- src/routes/ - Webhook, API, Health check 핸들러
  - webhook.ts (287줄)
  - api.ts (318줄)
  - health.ts (14줄)

- src/services/ - 비즈니스 로직
  - bank-sms-parser.ts (143줄)
  - deposit-matcher.ts (88줄)

- src/tools/ - Function Calling 도구 모듈화
  - weather-tool.ts (37줄)
  - search-tool.ts (156줄)
  - domain-tool.ts (725줄)
  - deposit-tool.ts (183줄)
  - utility-tools.ts (60줄)
  - index.ts (104줄) - 도구 레지스트리

- src/utils/ - 유틸리티 함수
  - email-decoder.ts - Quoted-Printable 디코더

타입 에러 수정:
- routes/webhook.ts: text undefined 체크
- summary-service.ts: D1 타입 캐스팅
- summary-service.ts: Workers AI 타입 처리
- n8n-service.ts: Workers AI 타입 + 미사용 변수 제거

빌드 검증:
- TypeScript 타입 체크 통과
- Wrangler dev 로컬 빌드 성공

문서:
- REFACTORING_SUMMARY.md 추가
- ROUTE_ARCHITECTURE.md 추가

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-19 15:36:17 +09:00
parent 3bf42947a7
commit ab6c9a2efa
18 changed files with 2578 additions and 1958 deletions

217
ROUTE_ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,217 @@
# Route Architecture
## Before Refactoring
```
┌─────────────────────────────────────────────────────────────┐
│ index.ts (921 lines) │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ fetch() Handler │ │
│ │ • /setup-webhook │ │
│ │ • /webhook-info │ │
│ │ • /health │ │
│ │ • /api/deposit/balance │ │
│ │ • /api/deposit/deduct │ │
│ │ • /api/test │ │
│ │ • /api/contact │ │
│ │ • /webhook (+ handleMessage + handleCallbackQuery) │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ email() Handler │ │
│ │ • SMS parsing │ │
│ │ • Auto-matching │ │
│ │ • Notifications │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ scheduled() Handler │ │
│ │ • 24h expiration cleanup │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## After Refactoring
```
┌─────────────────────────────────────────────────────────────┐
│ index.ts (205 lines) │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ fetch() Handler (Router) │ │
│ │ • /setup-webhook ──────────┐ │ │
│ │ • /webhook-info ───────────┤ │ │
│ │ • /health ──────────────────┼──→ routes/health.ts │ │
│ │ • /api/* ───────────────────┼──→ routes/api.ts │ │
│ │ • /webhook ─────────────────┴──→ routes/webhook.ts │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ email() Handler (unchanged) │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ scheduled() Handler (unchanged) │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ health.ts │ │ api.ts │ │ webhook.ts │
│ (14 lines) │ │ (318 lines) │ │ (287 lines) │
├──────────────┤ ├──────────────┤ ├──────────────┤
│ • status │ │ • balance │ │ • message │
│ • timestamp │ │ • deduct │ │ • callback │
│ │ │ • test │ │ • rate limit │
│ │ │ • contact │ │ • commands │
└──────────────┘ └──────────────┘ └──────────────┘
```
## Request Flow Examples
### 1. Telegram Message
```
User sends message
Telegram API → /webhook
index.ts:fetch() → routes/webhook.ts:handleWebhook()
validateWebhookRequest() (security check)
handleMessage()
├─ checkRateLimit() (KV-based)
├─ getOrCreateUser() (DB)
├─ handleCommand() OR generateAIResponse()
└─ sendMessage() (Telegram API)
```
### 2. Deposit Balance Inquiry
```
namecheap-api → /api/deposit/balance?telegram_id=123
index.ts:fetch() → routes/api.ts:handleApiRequest()
X-API-Key authentication
DB query (users + user_deposits)
JSON response { telegram_id, balance }
```
### 3. Contact Form Submission
```
Web form → /api/contact (POST)
index.ts:fetch() → routes/api.ts:handleApiRequest()
CORS check (hosting.anvil.it.com)
Validation (email format, message length)
sendMessage() to admin (Telegram notification)
```
### 4. Health Check
```
Monitoring → /health (GET)
index.ts:fetch() → routes/health.ts:handleHealthCheck()
JSON response { status: 'ok', timestamp }
```
## Module Dependencies
```
routes/webhook.ts
├── types.ts (Env, TelegramUpdate)
├── security.ts (validateWebhookRequest, checkRateLimit)
├── telegram.ts (sendMessage, sendMessageWithKeyboard, etc)
├── domain-register.ts (executeDomainRegister)
├── summary-service.ts (addToBuffer, processAndSummarize, generateAIResponse)
└── commands.ts (handleCommand)
routes/api.ts
├── types.ts (Env)
├── telegram.ts (sendMessage)
├── summary-service.ts (addToBuffer, processAndSummarize, generateAIResponse)
└── commands.ts (handleCommand)
routes/health.ts
└── (none - standalone)
index.ts
├── types.ts (Env, EmailMessage)
├── telegram.ts (sendMessage, setWebhook, getWebhookInfo)
├── services/bank-sms-parser.ts (parseBankSMS)
├── services/deposit-matcher.ts (matchPendingDeposit)
├── routes/webhook.ts (handleWebhook)
├── routes/api.ts (handleApiRequest)
└── routes/health.ts (handleHealthCheck)
```
## Code Organization Benefits
### 1. Separation of Concerns
- **webhook.ts**: Telegram-specific logic
- **api.ts**: REST API endpoints
- **health.ts**: Monitoring
- **index.ts**: Routing + email + cron
### 2. Testability
Each route can be tested independently:
```typescript
import { handleHealthCheck } from './routes/health';
const response = await handleHealthCheck();
expect(response.status).toBe(200);
```
### 3. Maintainability
- Smaller files (14-318 lines vs 921 lines)
- Clear responsibilities
- Easier to locate bugs
- Safe to modify without affecting other routes
### 4. Reusability
Route handlers can be:
- Imported by other modules
- Wrapped with middleware
- Tested in isolation
- Deployed independently (future: multiple workers)
## Future Enhancements
### Potential Middleware Layer
```typescript
// src/middleware/auth.ts
export function withAuth(handler: RouteHandler) {
return async (req, env, url) => {
if (!validateAuth(req)) {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
}
return handler(req, env, url);
};
}
// Usage in routes/api.ts
export const handleApiRequest = withAuth(async (req, env, url) => {
// ... existing logic
});
```
### Route Registration Pattern
```typescript
// src/router.ts
const routes = {
'/health': handleHealthCheck,
'/api/*': handleApiRequest,
'/webhook': handleWebhook,
};
// index.ts
const handler = routes[pathname] || notFound;
return handler(request, env, url);
```