feat: KRW 가격 지원 및 GPU/G8/VPU 인스턴스 추가
## KRW 가격 기능 - pricing 테이블에 hourly_price_krw, monthly_price_krw 컬럼 추가 - 부가세 10% + 영업이익 10% + 환율 적용 (기본 1450원) - 시간당: 1원 단위 반올림 (최소 1원) - 월간: 100원 단위 반올림 (최소 100원) - 환율/부가세/영업이익률 환경변수로 분리 (배포 없이 변경 가능) ## GPU/G8/VPU 인스턴스 지원 - gpu_instances, gpu_pricing 테이블 추가 - g8_instances, g8_pricing 테이블 추가 - vpu_instances, vpu_pricing 테이블 추가 - Linode/Vultr 커넥터에 GPU 동기화 로직 추가 ## 환경변수 추가 - KRW_EXCHANGE_RATE: 환율 (기본 1450) - KRW_VAT_RATE: 부가세율 (기본 1.1) - KRW_MARKUP_RATE: 영업이익률 (기본 1.1) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -176,6 +176,7 @@ export const CORS = {
|
||||
ALLOWED_ORIGINS: [
|
||||
'https://anvil.it.com',
|
||||
'https://cloud.anvil.it.com',
|
||||
'https://hosting.anvil.it.com',
|
||||
'http://localhost:3000', // DEVELOPMENT ONLY - exclude in production
|
||||
] as string[],
|
||||
/** Max age for CORS preflight cache (24 hours) */
|
||||
@@ -223,3 +224,90 @@ export const REQUEST_LIMITS = {
|
||||
/** Maximum request body size in bytes (10KB) */
|
||||
MAX_BODY_SIZE: 10 * 1024,
|
||||
} as const;
|
||||
|
||||
// ============================================================
|
||||
// KRW Pricing Configuration
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Default KRW (Korean Won) pricing configuration
|
||||
*
|
||||
* These defaults are used when environment variables are not set.
|
||||
* Calculation formula:
|
||||
* KRW = USD × VAT (1.1) × Markup (1.1) × Exchange Rate (1450)
|
||||
* KRW = USD × 1754.5
|
||||
*/
|
||||
export const KRW_PRICING_DEFAULTS = {
|
||||
/** VAT multiplier (10% VAT) */
|
||||
VAT_MULTIPLIER: 1.1,
|
||||
/** Markup multiplier (10% markup) */
|
||||
MARKUP_MULTIPLIER: 1.1,
|
||||
/** USD to KRW exchange rate */
|
||||
EXCHANGE_RATE: 1450,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* KRW pricing configuration interface
|
||||
*/
|
||||
export interface KRWConfig {
|
||||
exchangeRate: number;
|
||||
vatRate: number;
|
||||
markupRate: number;
|
||||
totalMultiplier: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get KRW pricing configuration from environment variables
|
||||
* Falls back to default values if env vars are not set
|
||||
*
|
||||
* @param env - Cloudflare Worker environment
|
||||
* @returns KRW pricing configuration
|
||||
*/
|
||||
export function getKRWConfig(env?: { KRW_EXCHANGE_RATE?: string; KRW_VAT_RATE?: string; KRW_MARKUP_RATE?: string }): KRWConfig {
|
||||
const exchangeRate = env?.KRW_EXCHANGE_RATE ? parseFloat(env.KRW_EXCHANGE_RATE) : KRW_PRICING_DEFAULTS.EXCHANGE_RATE;
|
||||
const vatRate = env?.KRW_VAT_RATE ? parseFloat(env.KRW_VAT_RATE) : KRW_PRICING_DEFAULTS.VAT_MULTIPLIER;
|
||||
const markupRate = env?.KRW_MARKUP_RATE ? parseFloat(env.KRW_MARKUP_RATE) : KRW_PRICING_DEFAULTS.MARKUP_MULTIPLIER;
|
||||
|
||||
return {
|
||||
exchangeRate,
|
||||
vatRate,
|
||||
markupRate,
|
||||
totalMultiplier: vatRate * markupRate * exchangeRate,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate KRW hourly price from USD price
|
||||
* Applies VAT, markup, and exchange rate conversion
|
||||
*
|
||||
* @param usd - Hourly price in USD
|
||||
* @param env - Optional environment for custom rates (uses defaults if not provided)
|
||||
* @returns Price in KRW, rounded to nearest 1 KRW (minimum 1 KRW)
|
||||
*
|
||||
* @example
|
||||
* calculateKRWHourly(0.0075) // Returns 13 (with defaults)
|
||||
* calculateKRWHourly(0.144) // Returns 253 (with defaults)
|
||||
*/
|
||||
export function calculateKRWHourly(usd: number, env?: { KRW_EXCHANGE_RATE?: string; KRW_VAT_RATE?: string; KRW_MARKUP_RATE?: string }): number {
|
||||
const config = getKRWConfig(env);
|
||||
const krw = Math.round(usd * config.totalMultiplier);
|
||||
return Math.max(krw, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate KRW monthly price from USD price
|
||||
* Applies VAT, markup, and exchange rate conversion
|
||||
*
|
||||
* @param usd - Monthly price in USD
|
||||
* @param env - Optional environment for custom rates (uses defaults if not provided)
|
||||
* @returns Price in KRW, rounded to nearest 100 KRW (minimum 100 KRW)
|
||||
*
|
||||
* @example
|
||||
* calculateKRWMonthly(5) // Returns 8800 (with defaults)
|
||||
* calculateKRWMonthly(96) // Returns 168400 (with defaults)
|
||||
*/
|
||||
export function calculateKRWMonthly(usd: number, env?: { KRW_EXCHANGE_RATE?: string; KRW_VAT_RATE?: string; KRW_MARKUP_RATE?: string }): number {
|
||||
const config = getKRWConfig(env);
|
||||
const krw = Math.round(usd * config.totalMultiplier / 100) * 100;
|
||||
return Math.max(krw, 100);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user