mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
fix(missing-user-stats): missing user stats rows covered via migration' (#1409)
This commit is contained in:
committed by
GitHub
parent
d83865c635
commit
16f5819941
@@ -403,54 +403,43 @@ export class ExecutionLogger implements IExecutionLoggerService {
|
||||
// Apply cost multiplier only to model costs, not base execution charge
|
||||
const costToStore = costSummary.baseExecutionCharge + costSummary.modelCost * costMultiplier
|
||||
|
||||
// Upsert user stats record - insert if doesn't exist, update if it does
|
||||
const { getFreeTierLimit } = await import('@/lib/billing/subscriptions/utils')
|
||||
const defaultLimit = getFreeTierLimit()
|
||||
const existing = await db.select().from(userStats).where(eq(userStats.userId, userId))
|
||||
if (existing.length === 0) {
|
||||
logger.error('User stats record not found - should be created during onboarding', {
|
||||
userId,
|
||||
trigger,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const updateFields: any = {
|
||||
totalTokensUsed: sql`total_tokens_used + ${costSummary.totalTokens}`,
|
||||
totalCost: sql`total_cost + ${costToStore}`,
|
||||
currentPeriodCost: sql`current_period_cost + ${costToStore}`,
|
||||
lastActive: new Date(),
|
||||
}
|
||||
|
||||
const triggerIncrements: any = {}
|
||||
switch (trigger) {
|
||||
case 'manual':
|
||||
triggerIncrements.totalManualExecutions = sql`total_manual_executions + 1`
|
||||
updateFields.totalManualExecutions = sql`total_manual_executions + 1`
|
||||
break
|
||||
case 'api':
|
||||
triggerIncrements.totalApiCalls = sql`total_api_calls + 1`
|
||||
updateFields.totalApiCalls = sql`total_api_calls + 1`
|
||||
break
|
||||
case 'webhook':
|
||||
triggerIncrements.totalWebhookTriggers = sql`total_webhook_triggers + 1`
|
||||
updateFields.totalWebhookTriggers = sql`total_webhook_triggers + 1`
|
||||
break
|
||||
case 'schedule':
|
||||
triggerIncrements.totalScheduledExecutions = sql`total_scheduled_executions + 1`
|
||||
updateFields.totalScheduledExecutions = sql`total_scheduled_executions + 1`
|
||||
break
|
||||
case 'chat':
|
||||
triggerIncrements.totalChatExecutions = sql`total_chat_executions + 1`
|
||||
updateFields.totalChatExecutions = sql`total_chat_executions + 1`
|
||||
break
|
||||
}
|
||||
|
||||
await db
|
||||
.insert(userStats)
|
||||
.values({
|
||||
id: uuidv4(),
|
||||
userId: userId,
|
||||
currentUsageLimit: defaultLimit.toString(),
|
||||
usageLimitUpdatedAt: new Date(),
|
||||
totalTokensUsed: costSummary.totalTokens,
|
||||
totalCost: costToStore,
|
||||
currentPeriodCost: costToStore,
|
||||
lastActive: new Date(),
|
||||
...triggerIncrements,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: userStats.userId,
|
||||
set: {
|
||||
totalTokensUsed: sql`total_tokens_used + ${costSummary.totalTokens}`,
|
||||
totalCost: sql`total_cost + ${costToStore}`,
|
||||
currentPeriodCost: sql`current_period_cost + ${costToStore}`,
|
||||
lastActive: new Date(),
|
||||
...triggerIncrements,
|
||||
},
|
||||
})
|
||||
await db.update(userStats).set(updateFields).where(eq(userStats.userId, userId))
|
||||
|
||||
logger.debug('Upserted user stats record with cost data', {
|
||||
logger.debug('Updated user stats record with cost data', {
|
||||
userId,
|
||||
trigger,
|
||||
addedCost: costToStore,
|
||||
|
||||
47
packages/db/migrations/0091_backfill_user_stats.sql
Normal file
47
packages/db/migrations/0091_backfill_user_stats.sql
Normal file
@@ -0,0 +1,47 @@
|
||||
-- Backfill user_stats for any users missing a stats row
|
||||
-- Uses defaults from schema for limits and counters
|
||||
|
||||
INSERT INTO "user_stats" (
|
||||
"id",
|
||||
"user_id",
|
||||
"current_usage_limit",
|
||||
"usage_limit_updated_at",
|
||||
"total_manual_executions",
|
||||
"total_api_calls",
|
||||
"total_webhook_triggers",
|
||||
"total_scheduled_executions",
|
||||
"total_chat_executions",
|
||||
"total_tokens_used",
|
||||
"total_cost",
|
||||
"current_period_cost",
|
||||
"last_period_cost",
|
||||
"total_copilot_cost",
|
||||
"total_copilot_tokens",
|
||||
"total_copilot_calls",
|
||||
"last_active",
|
||||
"billing_blocked"
|
||||
)
|
||||
SELECT
|
||||
u."id" AS id,
|
||||
u."id" AS user_id,
|
||||
NULL::decimal AS current_usage_limit,
|
||||
NOW() AS usage_limit_updated_at,
|
||||
0 AS total_manual_executions,
|
||||
0 AS total_api_calls,
|
||||
0 AS total_webhook_triggers,
|
||||
0 AS total_scheduled_executions,
|
||||
0 AS total_chat_executions,
|
||||
0 AS total_tokens_used,
|
||||
'0'::decimal AS total_cost,
|
||||
'0'::decimal AS current_period_cost,
|
||||
'0'::decimal AS last_period_cost,
|
||||
'0'::decimal AS total_copilot_cost,
|
||||
0 AS total_copilot_tokens,
|
||||
0 AS total_copilot_calls,
|
||||
NOW() AS last_active,
|
||||
FALSE AS billing_blocked
|
||||
FROM "user" u
|
||||
LEFT JOIN "user_stats" s ON s."user_id" = u."id"
|
||||
WHERE s."user_id" IS NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user