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

Function getUserUsageData

apps/sim/lib/billing/core/usage.ts:188–340  ·  view source on GitHub ↗
(
  userId: string,
  executor: DbClient = db
)

Source from the content-addressed store, hash-verified

186 * Get comprehensive usage data for a user
187 */
188export async function getUserUsageData(
189 userId: string,
190 executor: DbClient = db
191): Promise<UsageData> {
192 try {
193 // Write — always on the primary regardless of executor routing.
194 await ensureUserStatsExists(userId)
195
196 const [userStatsData, subscription] = await Promise.all([
197 // Read-your-write: must see the row ensureUserStatsExists may have just
198 // inserted, which a lagging replica can miss (this path throws on a
199 // missing row). Stays on the primary deliberately.
200 db
201 .select()
202 .from(userStats)
203 .where(eq(userStats.userId, userId))
204 .limit(1),
205 getHighestPrioritySubscription(userId, { executor }),
206 ])
207
208 if (userStatsData.length === 0) {
209 logger.error('User stats not found for userId', { userId })
210 throw new Error(`User stats not found for userId: ${userId}`)
211 }
212
213 const stats = userStatsData[0]
214 const orgScoped = isOrgScopedSubscription(subscription, userId)
215 const billingPeriod =
216 subscription?.periodStart && subscription.periodEnd
217 ? { start: subscription.periodStart, end: subscription.periodEnd }
218 : defaultBillingPeriod()
219
220 let currentUsageDecimal = toDecimal(stats.currentPeriodCost)
221 if (!orgScoped) {
222 currentUsageDecimal = currentUsageDecimal.plus(
223 await getBillingPeriodUsageCost(
224 { type: 'user', id: userId },
225 billingPeriod,
226 undefined,
227 executor
228 )
229 )
230 }
231
232 // For personally-scoped Pro users, include any snapshotted usage from
233 // a prior org-join so the display reflects their total Pro usage.
234 if (subscription && isPro(subscription.plan) && !orgScoped) {
235 const snapshotUsageDecimal = toDecimal(stats.proPeriodCostSnapshot)
236 if (snapshotUsageDecimal.greaterThan(0)) {
237 currentUsageDecimal = currentUsageDecimal.plus(snapshotUsageDecimal)
238 logger.info('Including Pro snapshot in usage display', {
239 userId,
240 currentPeriodCost: stats.currentPeriodCost,
241 proPeriodCostSnapshot: toNumber(snapshotUsageDecimal),
242 totalUsage: toNumber(currentUsageDecimal),
243 })
244 }
245 }

Callers 5

route.tsFile · 0.90
route.tsFile · 0.90
checkUsageStatusFunction · 0.85

Calls 15

isOrgScopedSubscriptionFunction · 0.90
defaultBillingPeriodFunction · 0.90
toDecimalFunction · 0.90
isProFunction · 0.90
toNumberFunction · 0.90
getFreeTierLimitFunction · 0.90
isPaidFunction · 0.90
getPlanTierDollarsFunction · 0.90

Tested by

no test coverage detected