docs: update documentation for Queue-based server provisioning

- Add Queue creation commands to CLAUDE.md
- Document server-provision-queue and provision-dlq
- Add Server System section with async flow diagram
- Document security improvements (password hashing, retryable flag)
- Update README.md with Queue setup in deployment guide

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-24 22:59:35 +09:00
parent 1fead51eff
commit 13c59fbfb8
2 changed files with 184 additions and 6 deletions

172
CLAUDE.md
View File

@@ -215,6 +215,17 @@ wrangler kv:namespace create RATE_LIMIT_KV
# 출력된 id를 wrangler.toml의 [[kv_namespaces]] 섹션에 입력
```
**Queue 생성 (최초 1회):**
```bash
# 서버 프로비저닝용 Queue 생성
wrangler queues create server-provision-queue
wrangler queues create provision-dlq
# Queue 상태 확인
wrangler queues list
wrangler queues describe server-provision-queue
```
**Secrets 설정:**
```bash
wrangler secret put BOT_TOKEN # Telegram Bot Token
@@ -603,7 +614,7 @@ Telegram Webhook → Security Validation → Command/Message Router
**Core Services:**
| 파일 | 역할 | 주요 함수 |
|------|------|----------|
| `index.ts` | Worker 진입점, Email Handler | `fetch()`, `email()` |
| `index.ts` | Worker 진입점, Email Handler, Queue Handler | `fetch()`, `email()`, `queue()` |
| `openai-service.ts` | AI 응답 + Function Calling | `generateResponse()`, `executeFunctionCall()` |
| `summary-service.ts` | 프로필 시스템 | `updateSummary()`, `getConversationContext()` |
| `deposit-agent.ts` | 예치금 함수 (코드 직접 처리) | `executeDepositFunction()` |
@@ -611,6 +622,9 @@ Telegram Webhook → Security Validation → Command/Message Router
| `services/notification.ts` | 관리자 알림 (Circuit Breaker, Retry 실패) | `notifyAdmin()` |
| `commands.ts` | 봇 명령어 | `handleCommand()` |
| `telegram.ts` | Telegram API | `sendMessage()`, `sendTypingAction()` |
| `queue/provision-consumer.ts` | 서버 생성 Queue Consumer | `handleProvisionQueue()` |
| `queue/provision-dlq.ts` | Dead Letter Queue 핸들러 (환불 처리) | `handleProvisionDLQ()` |
| `server-provision.ts` | 서버 프로비저닝 로직 | `executeServerProvision()` |
**Logging & Monitoring (Phase 5-3):**
| 파일 | 역할 | 주요 기능 |
@@ -661,6 +675,12 @@ end(); // duration 자동 기록
| `server_orders` | 서버 주문 내역 | user_id, provider_id, status, ip_address |
| `user_servers` | 서버 소유권 | user_id, provider_instance_id, verified |
**Queue System (Server Provisioning):**
| Queue | 역할 | Consumer |
|-------|------|----------|
| `server-provision-queue` | 서버 생성 요청 큐 | provision-consumer.ts |
| `provision-dlq` | 실패한 요청 (환불 처리) | provision-dlq.ts |
**AI Fallback:** OpenAI 미설정 시 Workers AI (Llama 3.1 8B) 자동 전환
### 에러 핸들링 구조 (index.ts:handleMessage)
@@ -1290,3 +1310,153 @@ POST /api/deposit/deduct # 잔액 차감
{ telegram_id, amount, reason }
Header: X-API-Key: DEPOSIT_API_SECRET
```
---
## Server System (Queue-based Provisioning)
**아키텍처:** Queue 기반 비동기 처리로 긴 프로비저닝 작업 대응
### Queue 기반 비동기 처리 흐름
```
사용자: "서버 생성해줘"
메인 AI: manage_server(action="order", ...)
1. 잔액 확인 + 차감 (즉시)
2. server_orders 테이블에 status='pending' 저장
3. Queue에 메시지 전송 (SERVER_PROVISION_QUEUE.send())
사용자 응답: "⏳ 서버 생성 요청 접수 (#123)"
┌───────────────────────────────────┐
│ Queue Consumer (비동기 처리) │
│ provision-consumer.ts │
└───────────────────────────────────┘
executeServerProvision():
1. Linode/Vultr API 호출 (5-30초 소요)
2. DB 업데이트: status='completed', ip_address, root_password
3. user_servers 테이블에 소유권 추가
성공 시 → 사용자 알림 (IP, 비밀번호)
실패 시 → 재시도 (최대 3회) → DLQ
```
### 보안 개선사항
**비밀번호 보안:**
```typescript
// ❌ 이전: 평문 저장 (보안 취약)
root_password: string
// ✅ 현재: 해시 저장 + 일회성 전송
root_password_hash: string // DB 저장용 (bcrypt)
root_password: string // Queue 메시지에만 포함 (사용자 알림 후 파기)
```
**Queue 메시지 구조:**
```typescript
interface ProvisionMessage {
order_id: number;
user_id: number;
telegram_user_id: number;
chat_id: number;
}
```
### Retry & DLQ 정책
**재시도 정책 (wrangler.toml):**
```toml
[[queues.consumers]]
queue = "server-provision-queue"
max_retries = 3 # 최대 3회 재시도
max_batch_size = 1 # 순차 처리
max_batch_timeout = 30 # 30초 타임아웃
max_concurrency = 3 # 최대 3개 동시 처리
dead_letter_queue = "provision-dlq"
```
**retryable 플래그:**
```typescript
// provision-consumer.ts에서 활용
if (result.retryable === false) {
// 재시도하면 안 되는 경우 (예: 잘못된 파라미터)
message.ack(); // DLQ로 보내지 않고 종료
} else {
// 일시적 오류 - 재시도 (max 3회 → DLQ)
message.retry();
}
```
**DLQ 처리 (provision-dlq.ts):**
```
1. DB 상태 업데이트: status='failed'
2. 잔액 환불 처리 (이미 차감된 경우)
- user_deposits.balance 복원
- deposit_transactions에 'refund' 거래 추가
3. 사용자 알림 (환불 정보 포함)
4. 관리자 알림 (notifyAdmin)
5. DLQ에서 제거 (ack) - 무한 루프 방지
```
### 관련 파일
| 파일 | 역할 |
|------|------|
| `queue/provision-consumer.ts` | Queue Consumer (서버 생성 실행) |
| `queue/provision-dlq.ts` | DLQ 핸들러 (환불 처리) |
| `server-provision.ts` | 실제 프로비저닝 로직 (Linode/Vultr API 호출) |
| `index.ts:queue()` | Queue 메시지 라우팅 |
### manage_server 도구 파라미터
```typescript
{
action: 'list' | 'search' | 'order' | 'info' | 'recommend',
provider?: 'linode' | 'vultr',
plan?: string,
region?: string,
...
}
```
### 사용자 알림 메시지 예시
**성공:**
```
🎉 서버 생성 완료!
주문번호: #123
📋 서버 정보
• 사양: Linode 2GB
• 리전: Tokyo 2
• IP 주소: 203.0.113.5
• 인스턴스 ID: 12345678
🔐 접속 정보
• Root 비밀번호: [REDACTED]
📌 SSH 접속 명령어
ssh root@203.0.113.5
⚠️ 보안 안내
• 비밀번호는 이 메시지에서만 확인 가능합니다.
• 접속 후 즉시 변경해주세요.
```
**실패 (DLQ):**
```
❌ 서버 생성 실패
주문번호: #123
일시적인 문제로 서버를 생성할 수 없습니다.
✅ 결제 금액이 환불되었습니다.
관리자가 확인 후 연락드리겠습니다.
```