TypeScript 97.5%
SQL 1.4%
Python 0.8%
1import { PLAN_LIMITS, type ConcreteNetwork, type Plan } from "@fetcha/core";2import { config } from "../config";34/**5 * Pricing service. Nothing in the execution path hardcodes prices: the executor reports6 * upstream cost + bytes + network and this module decides what the customer is charged.7 *8 * Model: base subscription (plan) + usage. Every request is priced as9 * per-request component (plan overage rate, 0 while within the included quota — quota is10 * enforced elsewhere) + bandwidth component for premium networks.11 */12export interface PriceInput {13 plan: Plan;14 network: ConcreteNetwork | null;15 bytes: number;16 upstreamCostUsd: number;17 attempts: number;18 success: boolean;19}2021export interface PriceBreakdown {22 requestUsd: number;23 bandwidthUsd: number;24 totalUsd: number;25 marginUsd: number;26}2728export function priceRequest(input: PriceInput): PriceBreakdown {29 const limits = PLAN_LIMITS[input.plan];30 // Private platform: the single plan has no unit prices → nothing is billed. Upstream cost is31 // still tracked for the admin's unit economics.32 if (limits.price_usd_month === 0 && limits.overage_per_1k_requests_usd === 0 && limits.residential_per_gb_usd === 0) {33 return { requestUsd: 0, bandwidthUsd: 0, totalUsd: 0, marginUsd: round6(-input.upstreamCostUsd) };34 }35 // Free/enterprise have no per-request rate; failed requests are never charged a request fee.36 const requestUsd = input.success ? limits.overage_per_1k_requests_usd / 1000 : 0;37 let bandwidthUsd = 0;38 if (input.network && input.network !== "datacenter") {39 const perGb = limits.residential_per_gb_usd || input.upstreamCostUsd > 0 ? limits.residential_per_gb_usd : 0;40 bandwidthUsd = perGb > 0 ? (input.bytes / 1_073_741_824) * perGb : input.upstreamCostUsd * config.defaultMargin;41 } else {42 bandwidthUsd = input.upstreamCostUsd * config.defaultMargin;43 }44 const totalUsd = round6(requestUsd + bandwidthUsd);45 return { requestUsd: round6(requestUsd), bandwidthUsd: round6(bandwidthUsd), totalUsd, marginUsd: round6(totalUsd - input.upstreamCostUsd) };46}4748export function round6(n: number): number {49 return Math.round(n * 1e6) / 1e6;50}5152export function formatUsd(n: number): string {53 if (n === 0) return "$0.00";54 if (n < 0.01) return `$${n.toFixed(5)}`;55 return `$${n.toFixed(2)}`;56}57