Files
cloud-host/backend/src/billing/pricing-catalog.constants.ts
T
keyhan 055e7a7c8d Add optional service pricing matrix and fix admin catalog save.
Users pick per-service CPU/memory/storage at deploy; admins manage unit rates and deploy defaults. PATCH sends only fields accepted by the pricing-catalog DTO.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 19:16:20 +03:30

110 lines
3.7 KiB
TypeScript

import { AppRuntime, OptionalService, PricingResourceType } from '../common/enums';
/** All application runtimes — new enum values appear in billing automatically. */
export function getAllBillingRuntimes(): AppRuntime[] {
return Object.values(AppRuntime);
}
export const RUNTIME_DISPLAY_LABELS: Record<AppRuntime, string> = {
[AppRuntime.NODEJS]: 'Node.js',
[AppRuntime.LARAVEL]: 'Laravel',
[AppRuntime.WORDPRESS]: 'WordPress',
[AppRuntime.GO]: 'Go',
[AppRuntime.PHP]: 'PHP',
[AppRuntime.PYTHON]: 'Python',
[AppRuntime.DJANGO]: 'Django',
[AppRuntime.DOTNET]: '.NET',
};
export const RUNTIME_PRICING_RESOURCES: PricingResourceType[] = [
PricingResourceType.BASE_FEE,
PricingResourceType.CPU_PER_CORE,
PricingResourceType.MEMORY_PER_GB,
PricingResourceType.STORAGE_PER_GB,
PricingResourceType.DATABASE_ADDON,
];
/** Same billing rows as apps, without database (not applicable to Redis/RabbitMQ/ES). */
export const OPTIONAL_SERVICE_BILLING_RESOURCES: PricingResourceType[] = [
PricingResourceType.BASE_FEE,
PricingResourceType.CPU_PER_CORE,
PricingResourceType.MEMORY_PER_GB,
PricingResourceType.STORAGE_PER_GB,
];
/** Maps optional service → flat addon row in addon_rates. */
export const OPTIONAL_SERVICE_PRICING_TYPE: Record<OptionalService, PricingResourceType> = {
[OptionalService.REDIS]: PricingResourceType.REDIS_ADDON,
[OptionalService.RABBITMQ]: PricingResourceType.RABBITMQ_ADDON,
[OptionalService.ELASTICSEARCH]: PricingResourceType.ELASTICSEARCH_ADDON,
};
export function getBillableAddonResourceTypes(): PricingResourceType[] {
return [PricingResourceType.CUSTOM_DOMAIN_ADDON];
}
export function getAllOptionalServices(): OptionalService[] {
return Object.values(OptionalService);
}
export const OPTIONAL_SERVICE_LABELS: Record<OptionalService, string> = {
[OptionalService.REDIS]: 'Redis',
[OptionalService.RABBITMQ]: 'RabbitMQ',
[OptionalService.ELASTICSEARCH]: 'Elasticsearch (logging)',
};
/** Deploy footprint aligned with helm/cloudhost-app defaults (limits used for billing). */
export const OPTIONAL_SERVICE_DEPLOY_SPECS: Record<
OptionalService,
{
cpuRequest: string;
memoryRequest: string;
cpuLimit: string;
memoryLimit: string;
storageGi: number;
}
> = {
[OptionalService.REDIS]: {
cpuRequest: '50m',
memoryRequest: '64Mi',
cpuLimit: '200m',
memoryLimit: '256Mi',
storageGi: 1,
},
[OptionalService.RABBITMQ]: {
cpuRequest: '100m',
memoryRequest: '256Mi',
cpuLimit: '500m',
memoryLimit: '512Mi',
storageGi: 2,
},
[OptionalService.ELASTICSEARCH]: {
cpuRequest: '50m',
memoryRequest: '64Mi',
cpuLimit: '50m',
memoryLimit: '64Mi',
storageGi: 0,
},
};
/** Fluent Bit sidecar per workload when Elasticsearch logging is enabled. */
export const FLUENT_BIT_SIDECAR = { cpuLimit: '50m', memoryLimit: '64Mi' };
export const RESOURCE_LABELS: Record<PricingResourceType, string> = {
[PricingResourceType.BASE_FEE]: 'Base fee',
[PricingResourceType.CPU_PER_CORE]: 'CPU (per core)',
[PricingResourceType.MEMORY_PER_GB]: 'Memory (per GB)',
[PricingResourceType.STORAGE_PER_GB]: 'Storage (per GB)',
[PricingResourceType.DATABASE_ADDON]: 'Database addon',
[PricingResourceType.REDIS_ADDON]: 'Redis (flat addon)',
[PricingResourceType.RABBITMQ_ADDON]: 'RabbitMQ (flat addon)',
[PricingResourceType.ELASTICSEARCH_ADDON]: 'Elasticsearch (flat addon)',
[PricingResourceType.CUSTOM_DOMAIN_ADDON]: 'Custom domain + SSL',
};
/** @deprecated Use getAllBillingRuntimes() */
export const BILLING_RUNTIMES = getAllBillingRuntimes();
/** @deprecated Use getBillableAddonResourceTypes() */
export const ADDON_PRICING_RESOURCES = getBillableAddonResourceTypes();