Skip to content

Commit 16f5819

Browse files
fix(missing-user-stats): missing user stats rows covered via migration' (#1409)
1 parent d83865c commit 16f5819

File tree

2 files changed

+69
-33
lines changed

2 files changed

+69
-33
lines changed

apps/sim/lib/logs/execution/logger.ts

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -403,54 +403,43 @@ export class ExecutionLogger implements IExecutionLoggerService {
403403
// Apply cost multiplier only to model costs, not base execution charge
404404
const costToStore = costSummary.baseExecutionCharge + costSummary.modelCost * costMultiplier
405405

406-
// Upsert user stats record - insert if doesn't exist, update if it does
407-
const { getFreeTierLimit } = await import('@/lib/billing/subscriptions/utils')
408-
const defaultLimit = getFreeTierLimit()
406+
const existing = await db.select().from(userStats).where(eq(userStats.userId, userId))
407+
if (existing.length === 0) {
408+
logger.error('User stats record not found - should be created during onboarding', {
409+
userId,
410+
trigger,
411+
})
412+
return
413+
}
414+
415+
const updateFields: any = {
416+
totalTokensUsed: sql`total_tokens_used + ${costSummary.totalTokens}`,
417+
totalCost: sql`total_cost + ${costToStore}`,
418+
currentPeriodCost: sql`current_period_cost + ${costToStore}`,
419+
lastActive: new Date(),
420+
}
409421

410-
const triggerIncrements: any = {}
411422
switch (trigger) {
412423
case 'manual':
413-
triggerIncrements.totalManualExecutions = sql`total_manual_executions + 1`
424+
updateFields.totalManualExecutions = sql`total_manual_executions + 1`
414425
break
415426
case 'api':
416-
triggerIncrements.totalApiCalls = sql`total_api_calls + 1`
427+
updateFields.totalApiCalls = sql`total_api_calls + 1`
417428
break
418429
case 'webhook':
419-
triggerIncrements.totalWebhookTriggers = sql`total_webhook_triggers + 1`
430+
updateFields.totalWebhookTriggers = sql`total_webhook_triggers + 1`
420431
break
421432
case 'schedule':
422-
triggerIncrements.totalScheduledExecutions = sql`total_scheduled_executions + 1`
433+
updateFields.totalScheduledExecutions = sql`total_scheduled_executions + 1`
423434
break
424435
case 'chat':
425-
triggerIncrements.totalChatExecutions = sql`total_chat_executions + 1`
436+
updateFields.totalChatExecutions = sql`total_chat_executions + 1`
426437
break
427438
}
428439

429-
await db
430-
.insert(userStats)
431-
.values({
432-
id: uuidv4(),
433-
userId: userId,
434-
currentUsageLimit: defaultLimit.toString(),
435-
usageLimitUpdatedAt: new Date(),
436-
totalTokensUsed: costSummary.totalTokens,
437-
totalCost: costToStore,
438-
currentPeriodCost: costToStore,
439-
lastActive: new Date(),
440-
...triggerIncrements,
441-
})
442-
.onConflictDoUpdate({
443-
target: userStats.userId,
444-
set: {
445-
totalTokensUsed: sql`total_tokens_used + ${costSummary.totalTokens}`,
446-
totalCost: sql`total_cost + ${costToStore}`,
447-
currentPeriodCost: sql`current_period_cost + ${costToStore}`,
448-
lastActive: new Date(),
449-
...triggerIncrements,
450-
},
451-
})
440+
await db.update(userStats).set(updateFields).where(eq(userStats.userId, userId))
452441

453-
logger.debug('Upserted user stats record with cost data', {
442+
logger.debug('Updated user stats record with cost data', {
454443
userId,
455444
trigger,
456445
addedCost: costToStore,
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
-- Backfill user_stats for any users missing a stats row
2+
-- Uses defaults from schema for limits and counters
3+
4+
INSERT INTO "user_stats" (
5+
"id",
6+
"user_id",
7+
"current_usage_limit",
8+
"usage_limit_updated_at",
9+
"total_manual_executions",
10+
"total_api_calls",
11+
"total_webhook_triggers",
12+
"total_scheduled_executions",
13+
"total_chat_executions",
14+
"total_tokens_used",
15+
"total_cost",
16+
"current_period_cost",
17+
"last_period_cost",
18+
"total_copilot_cost",
19+
"total_copilot_tokens",
20+
"total_copilot_calls",
21+
"last_active",
22+
"billing_blocked"
23+
)
24+
SELECT
25+
u."id" AS id,
26+
u."id" AS user_id,
27+
NULL::decimal AS current_usage_limit,
28+
NOW() AS usage_limit_updated_at,
29+
0 AS total_manual_executions,
30+
0 AS total_api_calls,
31+
0 AS total_webhook_triggers,
32+
0 AS total_scheduled_executions,
33+
0 AS total_chat_executions,
34+
0 AS total_tokens_used,
35+
'0'::decimal AS total_cost,
36+
'0'::decimal AS current_period_cost,
37+
'0'::decimal AS last_period_cost,
38+
'0'::decimal AS total_copilot_cost,
39+
0 AS total_copilot_tokens,
40+
0 AS total_copilot_calls,
41+
NOW() AS last_active,
42+
FALSE AS billing_blocked
43+
FROM "user" u
44+
LEFT JOIN "user_stats" s ON s."user_id" = u."id"
45+
WHERE s."user_id" IS NULL;
46+
47+

0 commit comments

Comments
 (0)