feat(phase-5-2): 에러 복구 전략 구현

Phase 5-2 완료: 재시도 로직, 서킷 브레이커, 관리자 알림

생성된 파일:
- src/utils/retry.ts (지수 백오프 재시도)
- src/utils/circuit-breaker.ts (서킷 브레이커 패턴)
- src/services/notification.ts (관리자 알림)
- src/services/__test__/notification.test.ts (테스트 가이드)

수정된 파일:
- src/openai-service.ts (Circuit Breaker + Retry 적용)
- src/tools/search-tool.ts (4개 API 재시도)
- src/tools/domain-tool.ts (11개 API 재시도)
- CLAUDE.md (알림 시스템 문서 추가)

주요 기능:
- 지수 백오프: 1초 → 2초 → 4초 (Jitter ±20%)
- Circuit Breaker: 3회 실패 시 30초 차단 (OpenAI)
- 재시도: 총 15개 외부 API 호출에 적용
- 알림: 3가지 유형 (Circuit Breaker, Retry, API Error)
- Rate Limiting: 같은 알림 1시간 1회

검증:
-  TypeScript 컴파일 성공
-  Wrangler 로컬 빌드 성공
-  프로덕션 배포 완료 (Version: c4a1a8e9)
This commit is contained in:
kappa
2026-01-19 16:30:54 +09:00
parent 9b633ea38b
commit 58d8bbffc6
8 changed files with 1091 additions and 159 deletions

View File

@@ -320,6 +320,85 @@ wrangler d1 execute telegram-conversations --command "SELECT * FROM users LIMIT
---
## Admin Notification System
**목적:** 심각한 시스템 에러 발생 시 관리자에게 실시간 Telegram 알림
**파일:** `src/services/notification.ts`
**알림 유형:**
| 유형 | 트리거 조건 | 심각도 |
|------|------------|--------|
| `circuit_breaker` | Circuit Breaker OPEN 상태 전환 | 🚨 HIGH |
| `retry_exhausted` | 모든 재시도 실패 (3회) | ⚠️ MEDIUM |
| `api_error` | 치명적 API 에러 (5xx, Rate Limit) | 🔴 CRITICAL |
**Rate Limiting:**
- 같은 유형의 알림은 1시간에 1회만 전송
- KV Namespace 사용 (`RATE_LIMIT_KV`)
- 키: `notification:{type}:{service}`
- TTL: 3600초 (1시간)
**사용 예시:**
```typescript
import { notifyAdmin } from './services/notification';
import { sendMessage } from './telegram';
// Circuit Breaker가 OPEN 상태가 되었을 때
await notifyAdmin(
'circuit_breaker',
{
service: 'OpenAI API',
error: 'Connection timeout after 30s',
context: 'User message processing failed'
},
{
telegram: {
sendMessage: (chatId: number, text: string) =>
sendMessage(env.BOT_TOKEN, chatId, text)
},
adminId: env.DEPOSIT_ADMIN_ID || '',
env
}
);
```
**알림 메시지 형식:**
```
🚨 시스템 알림 (Circuit Breaker)
서비스: OpenAI API
에러: Connection timeout
상태: OPEN
시간: 2026-01-19 15:30:45
자동 복구 시도: 30초 후
```
**환경 변수:**
- `DEPOSIT_ADMIN_ID`: 관리자 Telegram Chat ID (wrangler.toml)
**통합 지점:**
- `utils/circuit-breaker.ts`: Circuit 차단 시
- `utils/retry.ts`: 재시도 실패 시
- `openai-service.ts`: OpenAI API 에러 시
- `tools/*.ts`: 외부 API 에러 시
**에러 핸들링:**
- 알림 전송 실패 시 로그만 기록하고 무시
- 메인 로직에 영향 없음
**테스트:**
```bash
# 테스트 엔드포인트를 index.ts에 임시 추가
curl https://your-worker.workers.dev/test-notification
# 로그 확인
npm run tail
```
---
## Architecture
**Message Flow:**
@@ -347,6 +426,7 @@ Telegram Webhook → Security Validation → Command/Message Router
| `summary-service.ts` | 프로필 시스템 | `updateSummary()`, `getConversationContext()` |
| `deposit-agent.ts` | 예치금 함수 (코드 직접 처리) | `executeDepositFunction()` |
| `security.ts` | Webhook 보안, Rate Limiting (KV) | `validateWebhook()`, `checkRateLimit()` |
| `services/notification.ts` | 관리자 알림 (Circuit Breaker, Retry 실패) | `notifyAdmin()` |
| `commands.ts` | 봇 명령어 | `handleCommand()` |
| `telegram.ts` | Telegram API | `sendMessage()`, `sendTypingAction()` |