From 13c59fbfb82b9ff0ba54478ea36567a96691987c Mon Sep 17 00:00:00 2001 From: kappa Date: Sat, 24 Jan 2026 22:59:35 +0900 Subject: [PATCH] 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 --- CLAUDE.md | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++- README.md | 18 ++++-- 2 files changed, 184 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 152071b..4fa5829 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 + +일시적인 문제로 서버를 생성할 수 없습니다. + +✅ 결제 금액이 환불되었습니다. + +관리자가 확인 후 연락드리겠습니다. +``` diff --git a/README.md b/README.md index 08d3351..66e8065 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ * 🛠 **Function Calling**: 날씨, 검색, 계산, 시간 등 다양한 도구를 자연어로 호출 * 💰 **예치금 시스템**: 은행 SMS 자동 파싱(AI 폴백 지원) 및 양방향 매칭을 통한 자동 충전 * 🌐 **도메인 관리**: 도메인 검색, 추천(AI), 가격 조회, 등록, DNS 관리 통합 -* 🖥️ **서버 관리**: Linode/Vultr 인스턴스 검색, 비교, 주문, 소유권 관리 -* ⚡ **서버리스**: Cloudflare Workers 위에서 동작하여 별도의 서버 관리 불필요 +* 🖥️ **서버 관리 (Queue 기반)**: Linode/Vultr 인스턴스 검색, 비교, 주문, 비동기 프로비저닝 +* ⚡ **서버리스**: Cloudflare Workers + Queues로 긴 작업도 안정적 처리 ### 🚀 성능 최적화 @@ -59,7 +59,14 @@ npx wrangler kv:namespace create RATE_LIMIT_KV # 출력된 id를 wrangler.toml의 [[kv_namespaces]] 섹션에 입력 ``` -### 4. 환경변수 설정 +### 4. Queue 생성 +```bash +# 서버 프로비저닝용 Queue 생성 (서버 기능 사용 시 필수) +npx wrangler queues create server-provision-queue +npx wrangler queues create provision-dlq +``` + +### 5. 환경변수 설정 #### 필수 Secrets @@ -111,7 +118,7 @@ NAMECHEAP_API_URL = "https://your-api.example.com" - `WTTR_IN_URL` - 날씨 API - `HOSTING_SITE_URL` - 공식 웹사이트 -### 5. 배포 +### 6. 배포 #### 배포 전 체크리스트 @@ -148,7 +155,7 @@ curl "https://telegram-summary-bot.kappa-d8e.workers.dev/webhook-info?token=${BO npm run tail ``` -### 6. Webhook 연결 +### 7. Webhook 연결 ```bash # 웹훅 설정 (token + secret 필요) @@ -159,6 +166,7 @@ curl "https:///setup-webhook?token=${BOT_TOKEN}&secret=${WEBHOO - **WEBHOOK_SECRET 필수**: 미설정 시 모든 webhook 요청이 거부됩니다. - **KV Namespace 필수**: 미생성 시 Rate Limiting이 비활성화되어 DoS 공격에 취약합니다. +- **Queue 필수 (서버 기능 사용 시)**: 미생성 시 서버 프로비저닝 기능이 동작하지 않습니다. - **환경변수 기본값**: 대부분의 외부 API URL은 기본값이 설정되어 있습니다. 프로덕션 환경에서는 기본값을 그대로 사용하거나, 필요시에만 override하세요. ---