refactor: code quality improvements (P3)

## Type Safety
- Add zod runtime validation for external API responses
  * Namecheap API responses (domain-register.ts)
  * n8n webhook responses (n8n-service.ts)
  * User request bodies (routes/api.ts)
  * Replaced unsafe type assertions with safeParse()
  * Proper error handling and logging

## Dead Code Removal
- Remove unused callDepositAgent function (127 lines)
  * Legacy Assistants API code no longer needed
  * Now using direct code execution
  * File reduced from 469 → 345 lines (26.4% reduction)

## Configuration Management
- Extract hardcoded URLs to environment variables
  * Added 7 new vars in wrangler.toml:
    OPENAI_API_BASE, NAMECHEAP_API_URL, WHOIS_API_URL,
    CONTEXT7_API_BASE, BRAVE_API_BASE, WTTR_IN_URL, HOSTING_SITE_URL
  * Updated Env interface in types.ts
  * All URLs have fallback to current production values
  * Enables environment-specific configuration (dev/staging/prod)

## Dependencies
- Add zod 4.3.5 for runtime type validation

## Files Modified
- Configuration: wrangler.toml, types.ts, package.json
- Services: 11 TypeScript files with URL/validation updates
- Total: 15 files, +196/-189 lines

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-19 22:06:01 +09:00
parent 4f68dd3ebb
commit 45e0677ab0
15 changed files with 196 additions and 189 deletions

View File

@@ -5,7 +5,10 @@ import { createLogger, maskUserId } from '../utils/logger';
const logger = createLogger('domain-tool');
// Cloudflare AI Gateway를 통해 OpenAI API 호출 (지역 제한 우회)
const OPENAI_API_URL = 'https://gateway.ai.cloudflare.com/v1/d8e5997eb4040f8b489f09095c0f623c/telegram-bot/openai/chat/completions';
function getOpenAIUrl(env: Env): string {
const base = env.OPENAI_API_BASE || 'https://gateway.ai.cloudflare.com/v1/d8e5997eb4040f8b489f09095c0f623c/telegram-bot/openai';
return `${base}/chat/completions`;
}
// KV 캐싱 인터페이스
interface CachedTLDPrice {
@@ -157,7 +160,7 @@ async function callNamecheapApi(
return { error: 'Namecheap API 키가 설정되지 않았습니다.' };
}
const apiKey = env.NAMECHEAP_API_KEY_INTERNAL;
const apiUrl = 'https://namecheap-api.anvil.it.com';
const apiUrl = env.NAMECHEAP_API_URL || 'https://namecheap-api.anvil.it.com';
// 도메인 권한 체크 (쓰기 작업만)
// 읽기 작업(get_domain_info, get_nameservers)은 누구나 조회 가능
@@ -320,7 +323,7 @@ async function callNamecheapApi(
const domain = funcArgs.domain;
try {
const whoisRes = await retryWithBackoff(
() => fetch(`https://whois-api-kappa-inoutercoms-projects.vercel.app/api/whois/${domain}`),
() => fetch(`${env.WHOIS_API_URL || 'https://whois-api-kappa-inoutercoms-projects.vercel.app'}/api/whois/${domain}`),
{ maxRetries: 3 }
);
if (!whoisRes.ok) {
@@ -778,7 +781,7 @@ export async function executeSuggestDomains(args: { keywords: string }, env?: En
}
try {
const namecheapApiUrl = 'https://namecheap-api.anvil.it.com';
const namecheapApiUrl = env.NAMECHEAP_API_URL || 'https://namecheap-api.anvil.it.com';
const TARGET_COUNT = 10;
const MAX_RETRIES = 3;
@@ -793,7 +796,7 @@ export async function executeSuggestDomains(args: { keywords: string }, env?: En
// Step 1: GPT에게 도메인 아이디어 생성 요청
const ideaResponse = await retryWithBackoff(
() => fetch(OPENAI_API_URL, {
() => fetch(getOpenAIUrl(env), {
method: 'POST',
headers: {
'Content-Type': 'application/json',