MCPcopy Index your code
hub / github.com/simstudioai/sim / calculateBillingProjection

Function calculateBillingProjection

apps/sim/lib/billing/core/usage.ts:774–815  ·  view source on GitHub ↗

* Calculate billing projection based on current usage

(userId: string)

Source from the content-addressed store, hash-verified

772 * Calculate billing projection based on current usage
773 */
774async function calculateBillingProjection(userId: string): Promise<BillingData> {
775 try {
776 const usageData = await getUserUsageData(userId)
777
778 if (!usageData.billingPeriodStart || !usageData.billingPeriodEnd) {
779 return {
780 currentPeriodCost: usageData.currentUsage,
781 projectedCost: usageData.currentUsage,
782 limit: usageData.limit,
783 billingPeriodStart: null,
784 billingPeriodEnd: null,
785 daysRemaining: 0,
786 }
787 }
788
789 const now = new Date()
790 const periodStart = new Date(usageData.billingPeriodStart)
791 const periodEnd = new Date(usageData.billingPeriodEnd)
792
793 const totalDays = Math.ceil(
794 (periodEnd.getTime() - periodStart.getTime()) / (1000 * 60 * 60 * 24)
795 )
796 const daysElapsed = Math.ceil((now.getTime() - periodStart.getTime()) / (1000 * 60 * 60 * 24))
797 const daysRemaining = Math.max(0, totalDays - daysElapsed)
798
799 // Project cost based on daily usage rate
800 const dailyRate = daysElapsed > 0 ? usageData.currentUsage / daysElapsed : 0
801 const projectedCost = dailyRate * totalDays
802
803 return {
804 currentPeriodCost: usageData.currentUsage,
805 projectedCost: Math.min(projectedCost, usageData.limit), // Cap at limit
806 limit: usageData.limit,
807 billingPeriodStart: usageData.billingPeriodStart,
808 billingPeriodEnd: usageData.billingPeriodEnd,
809 daysRemaining,
810 }
811 } catch (error) {
812 logger.error('Failed to calculate billing projection', { userId, error })
813 throw error
814 }
815}
816
817/**
818 * Send usage threshold notification when crossing from <80% to ≥80%.

Callers

nothing calls this directly

Calls 2

getUserUsageDataFunction · 0.85
errorMethod · 0.80

Tested by

no test coverage detected