MCPcopy
hub / github.com/simstudioai/sim / getOrganizationBillingData

Function getOrganizationBillingData

apps/sim/lib/billing/core/organization.ts:92–274  ·  view source on GitHub ↗
(
  organizationId: string,
  executor: DbClient = db
)

Source from the content-addressed store, hash-verified

90 * Get comprehensive organization billing and usage data
91 */
92export async function getOrganizationBillingData(
93 organizationId: string,
94 executor: DbClient = db
95): Promise<OrganizationUsageData | null> {
96 try {
97 // Get organization info
98 const orgRecord = await executor
99 .select()
100 .from(organization)
101 .where(eq(organization.id, organizationId))
102 .limit(1)
103
104 if (orgRecord.length === 0) {
105 logger.warn('Organization not found', { organizationId })
106 return null
107 }
108
109 const organizationData = orgRecord[0]
110
111 // Get organization subscription directly (referenceId = organizationId)
112 const subscription = await getOrganizationSubscription(organizationId, { executor })
113
114 if (!subscription) {
115 logger.warn('No subscription found for organization', { organizationId })
116 return null
117 }
118
119 // Get all organization members with their usage data
120 const membersWithUsage = await executor
121 .select({
122 userId: member.userId,
123 userName: user.name,
124 userEmail: user.email,
125 role: member.role,
126 joinedAt: member.createdAt,
127 // User stats fields
128 currentPeriodCost: userStats.currentPeriodCost,
129 currentUsageLimit: userStats.currentUsageLimit,
130 })
131 .from(member)
132 .innerJoin(user, eq(member.userId, user.id))
133 .leftJoin(userStats, eq(member.userId, userStats.userId))
134 .where(eq(member.organizationId, organizationId))
135
136 // Per-member current-period usage = userStats baseline + attributed usage_log
137 // rows. currentPeriodCost is no longer incremented on the hot path, so the
138 // baseline alone under-reports; add each member's ledger sum for the period.
139 const billingPeriod =
140 subscription.periodStart && subscription.periodEnd
141 ? { start: subscription.periodStart, end: subscription.periodEnd }
142 : null
143 const usageByUser = await getOrgMemberLedgerByUser(organizationId, billingPeriod, executor)
144
145 // Process member data
146 const members: MemberUsageData[] = membersWithUsage.map((memberRecord) => {
147 const currentUsage =
148 Number(memberRecord.currentPeriodCost || 0) + (usageByUser.get(memberRecord.userId) ?? 0)
149 const usageLimit = Number(memberRecord.currentUsageLimit || getFreeTierLimit())

Callers 4

route.tsFile · 0.90
route.tsFile · 0.90
route.tsFile · 0.90

Calls 15

getFreeTierLimitFunction · 0.90
isPaidFunction · 0.90
getPlanTierDollarsFunction · 0.90
getPlanPricingFunction · 0.90
getEffectiveSeatsFunction · 0.90
isEnterpriseFunction · 0.90
toNumberFunction · 0.90
toDecimalFunction · 0.90

Tested by

no test coverage detected