/** * Centralized pattern detection for keyword matching * * Purpose: Unified keyword matching patterns used across multiple services: * - Tool category detection (tools/index.ts) * - Memory category detection (openai-service.ts) * - Region/tech stack detection (server-agent.ts) */ // ============================================================================ // Tool Category Patterns // ============================================================================ export const DOMAIN_PATTERNS = /도메인|네임서버|whois|dns|tld|등록|\.com|\.net|\.io|\.kr|\.org/i; export const DEPOSIT_PATTERNS = /입금|충전|잔액|계좌|예치금|송금|돈/i; export const SERVER_PATTERNS = /서버|VPS|클라우드|호스팅|인스턴스|linode|vultr|\d+번\s*(?:시작|중지|정지|재시작|리셋|리부팅|삭제|해지)|#\d+\s*(?:시작|중지|정지|재시작|리셋|리부팅|삭제|해지)|reboot/i; export const TROUBLESHOOT_PATTERNS = /문제|에러|오류|안[돼되]|느려|트러블|장애|버그|실패|안\s*됨/i; export const WEATHER_PATTERNS = /날씨|기온|비|눈|맑|흐림|더워|추워/i; export const SEARCH_PATTERNS = /검색|찾아|뭐야|뉴스|최신/i; export const REDDIT_PATTERNS = /레딧|reddit|서브레딧|subreddit/i; export const DDOS_PATTERNS = /ddos|DDoS|공격|트래픽\s*폭주|서비스\s*마비|봇\s*공격|디도스|대역폭\s*공격/i; // ============================================================================ // Memory Category Patterns // ============================================================================ // Company/workplace patterns export const COMPANY_PATTERNS = /(?:에서|에)\s*(?:일해|일하고|근무|다녀)/; // Tech/learning patterns export const TECH_LEARNING_PATTERNS = /(?:공부|개발|작업|배우)/; // Role patterns export const ROLE_PATTERNS = /(?:개발자|엔지니어|디자이너|기획자)/; // Location patterns export const LOCATION_PATTERNS = /(?:에서|에)\s*(?:살아|거주|있어)/; // Server/infrastructure patterns (for memory) export const SERVER_INFRA_PATTERNS = /(?:AWS|GCP|Azure|Vultr|Linode|DigitalOcean|클라우드|가비아|카페24|서버\s*\d|트래픽|DAU|MAU|동시접속|쿠버네티스|k8s|도커|docker|컨테이너)/i; // ============================================================================ // Region Patterns (Korean/English/Japanese) // ============================================================================ export const REGION_PATTERNS = { korea: /한국|서울|korea|seoul|kr\b/i, japan: /일본|도쿄|tokyo|japan|jp\b/i, osaka: /오사카|osaka/i, singapore: /싱가포르|singapore|sg\b/i, us: /미국|us|america|달라스|프리몬트/i, } as const; // ============================================================================ // Tech Stack Patterns // ============================================================================ export const TECH_PATTERNS = { // Databases postgresql: /postgresql|postgres|postgis/i, mysql: /mysql|mariadb/i, mongodb: /mongodb|mongo/i, // Cache/Messaging redis: /redis/i, memcached: /memcached/i, messaging: /kafka|rabbitmq/i, // Runtimes nodejs: /node\.?js|nodejs|express/i, python: /python|django|flask|fastapi/i, java: /java|spring/i, go: /golang|go\s/i, // Platforms wordpress: /wordpress/i, php: /laravel|php/i, // Service Types saas: /saas|b2b|enterprise/i, ecommerce: /ecommerce|쇼핑몰|이커머스/i, game: /게임|game|minecraft|팰월드|palworld/i, streaming: /streaming|스트리밍|video/i, } as const; // ============================================================================ // Pattern Matching Functions // ============================================================================ /** * Check if text matches a given pattern */ export function matchesPattern(text: string, pattern: RegExp): boolean { return pattern.test(text); } /** * Detect tool categories from message text * @returns Array of category names that match */ export function detectToolCategories(text: string): string[] { const categories: string[] = []; if (DOMAIN_PATTERNS.test(text)) categories.push('domain'); if (DEPOSIT_PATTERNS.test(text)) categories.push('deposit'); if (SERVER_PATTERNS.test(text)) categories.push('server'); if (TROUBLESHOOT_PATTERNS.test(text)) categories.push('troubleshoot'); if (DDOS_PATTERNS.test(text)) categories.push('ddos'); if (WEATHER_PATTERNS.test(text)) categories.push('weather'); if (SEARCH_PATTERNS.test(text)) categories.push('search'); if (REDDIT_PATTERNS.test(text)) categories.push('reddit'); return categories; } /** * Detect memory category from message content * @returns Category name or null if no match */ export type MemoryCategory = 'company' | 'tech' | 'role' | 'location' | 'server' | null; export function detectMemoryCategory(content: string): MemoryCategory { // Company/workplace if (COMPANY_PATTERNS.test(content)) { return 'company'; } // Tech/learning if (TECH_LEARNING_PATTERNS.test(content)) { return 'tech'; } // Role if (ROLE_PATTERNS.test(content)) { return 'role'; } // Location if (LOCATION_PATTERNS.test(content)) { return 'location'; } // Server/infrastructure if (SERVER_INFRA_PATTERNS.test(content)) { return 'server'; } return null; } /** * Detect region preference from text * @returns Array of region codes or undefined */ export function detectRegion(text: string): string[] | undefined { const lower = text.toLowerCase(); const regions: string[] = []; if (REGION_PATTERNS.korea.test(lower)) regions.push('seoul'); if (REGION_PATTERNS.japan.test(lower)) regions.push('tokyo'); if (REGION_PATTERNS.osaka.test(lower)) regions.push('osaka'); if (REGION_PATTERNS.singapore.test(lower)) regions.push('singapore'); return regions.length > 0 ? regions : undefined; } /** * Detect tech stack from text * @returns Array of tech stack names */ export function detectTechStack(text: string): string[] { const lower = text.toLowerCase(); const stack: string[] = []; // Databases if (TECH_PATTERNS.postgresql.test(lower)) stack.push('postgresql'); if (TECH_PATTERNS.mysql.test(lower)) stack.push('mysql'); if (TECH_PATTERNS.mongodb.test(lower)) stack.push('mongodb'); // Cache/Messaging if (TECH_PATTERNS.redis.test(lower)) stack.push('redis'); if (TECH_PATTERNS.memcached.test(lower)) stack.push('memcached'); if (TECH_PATTERNS.messaging.test(lower)) stack.push('messaging'); // Runtimes if (TECH_PATTERNS.nodejs.test(lower)) stack.push('nodejs'); if (TECH_PATTERNS.python.test(lower)) stack.push('python'); if (TECH_PATTERNS.java.test(lower)) stack.push('java'); if (TECH_PATTERNS.go.test(lower)) stack.push('go'); // Platforms if (TECH_PATTERNS.wordpress.test(lower)) stack.push('wordpress'); if (TECH_PATTERNS.php.test(lower)) stack.push('php'); // Service Types if (TECH_PATTERNS.saas.test(lower)) stack.push('saas'); if (TECH_PATTERNS.ecommerce.test(lower)) stack.push('ecommerce'); if (TECH_PATTERNS.game.test(lower)) stack.push('game'); if (TECH_PATTERNS.streaming.test(lower)) stack.push('streaming'); return stack; }