refactor: remove ServerSession types from types.ts
Removed: - ServerSessionStatus type - ServerSession interface - Recommendation-related fields from ManageServerArgs (tech_stack, expected_users, use_case, etc.) - Updated ManageServerArgs actions to server management only (order, start, stop, reboot, delete, list, info, images, rename) Commented out (temporary): - ServerSessionManager class in session-manager.ts - Server consultation session cleanup code in server-tool.ts (2 locations) - Server order confirmation handler in api/chat.ts These commented sections will be fully removed in subsequent commits when server-agent and related code are removed. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -319,126 +319,127 @@ async function handleChatApi(request: Request, env: Env): Promise<Response> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 서버 신청 확인 처리 (텍스트 기반) - Queue 기반
|
// NOTE: Server order confirmation removed (recommendation feature deprecated)
|
||||||
if (body.message.trim() === '신청') {
|
// This entire block was for processing server orders based on recommendation sessions
|
||||||
const orderSessionKey = `server_order_confirm:${telegramUserId}`;
|
// if (body.message.trim() === '신청') {
|
||||||
logger.info('신청 세션 확인', { orderSessionKey, telegramUserId });
|
// const orderSessionKey = `server_order_confirm:${telegramUserId}`;
|
||||||
const orderSessionData = await env.SESSION_KV.get(orderSessionKey);
|
// logger.info('신청 세션 확인', { orderSessionKey, telegramUserId });
|
||||||
logger.info('신청 세션 데이터', { found: !!orderSessionData, data: orderSessionData?.slice(0, 100) });
|
// const orderSessionData = await env.SESSION_KV.get(orderSessionKey);
|
||||||
|
// logger.info('신청 세션 데이터', { found: !!orderSessionData, data: orderSessionData?.slice(0, 100) });
|
||||||
if (orderSessionData) {
|
//
|
||||||
try {
|
// if (orderSessionData) {
|
||||||
const orderData = JSON.parse(orderSessionData);
|
// try {
|
||||||
|
// const orderData = JSON.parse(orderSessionData);
|
||||||
// 1. 서버 세션에서 가격 정보 가져오기
|
//
|
||||||
const { ServerSessionManager } = await import('../../utils/session-manager');
|
// // 1. 서버 세션에서 가격 정보 가져오기
|
||||||
const { getSessionConfig } = await import('../../constants/agent-config');
|
// const { ServerSessionManager } = await import('../../utils/session-manager');
|
||||||
const sessionManager = new ServerSessionManager(getSessionConfig('server'));
|
// const { getSessionConfig } = await import('../../constants/agent-config');
|
||||||
const session = await sessionManager.get(env.DB, telegramUserId);
|
// const sessionManager = new ServerSessionManager(getSessionConfig('server'));
|
||||||
|
// const session = await sessionManager.get(env.DB, telegramUserId);
|
||||||
if (!session || !session.last_recommendation) {
|
//
|
||||||
await env.SESSION_KV.delete(orderSessionKey);
|
// if (!session || !session.last_recommendation) {
|
||||||
const processingTimeMs = Date.now() - startTime;
|
// await env.SESSION_KV.delete(orderSessionKey);
|
||||||
|
// const processingTimeMs = Date.now() - startTime;
|
||||||
return Response.json({
|
//
|
||||||
success: true,
|
// return Response.json({
|
||||||
response: '❌ 세션이 만료되었습니다.\n다시 "서버 추천"을 시작해주세요.',
|
// success: true,
|
||||||
processing_time_ms: processingTimeMs,
|
// response: '❌ 세션이 만료되었습니다.\n다시 "서버 추천"을 시작해주세요.',
|
||||||
});
|
// processing_time_ms: processingTimeMs,
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
const selected = session.last_recommendation.recommendations[orderData.index];
|
//
|
||||||
if (!selected) {
|
// const selected = session.last_recommendation.recommendations[orderData.index];
|
||||||
await env.SESSION_KV.delete(orderSessionKey);
|
// if (!selected) {
|
||||||
await sessionManager.delete(env.DB, telegramUserId);
|
// await env.SESSION_KV.delete(orderSessionKey);
|
||||||
const processingTimeMs = Date.now() - startTime;
|
// await sessionManager.delete(env.DB, telegramUserId);
|
||||||
|
// const processingTimeMs = Date.now() - startTime;
|
||||||
return Response.json({
|
//
|
||||||
success: true,
|
// return Response.json({
|
||||||
response: '❌ 선택한 서버를 찾을 수 없습니다.',
|
// success: true,
|
||||||
processing_time_ms: processingTimeMs,
|
// response: '❌ 선택한 서버를 찾을 수 없습니다.',
|
||||||
});
|
// processing_time_ms: processingTimeMs,
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
const price = selected.price?.monthly_krw || 0;
|
//
|
||||||
|
// const price = selected.price?.monthly_krw || 0;
|
||||||
// 2. 잔액 확인
|
//
|
||||||
const deposit = await env.DB.prepare(
|
// // 2. 잔액 확인
|
||||||
'SELECT balance FROM user_deposits WHERE user_id = ?'
|
// const deposit = await env.DB.prepare(
|
||||||
).bind(userId).first<{ balance: number }>();
|
// 'SELECT balance FROM user_deposits WHERE user_id = ?'
|
||||||
|
// ).bind(userId).first<{ balance: number }>();
|
||||||
if (!deposit || deposit.balance < price) {
|
//
|
||||||
const processingTimeMs = Date.now() - startTime;
|
// if (!deposit || deposit.balance < price) {
|
||||||
|
// const processingTimeMs = Date.now() - startTime;
|
||||||
return Response.json({
|
//
|
||||||
success: true,
|
// return Response.json({
|
||||||
response:
|
// success: true,
|
||||||
`❌ 잔액이 부족합니다.\n\n` +
|
// response:
|
||||||
`• 서버 가격: ${price.toLocaleString()}원/월\n` +
|
// `❌ 잔액이 부족합니다.\n\n` +
|
||||||
`• 현재 잔액: ${(deposit?.balance || 0).toLocaleString()}원\n` +
|
// `• 서버 가격: ${price.toLocaleString()}원/월\n` +
|
||||||
`• 부족 금액: ${(price - (deposit?.balance || 0)).toLocaleString()}원\n\n` +
|
// `• 현재 잔액: ${(deposit?.balance || 0).toLocaleString()}원\n` +
|
||||||
`잔액을 충전 후 다시 시도해주세요.`,
|
// `• 부족 금액: ${(price - (deposit?.balance || 0)).toLocaleString()}원\n\n` +
|
||||||
processing_time_ms: processingTimeMs,
|
// `잔액을 충전 후 다시 시도해주세요.`,
|
||||||
});
|
// processing_time_ms: processingTimeMs,
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
// 3. Queue 확인
|
//
|
||||||
if (!env.SERVER_PROVISION_QUEUE) {
|
// // 3. Queue 확인
|
||||||
const processingTimeMs = Date.now() - startTime;
|
// if (!env.SERVER_PROVISION_QUEUE) {
|
||||||
|
// const processingTimeMs = Date.now() - startTime;
|
||||||
return Response.json({
|
//
|
||||||
success: true,
|
// return Response.json({
|
||||||
response: '❌ 서버 프로비저닝 시스템이 준비되지 않았습니다.',
|
// success: true,
|
||||||
processing_time_ms: processingTimeMs,
|
// response: '❌ 서버 프로비저닝 시스템이 준비되지 않았습니다.',
|
||||||
});
|
// processing_time_ms: processingTimeMs,
|
||||||
}
|
// });
|
||||||
|
// }
|
||||||
// 4. 주문 생성 및 Queue 전송
|
//
|
||||||
const { createServerOrder, sendProvisionMessage } = await import('../../server-provision');
|
// // 4. 주문 생성 및 Queue 전송
|
||||||
|
// const { createServerOrder, sendProvisionMessage } = await import('../../server-provision');
|
||||||
const orderId = await createServerOrder(
|
//
|
||||||
env.DB,
|
// const orderId = await createServerOrder(
|
||||||
userId,
|
// env.DB,
|
||||||
telegramUserId,
|
// userId,
|
||||||
selected.pricing_id,
|
// telegramUserId,
|
||||||
selected.region.code,
|
// selected.pricing_id,
|
||||||
'anvil',
|
// selected.region.code,
|
||||||
price,
|
// 'anvil',
|
||||||
`${selected.plan_name} - ${orderData.label || session.collected_info?.useCase || 'server'}`
|
// price,
|
||||||
);
|
// `${selected.plan_name} - ${orderData.label || session.collected_info?.useCase || 'server'}`
|
||||||
|
// );
|
||||||
await sendProvisionMessage(env.SERVER_PROVISION_QUEUE, orderId, userId, telegramUserId);
|
//
|
||||||
|
// await sendProvisionMessage(env.SERVER_PROVISION_QUEUE, orderId, userId, telegramUserId);
|
||||||
// 5. 세션 정리
|
//
|
||||||
await env.SESSION_KV.delete(orderSessionKey);
|
// // 5. 세션 정리
|
||||||
await sessionManager.delete(env.DB, telegramUserId);
|
// await env.SESSION_KV.delete(orderSessionKey);
|
||||||
|
// await sessionManager.delete(env.DB, telegramUserId);
|
||||||
// 6. 즉시 응답
|
//
|
||||||
const processingTimeMs = Date.now() - startTime;
|
// // 6. 즉시 응답
|
||||||
|
// const processingTimeMs = Date.now() - startTime;
|
||||||
return Response.json({
|
//
|
||||||
success: true,
|
// return Response.json({
|
||||||
response:
|
// success: true,
|
||||||
`📋 <b>서버 주문 접수 완료!</b> (주문 #${orderId})\n\n` +
|
// response:
|
||||||
`• 서버: ${selected.plan_name}\n` +
|
// `📋 <b>서버 주문 접수 완료!</b> (주문 #${orderId})\n\n` +
|
||||||
`• 리전: ${selected.region.name} (${selected.region.code})\n` +
|
// `• 서버: ${selected.plan_name}\n` +
|
||||||
`• 가격: ${price.toLocaleString()}원/월\n\n` +
|
// `• 리전: ${selected.region.name} (${selected.region.code})\n` +
|
||||||
`⏳ 서버를 생성하고 있습니다... (1-2분 소요)\n` +
|
// `• 가격: ${price.toLocaleString()}원/월\n\n` +
|
||||||
`완료되면 메시지로 알려드릴게요.`,
|
// `⏳ 서버를 생성하고 있습니다... (1-2분 소요)\n` +
|
||||||
processing_time_ms: processingTimeMs,
|
// `완료되면 메시지로 알려드릴게요.`,
|
||||||
});
|
// processing_time_ms: processingTimeMs,
|
||||||
} catch (error) {
|
// });
|
||||||
logger.error('Chat API - 서버 신청 처리 오류', toError(error));
|
// } catch (error) {
|
||||||
const processingTimeMs = Date.now() - startTime;
|
// logger.error('Chat API - 서버 신청 처리 오류', toError(error));
|
||||||
|
// const processingTimeMs = Date.now() - startTime;
|
||||||
return Response.json({
|
//
|
||||||
success: true,
|
// return Response.json({
|
||||||
response: '🚫 서버 신청 중 오류가 발생했습니다. 다시 시도해주세요.',
|
// success: true,
|
||||||
processing_time_ms: processingTimeMs,
|
// response: '🚫 서버 신청 중 오류가 발생했습니다. 다시 시도해주세요.',
|
||||||
});
|
// processing_time_ms: processingTimeMs,
|
||||||
}
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// 서버 신청 취소 처리 (다른 메시지 입력 시)
|
// 서버 신청 취소 처리 (다른 메시지 입력 시)
|
||||||
const orderSessionKey = `server_order_confirm:${telegramUserId}`;
|
const orderSessionKey = `server_order_confirm:${telegramUserId}`;
|
||||||
|
|||||||
@@ -903,15 +903,15 @@ export async function executeServerDelete(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear server consultation session (if any)
|
// NOTE: Server consultation session cleanup removed (recommendation feature deprecated)
|
||||||
try {
|
// try {
|
||||||
const { ServerSessionManager } = await import('../utils/session-manager');
|
// const { ServerSessionManager } = await import('../utils/session-manager');
|
||||||
const { getSessionConfig } = await import('../constants/agent-config');
|
// const { getSessionConfig } = await import('../constants/agent-config');
|
||||||
const sessionManager = new ServerSessionManager(getSessionConfig('server'));
|
// const sessionManager = new ServerSessionManager(getSessionConfig('server'));
|
||||||
await sessionManager.delete(env.DB, telegramUserId);
|
// await sessionManager.delete(env.DB, telegramUserId);
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
provisionLogger.error('서버 세션 삭제 실패 (무시)', error as Error);
|
// provisionLogger.error('서버 세션 삭제 실패 (무시)', error as Error);
|
||||||
}
|
// }
|
||||||
|
|
||||||
provisionLogger.info('서버 삭제 완료', { orderId });
|
provisionLogger.info('서버 삭제 완료', { orderId });
|
||||||
return {
|
return {
|
||||||
@@ -994,15 +994,15 @@ export async function executeServerOrder(
|
|||||||
const order = result.order;
|
const order = result.order;
|
||||||
provisionLogger.info('서버 주문 완료', { orderId: order?.id, plan: orderData.plan });
|
provisionLogger.info('서버 주문 완료', { orderId: order?.id, plan: orderData.plan });
|
||||||
|
|
||||||
// Clear server consultation session
|
// NOTE: Server consultation session cleanup removed (recommendation feature deprecated)
|
||||||
try {
|
// try {
|
||||||
const { ServerSessionManager } = await import('../utils/session-manager');
|
// const { ServerSessionManager } = await import('../utils/session-manager');
|
||||||
const { getSessionConfig } = await import('../constants/agent-config');
|
// const { getSessionConfig } = await import('../constants/agent-config');
|
||||||
const sessionManager = new ServerSessionManager(getSessionConfig('server'));
|
// const sessionManager = new ServerSessionManager(getSessionConfig('server'));
|
||||||
await sessionManager.delete(env.DB, telegramUserId);
|
// await sessionManager.delete(env.DB, telegramUserId);
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
provisionLogger.error('서버 세션 삭제 실패 (무시)', error as Error);
|
// provisionLogger.error('서버 세션 삭제 실패 (무시)', error as Error);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Build success message
|
// Build success message
|
||||||
let successMessage = `✅ 서버 신청이 완료되었습니다!\n\n`;
|
let successMessage = `✅ 서버 신청이 완료되었습니다!\n\n`;
|
||||||
|
|||||||
68
src/types.ts
68
src/types.ts
@@ -211,31 +211,22 @@ export interface LookupDocsArgs {
|
|||||||
|
|
||||||
export interface ManageServerArgs {
|
export interface ManageServerArgs {
|
||||||
action:
|
action:
|
||||||
| "recommend"
|
|
||||||
| "order"
|
| "order"
|
||||||
| "start"
|
| "start"
|
||||||
| "stop"
|
| "stop"
|
||||||
|
| "reboot"
|
||||||
| "delete"
|
| "delete"
|
||||||
| "list"
|
| "list"
|
||||||
| "info"
|
| "info"
|
||||||
| "images"
|
| "images"
|
||||||
| "start_consultation"
|
| "rename";
|
||||||
| "continue_consultation"
|
|
||||||
| "cancel_consultation";
|
|
||||||
tech_stack?: string[];
|
|
||||||
expected_users?: number;
|
|
||||||
use_case?: string;
|
|
||||||
traffic_pattern?: string;
|
|
||||||
region_preference?: string[];
|
|
||||||
budget_limit?: number;
|
|
||||||
lang?: string;
|
|
||||||
server_id?: string;
|
server_id?: string;
|
||||||
region_code?: string;
|
region_code?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
message?: string; // For continue_consultation
|
pricing_id?: number;
|
||||||
pricing_id?: number; // For order
|
order_id?: number;
|
||||||
order_id?: number; // For info, delete
|
new_label?: string;
|
||||||
image?: string; // For order (OS image key)
|
image?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ManageMemoryArgs {
|
export interface ManageMemoryArgs {
|
||||||
@@ -244,53 +235,6 @@ export interface ManageMemoryArgs {
|
|||||||
memory_id?: number;
|
memory_id?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server Consultation Session Status
|
|
||||||
export type ServerSessionStatus =
|
|
||||||
| 'gathering' // 정보 수집 중
|
|
||||||
| 'recommending' // 추천 중
|
|
||||||
| 'selecting' // 선택 대기
|
|
||||||
| 'ordering' // 주문 대기
|
|
||||||
| 'completed'; // 완료
|
|
||||||
|
|
||||||
// Server Consultation Session (D1)
|
|
||||||
export interface ServerSession {
|
|
||||||
user_id: string;
|
|
||||||
status: ServerSessionStatus;
|
|
||||||
collected_info: {
|
|
||||||
useCase?: string;
|
|
||||||
scale?: 'personal' | 'business';
|
|
||||||
budgetLimit?: number;
|
|
||||||
regionPreference?: string[];
|
|
||||||
expectedDau?: number; // 일일 활성 사용자 (Daily Active Users)
|
|
||||||
expectedConcurrent?: number; // 동시접속자 (Concurrent Users)
|
|
||||||
};
|
|
||||||
messages: Array<{ role: 'user' | 'assistant'; content: string }>;
|
|
||||||
created_at: number;
|
|
||||||
updated_at: number;
|
|
||||||
expires_at: number;
|
|
||||||
last_recommendation?: {
|
|
||||||
recommendations: Array<{
|
|
||||||
pricing_id: number; // cloud-instances-db.anvil_pricing.id
|
|
||||||
plan_name: string;
|
|
||||||
provider: string;
|
|
||||||
specs: { vcpu: number; ram_gb: number; storage_gb: number };
|
|
||||||
region: { code: string; name: string };
|
|
||||||
price: {
|
|
||||||
monthly_krw: number;
|
|
||||||
bandwidth_tb: number;
|
|
||||||
estimated_monthly_tb?: number; // origin 트래픽 (서버 도달)
|
|
||||||
gross_monthly_tb?: number; // CDN 전 트래픽
|
|
||||||
cdn_cache_hit_rate?: number; // CDN 히트율 (0.0-1.0)
|
|
||||||
overage_tb?: number;
|
|
||||||
overage_cost_krw?: number;
|
|
||||||
currency?: string; // 통화 단위 (KRW, USD 등)
|
|
||||||
};
|
|
||||||
score: number;
|
|
||||||
max_users: number;
|
|
||||||
}>;
|
|
||||||
created_at: number;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Troubleshooting Session Status
|
// Troubleshooting Session Status
|
||||||
export type TroubleshootSessionStatus =
|
export type TroubleshootSessionStatus =
|
||||||
|
|||||||
@@ -316,24 +316,27 @@ export class DomainSessionManager extends SessionManager<DomainSession> {
|
|||||||
/**
|
/**
|
||||||
* Specialized session manager for Server Agent
|
* Specialized session manager for Server Agent
|
||||||
* Handles last_recommendation field
|
* Handles last_recommendation field
|
||||||
|
*
|
||||||
|
* NOTE: Temporarily commented out during server recommendation removal refactoring.
|
||||||
|
* This class will be removed in a future commit when server-tool.ts is updated.
|
||||||
*/
|
*/
|
||||||
export class ServerSessionManager extends SessionManager<ServerSession> {
|
// export class ServerSessionManager extends SessionManager<ServerSession> {
|
||||||
protected parseAdditionalFields(result: Record<string, unknown>): Partial<ServerSession> {
|
// protected parseAdditionalFields(result: Record<string, unknown>): Partial<ServerSession> {
|
||||||
return {
|
// return {
|
||||||
last_recommendation: result.last_recommendation
|
// last_recommendation: result.last_recommendation
|
||||||
? JSON.parse(result.last_recommendation as string)
|
// ? JSON.parse(result.last_recommendation as string)
|
||||||
: undefined,
|
// : undefined,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected getAdditionalColumns(session: ServerSession): Record<string, unknown> {
|
// protected getAdditionalColumns(session: ServerSession): Record<string, unknown> {
|
||||||
return {
|
// return {
|
||||||
last_recommendation: session.last_recommendation
|
// last_recommendation: session.last_recommendation
|
||||||
? JSON.stringify(session.last_recommendation)
|
// ? JSON.stringify(session.last_recommendation)
|
||||||
: null,
|
// : null,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Import types (avoid circular dependency by importing at end)
|
// Import types (avoid circular dependency by importing at end)
|
||||||
import type { DomainSession, ServerSession } from '../types';
|
import type { DomainSession } from '../types';
|
||||||
|
|||||||
Reference in New Issue
Block a user