Files
telegram-bot-workers/CLAUDE.md
kappa cd33a7c790 docs: CLAUDE.md 전면 개선
- Auto-Read: 세션 시작 시 README.md 필수 읽기
- Critical Rules: 배포/보안/위험 작업 규칙 추가
- Documentation Rules: 트리거 조건 테이블화
- Code Style: TypeScript, 에러 핸들링, 로깅, 네이밍 규칙
- Testing: 로컬 테스트 절차, 배포 후 확인
- Troubleshooting: 자주 발생하는 에러 6개 + 해결법
- 기존 섹션 테이블 형식으로 가독성 개선

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 15:22:57 +09:00

11 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Auto-Read on Start

세션 시작 시 반드시 수행:

  1. README.md를 Read 도구로 읽어 프로젝트 전체 구조 파악
  2. 작업 대상 파일의 기존 코드 먼저 확인
필수 읽기: README.md → 작업 대상 파일

Critical Rules

절대 지켜야 할 규칙:

규칙 이유
배포 전 npm run dev 로컬 테스트 프로덕션 장애 방지
D1 스키마 변경 시 마이그레이션 SQL 별도 작성 기존 데이터 보존
Secrets(BOT_TOKEN, API_KEY 등) 코드에 하드코딩 금지 보안
wrangler.toml의 ID 값 변경 금지 리소스 연결 유지
Function Calling 도구 추가 시 tools 배열 + executeFunctionCall() 동시 수정 불일치 방지

위험한 작업:

  • wrangler d1 execute 직접 실행 (production) → 반드시 확인 요청
  • user_deposits, deposit_transactions 테이블 직접 수정 → 금전 관련, 주의

Documentation Rules

작업 완료 후 문서 자동 업데이트:

트리거 조건

변경 유형 업데이트 대상
src/*.ts 파일 수정 CLAUDE.md (Core Services, Key Patterns)
새 Function Calling 도구 추가 양쪽 (README: 지원 기능 테이블, CLAUDE: tools 목록)
schema.sql 변경 양쪽 (Data Layer 섹션)
wrangler.toml 환경변수 추가 양쪽 (Configuration 섹션)
외부 API 연동 추가/변경 양쪽 (External Integrations)
봇 명령어 추가 양쪽 (Commands 섹션)

업데이트 체크리스트

[ ] CLAUDE.md - 기술 상세 (개발자용)
[ ] README.md - 사용자 가이드 (배포/운영자용)
[ ] 다이어그램/플로우 수정 필요 여부
[ ] wrangler.toml 주석 업데이트

Commands

npm run dev           # 로컬 개발 (wrangler dev)
npm run deploy        # Cloudflare Workers 배포
npm run db:init       # D1 스키마 초기화 (production) ⚠️ 주의
npm run db:init:local # D1 스키마 초기화 (local)
npm run tail          # Workers 로그 스트리밍

Secrets 설정:

wrangler secret put BOT_TOKEN        # Telegram Bot Token
wrangler secret put WEBHOOK_SECRET   # Webhook 검증용
wrangler secret put OPENAI_API_KEY   # OpenAI API 키

Webhook 설정:

curl https://telegram-summary-bot.kappa-d8e.workers.dev/setup-webhook
curl https://telegram-summary-bot.kappa-d8e.workers.dev/webhook-info

Code Style & Conventions

TypeScript

  • Strict mode: tsconfig.json에서 strict 활성화
  • 타입 정의: types.ts에 인터페이스 집중 관리
  • any 사용 금지: 불가피한 경우 주석으로 이유 명시

에러 핸들링

// 패턴: try-catch + 사용자 친화적 메시지
try {
  // 작업
} catch (error) {
  console.error('[ServiceName] 작업 실패:', error);
  return '죄송합니다. 일시적인 오류가 발생했습니다.';
}

로깅 규칙

console.log('[ServiceName] 동작 설명');      // 정상 동작
console.error('[ServiceName] 에러 설명:', error);  // 에러
// wrangler tail로 확인 가능

네이밍

  • 파일: kebab-case.ts (예: openai-service.ts)
  • 함수: camelCase (예: executeFunctionCall)
  • 상수: UPPER_SNAKE_CASE (예: SUMMARY_THRESHOLD)
  • 타입/인터페이스: PascalCase (예: TelegramUpdate)

Testing

현재 테스트 스크립트 없음 - 수동 테스트 필수

로컬 테스트 절차

# 1. 로컬 D1 초기화 (최초 1회)
npm run db:init:local

# 2. 로컬 서버 실행
npm run dev

# 3. 다른 터미널에서 테스트 요청
curl -X POST http://localhost:8787/webhook \
  -H "Content-Type: application/json" \
  -H "X-Telegram-Bot-Api-Secret-Token: test-secret" \
  -d '{"message":{"chat":{"id":123},"text":"테스트"}}'

배포 후 확인

# 로그 스트리밍
npm run tail

# Webhook 상태 확인
curl https://telegram-summary-bot.kappa-d8e.workers.dev/webhook-info

Troubleshooting

자주 발생하는 에러

증상 원인 해결
D1_ERROR: no such table 스키마 미적용 npm run db:init 실행
401 Unauthorized (OpenAI) API 키 만료/잘못됨 wrangler secret put OPENAI_API_KEY
Webhook 응답 없음 Secret Token 불일치 WEBHOOK_SECRET 재설정 후 /setup-webhook
Function Calling 무한 루프 tool_choice 설정 오류 tool_choice: "auto" 확인
프로필 업데이트 안됨 메시지 20개 미만 /context로 버퍼 수 확인
Email Worker 파싱 실패 SMS 형식 변경 index.ts의 정규식 패턴 확인

디버깅 명령어

# D1 데이터 직접 조회 (로컬)
wrangler d1 execute telegram-conversations --local --command "SELECT * FROM users LIMIT 5"

# D1 데이터 직접 조회 (production) ⚠️ 주의
wrangler d1 execute telegram-conversations --command "SELECT * FROM users LIMIT 5"

Architecture

Message Flow:

Telegram Webhook → Security Validation → Command/Message Router
                                              ↓
                   ┌──────────────────────────┴──────────────────────────┐
                   ↓                                                      ↓
            Command Handler                                    AI Response Generator
            (commands.ts)                                      (openai-service.ts)
                                                                      ↓
                                                              Function Calling
                                                    (weather, search, time, calc, docs)
                                                                      ↓
                                                              Profile System
                                                            (summary-service.ts)

Core Services:

파일 역할 주요 함수
index.ts Worker 진입점, Email Handler fetch(), email()
openai-service.ts AI 응답 + Function Calling generateResponse(), executeFunctionCall()
summary-service.ts 프로필 시스템 updateSummary(), getConversationContext()
security.ts Webhook 보안 validateWebhook(), checkRateLimit()
commands.ts 봇 명령어 handleCommand()
telegram.ts Telegram API sendMessage(), sendTypingAction()

Function Calling Tools (7개):

도구 함수명 외부 API
날씨 get_weather wttr.in
검색 web_search DuckDuckGo
시간 get_current_time 내장
계산 calculate 내장
문서 lookup_docs Context7
도메인 manage_domain Domain Agent → Namecheap
예치금 manage_deposit D1

Data Layer (D1 SQLite):

테이블 용도 주요 컬럼
users 사용자 telegram_id, username
message_buffer 대화 기록 user_id, role, content
summaries 프로필 user_id, generation, summary
user_deposits 예치금 계정 user_id, balance
deposit_transactions 거래 내역 user_id, amount, status
bank_notifications SMS 파싱 depositor_name, amount, bank

AI Fallback: OpenAI 미설정 시 Workers AI (Llama 3.1 8B) 자동 전환


Key Patterns

Function Calling 추가 방법

// 1. openai-service.ts의 tools 배열에 추가
const tools = [
  // ... 기존 도구들
  {
    type: "function",
    function: {
      name: "new_tool",
      description: "도구 설명",
      parameters: { /* JSON Schema */ }
    }
  }
];

// 2. executeFunctionCall()에 케이스 추가
case 'new_tool':
  return await executeNewTool(args);

프로필 시스템 흐름

메시지 수신 → message_buffer 저장 (최대 19개)
                    ↓ 20개 도달
            사용자 발언만 추출 → OpenAI 분석
                    ↓
            summaries 테이블 저장 (generation++)
                    ↓
            구버전 삭제 (최근 3개만 유지)

Context Enrichment

// getConversationContext() 반환값 구조
{
  profile: "이전 프로필 요약",
  recentMessages: [ /* 최근 10개 */ ]
}
// → AI 프롬프트의 system 메시지에 포함

Configuration

wrangler.toml 환경변수:

변수 기본값 설명
SUMMARY_THRESHOLD 20 프로필 업데이트 주기 (메시지 수)
MAX_SUMMARIES_PER_USER 3 유지할 프로필 버전 수
DOMAIN_AGENT_ID - OpenAI Assistant ID
DOMAIN_OWNER_ID - 도메인 관리 권한 Telegram ID
DEPOSIT_ADMIN_ID - 예치금 관리 권한 Telegram ID

External Integrations

서비스 용도 엔드포인트 주의사항
Context7 문서 조회 context7.com API -
Domain Agent 도메인 관리 OpenAI Assistants asst_MzPFKoqt7V4w6bc0UwcXU4ob
Namecheap API 도메인 백엔드 namecheap-api.anvil.it.com 날짜: MM/DD/YYYY → ISO 변환
WHOIS API WHOIS 조회 whois-api-eight.vercel.app ccSLD 미지원
wttr.in 날씨 wttr.in -
DuckDuckGo 검색 api.duckduckgo.com -
Vault API 키 관리 vault.anvil.it.com -

Deposit System

자동 매칭 흐름:

[시나리오 1: 사용자 먼저]
"홍길동 50000원 입금" → bank_notifications 검색
                              ↓
              매칭 O → confirmed | 매칭 X → pending

[시나리오 2: SMS 먼저]
은행 SMS → Email Worker → 파싱 → bank_notifications 저장
                                       ↓
                         deposit_transactions 검색 (pending)
                                       ↓
                         매칭 O → confirmed + 잔액↑ | 매칭 X → 저장만

입금 계좌: 하나은행 427-910018-27104 (주식회사 아이언클래드)

  • Vault 경로: secret/companies/ironclad-corp

Domain System

도구 목록:

도구 권한 설명
list_domains 소유자 도메인 목록
get_domain_info 소유자 상세 정보 (만료일 등)
get_nameservers 공개 네임서버 조회
set_nameservers 소유자 네임서버 변경
get_price 공개 TLD 가격 (원화)
check_domains 공개 가용성 확인
whois_lookup 공개 WHOIS 조회

가격 정책: Namecheap 원가 + 13%, 매일 환율 업데이트

권한 체크: user_domains 테이블 verified=1