Files
cloud-orchestrator/src/index.ts
kappa b682abc45d refactor: modularize codebase and add DB workload multiplier
- Split monolithic index.ts (2370 lines) into modular structure:
  - src/handlers/ for route handlers
  - src/utils.ts for shared utilities
  - src/config.ts for configuration
  - src/types.ts for TypeScript definitions

- Add DB workload multiplier for smarter database resource calculation:
  - Heavy (analytics, logs): 0.3x multiplier
  - Medium-heavy (e-commerce, transactional): 0.5x
  - Medium (API, SaaS): 0.7x
  - Light (blog, portfolio): 1.0x

- Fix tech_specs with realistic vcpu_per_users values (150+ technologies)
- Fix "blog" matching "log" regex bug
- Update documentation to reflect new architecture

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 17:46:16 +09:00

91 lines
2.5 KiB
TypeScript

/**
* Cloudflare Worker - Server Recommendation System Entry Point
*
* AI-powered server recommendation service using Workers AI, D1, and KV.
*/
import type { Env } from './types';
import { getAllowedOrigin, checkRateLimit, jsonResponse } from './utils';
import { handleHealth } from './handlers/health';
import { handleGetServers } from './handlers/servers';
import { handleRecommend } from './handlers/recommend';
/**
* Main request handler
*/
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const requestId = crypto.randomUUID();
try {
const url = new URL(request.url);
const path = url.pathname;
// Rate limiting (except for health checks)
if (path !== '/api/health') {
const clientIP = request.headers.get('CF-Connecting-IP') || 'unknown';
const rateCheck = await checkRateLimit(clientIP, env);
if (!rateCheck.allowed) {
const origin = getAllowedOrigin(request);
return jsonResponse(
{ error: 'Too many requests', request_id: rateCheck.requestId },
429,
{
'Access-Control-Allow-Origin': origin,
'Vary': 'Origin',
}
);
}
}
// CORS headers for all responses
const origin = getAllowedOrigin(request);
const corsHeaders = {
'Access-Control-Allow-Origin': origin,
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
'Vary': 'Origin',
};
// Handle preflight requests
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
// Route handling
if (path === '/api/health') {
return handleHealth(corsHeaders);
}
if (path === '/api/servers' && request.method === 'GET') {
return handleGetServers(request, env, corsHeaders);
}
if (path === '/api/recommend' && request.method === 'POST') {
return handleRecommend(request, env, corsHeaders);
}
return jsonResponse(
{ error: 'Not found', request_id: requestId },
404,
corsHeaders
);
} catch (error) {
console.error('[Worker] Unhandled error:', error);
const origin = getAllowedOrigin(request);
return jsonResponse(
{
error: 'Internal server error',
request_id: requestId,
},
500,
{
'Access-Control-Allow-Origin': origin,
'Vary': 'Origin',
}
);
}
},
};