From 2de9bdf6c30796d9a812cdfb0ad63fa787d25df2 Mon Sep 17 00:00:00 2001 From: vikingowl Date: Tue, 28 Apr 2026 12:56:32 +0200 Subject: [PATCH] chore(db): backfill historical ai_usage costs after pricing fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-prices every existing ai_usage row using the correct $/1M token rates per model family. CASE clauses ordered specific-first (flash-lite before flash) to mirror the longest-prefix-match in priceFor(). Aliases (gemini-*-latest) resolve to the 2.5 family, the only one in production during the affected window. The grounding-fee component ($35/1k above 1500/day free tier) is not recomputed: historical traffic shows zero grounded calls in the window, so the bumper would be 0. Down is a no-op (irreversible by design — the original miscalculated values are not preserved). --- .../000031_backfill_ai_usage_costs.down.sql | 4 +++ .../000031_backfill_ai_usage_costs.up.sql | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 backend/migrations/000031_backfill_ai_usage_costs.down.sql create mode 100644 backend/migrations/000031_backfill_ai_usage_costs.up.sql diff --git a/backend/migrations/000031_backfill_ai_usage_costs.down.sql b/backend/migrations/000031_backfill_ai_usage_costs.down.sql new file mode 100644 index 0000000..cf0fc86 --- /dev/null +++ b/backend/migrations/000031_backfill_ai_usage_costs.down.sql @@ -0,0 +1,4 @@ +-- Irreversible: the original (incorrect) per-row costs were not preserved. +-- Rolling back would require recomputing at flash-lite rates, which is exactly +-- the bug we just fixed. No-op. +SELECT 1; diff --git a/backend/migrations/000031_backfill_ai_usage_costs.up.sql b/backend/migrations/000031_backfill_ai_usage_costs.up.sql new file mode 100644 index 0000000..95ae22d --- /dev/null +++ b/backend/migrations/000031_backfill_ai_usage_costs.up.sql @@ -0,0 +1,29 @@ +-- Re-price historical ai_usage rows. Until the model-aware estimateCost fix +-- (migration 000030 era), every call was billed at hardcoded flash-lite rates +-- regardless of the actual model. This restates estimated_cost_usd using the +-- correct $/1M token rates per model family. +-- +-- Aliases (gemini-*-latest) are assumed to resolve to the 2.5 family — the only +-- one in production at the time. The grounding-fee component ($35/1k above the +-- 1500/day free tier) is intentionally not recomputed: historical traffic +-- shows zero grounded calls in the affected window, so the bumper would be 0. +-- +-- More-specific WHEN clauses come first (e.g. flash-lite before flash) to +-- mirror the longest-prefix-match semantics of priceFor() in Go. + +UPDATE ai_usage +SET estimated_cost_usd = ROUND(( + CASE + WHEN model LIKE 'gemini-3.1-pro%' THEN input_tokens * 2.00 + output_tokens * 12.00 + WHEN model LIKE 'gemini-3.1-flash-lite%' THEN input_tokens * 0.25 + output_tokens * 1.50 + WHEN model LIKE 'gemini-3-flash%' THEN input_tokens * 0.50 + output_tokens * 3.00 + WHEN model LIKE 'gemini-2.5-pro%' THEN input_tokens * 1.25 + output_tokens * 10.00 + WHEN model LIKE 'gemini-2.5-flash-lite%' THEN input_tokens * 0.10 + output_tokens * 0.40 + WHEN model LIKE 'gemini-2.5-flash%' THEN input_tokens * 0.30 + output_tokens * 2.50 + WHEN model = 'gemini-pro-latest' THEN input_tokens * 1.25 + output_tokens * 10.00 + WHEN model = 'gemini-flash-latest' THEN input_tokens * 0.30 + output_tokens * 2.50 + WHEN model = 'gemini-flash-lite-latest' THEN input_tokens * 0.10 + output_tokens * 0.40 + ELSE estimated_cost_usd * 1000000 -- preserve original (will divide back below) + END +) / 1000000.0, 6) +WHERE provider = 'gemini';