feat(billing): 引入 billing v3 settlement snapshot 及 usage_billing_facts 视图

- 新增迁移 20260424000000:为 usage_settlement_snapshots 添加 settlement_snapshot、
  billing_dimensions、billing_input/output/cache tokens、billing_total_cost_usd 等列,
  并创建 usage_billing_facts 视图(从 settlement snapshot 覆盖原始 usage token/cost 字段)
- event_enrichment:构建结构化 settlement_snapshot(含 pricing_snapshot、billing_plan_snapshot、
  resolved_dimensions、cost_breakdown 等),写入 request_metadata
- pricing:新增 pricing_source() 方法区分 provider_override / global_default / unpriced
- sql.rs:settlement snapshot 写入新列;用量汇总查询改用 usage_billing_facts 视图
- maintenance/runtime:所有统计查询的 FROM usage 替换为 FROM usage_billing_facts
- admin observability:在 settlement 响应中暴露 settlement_snapshot / billing_dimensions,
  并从 metadata 中剥离对应字段
- request_metadata:允许 settlement_snapshot / billing_dimensions 字段传播
- stream execution:在首个数据帧到达时记录 TTFB,补全流式请求的 streaming 事件
This commit is contained in:
fawney19
2026-04-24 17:52:33 +08:00
parent fb46fcd80f
commit f695238e8a
11 changed files with 1970 additions and 197 deletions

View File

@@ -121,7 +121,7 @@ WITH aggregated AS (
COALESCE(SUM(usage.cache_read_input_tokens), 0) AS cache_read_tokens,
MIN(COALESCE(usage_settlement_snapshots.finalized_at, usage.finalized_at)) AS first_finalized_at,
MAX(COALESCE(usage_settlement_snapshots.finalized_at, usage.finalized_at)) AS last_finalized_at
FROM usage
FROM usage_billing_facts AS usage
JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage_settlement_snapshots.wallet_id IS NOT NULL
@@ -184,7 +184,7 @@ WHERE ledgers.billing_date = $1
AND ledgers.billing_timezone = $2
AND NOT EXISTS (
SELECT 1
FROM usage
FROM usage_billing_facts AS usage
JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage_settlement_snapshots.wallet_id = ledgers.wallet_id
@@ -600,7 +600,7 @@ const SELECT_STATS_DAILY_AGGREGATE_SQL: &str = r#"
SELECT
(
SELECT CAST(COUNT(cache_hit_usage.id) AS BIGINT)
FROM usage AS cache_hit_usage
FROM usage_billing_facts AS cache_hit_usage
WHERE cache_hit_usage.created_at >= $1
AND cache_hit_usage.created_at < $2
) AS cache_hit_total_requests,
@@ -610,13 +610,13 @@ SELECT
WHERE GREATEST(COALESCE(cache_hit_usage.cache_read_input_tokens, 0), 0) > 0
) AS BIGINT
)
FROM usage AS cache_hit_usage
FROM usage_billing_facts AS cache_hit_usage
WHERE cache_hit_usage.created_at >= $1
AND cache_hit_usage.created_at < $2
) AS cache_hit_requests,
(
SELECT CAST(COUNT(completed_usage.id) AS BIGINT)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -627,7 +627,7 @@ SELECT
WHERE GREATEST(COALESCE(completed_usage.cache_read_input_tokens, 0), 0) > 0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -636,7 +636,7 @@ SELECT
SELECT CAST(
COALESCE(SUM(GREATEST(COALESCE(completed_usage.input_tokens, 0), 0)), 0) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -659,7 +659,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -671,7 +671,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -809,7 +809,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -826,7 +826,7 @@ SELECT
0
) AS DOUBLE PRECISION
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -840,7 +840,7 @@ SELECT
0
) AS DOUBLE PRECISION
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -850,7 +850,7 @@ SELECT
COALESCE(SUM(COALESCE(CAST(settled_usage.total_cost_usd AS DOUBLE PRECISION), 0)), 0)
AS DOUBLE PRECISION
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -858,7 +858,7 @@ SELECT
) AS settled_total_cost,
(
SELECT CAST(COUNT(settled_usage.id) AS BIGINT)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -868,7 +868,7 @@ SELECT
SELECT CAST(
COALESCE(SUM(GREATEST(COALESCE(settled_usage.input_tokens, 0), 0)), 0) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -878,7 +878,7 @@ SELECT
SELECT CAST(
COALESCE(SUM(GREATEST(COALESCE(settled_usage.output_tokens, 0), 0)), 0) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -891,7 +891,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -904,7 +904,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -912,7 +912,7 @@ SELECT
) AS settled_cache_read_tokens,
(
SELECT MIN(CAST(EXTRACT(EPOCH FROM settled_usage.finalized_at) AS BIGINT))
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -920,7 +920,7 @@ SELECT
) AS settled_first_finalized_at_unix_secs,
(
SELECT MAX(CAST(EXTRACT(EPOCH FROM settled_usage.finalized_at) AS BIGINT))
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -1081,7 +1081,7 @@ SELECT
CAST(COALESCE(AVG(response_time_ms), 0) AS DOUBLE PRECISION) AS avg_response_time_ms,
CAST(COUNT(DISTINCT model) AS BIGINT) AS unique_models,
CAST(COUNT(DISTINCT provider_name) AS BIGINT) AS unique_providers
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND status NOT IN ('pending', 'streaming')
@@ -1105,7 +1105,7 @@ SELECT
CAST(percentile_cont(0.5) WITHIN GROUP (ORDER BY response_time_ms) AS DOUBLE PRECISION) AS p50,
CAST(percentile_cont(0.9) WITHIN GROUP (ORDER BY response_time_ms) AS DOUBLE PRECISION) AS p90,
CAST(percentile_cont(0.99) WITHIN GROUP (ORDER BY response_time_ms) AS DOUBLE PRECISION) AS p99
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND status = 'completed'
@@ -1118,7 +1118,7 @@ SELECT
CAST(percentile_cont(0.5) WITHIN GROUP (ORDER BY first_byte_time_ms) AS DOUBLE PRECISION) AS p50,
CAST(percentile_cont(0.9) WITHIN GROUP (ORDER BY first_byte_time_ms) AS DOUBLE PRECISION) AS p90,
CAST(percentile_cont(0.99) WITHIN GROUP (ORDER BY first_byte_time_ms) AS DOUBLE PRECISION) AS p99
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND status = 'completed'
@@ -1295,7 +1295,7 @@ WITH aggregated AS (
) AS BIGINT
) AS response_time_samples,
CAST(COALESCE(AVG(response_time_ms), 0) AS DOUBLE PRECISION) AS avg_response_time_ms
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND model IS NOT NULL
@@ -1365,7 +1365,7 @@ WITH aggregated AS (
CAST(COALESCE(SUM(cache_creation_input_tokens), 0) AS BIGINT) AS cache_creation_tokens,
CAST(COALESCE(SUM(cache_read_input_tokens), 0) AS BIGINT) AS cache_read_tokens,
CAST(COALESCE(SUM(total_cost_usd), 0) AS DOUBLE PRECISION) AS total_cost
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND status NOT IN ('pending', 'streaming')
@@ -1437,7 +1437,7 @@ WITH aggregated AS (
0
) AS BIGINT
) AS response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND model IS NOT NULL
@@ -1523,7 +1523,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -1589,7 +1589,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -1665,7 +1665,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -1742,7 +1742,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -1832,7 +1832,7 @@ WITH aggregated AS (
CAST(COALESCE(SUM(cache_creation_input_tokens), 0) AS BIGINT) AS cache_creation_tokens,
CAST(COALESCE(SUM(cache_read_input_tokens), 0) AS BIGINT) AS cache_read_tokens,
CAST(COALESCE(SUM(total_cost_usd), 0) AS DOUBLE PRECISION) AS total_cost
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND api_key_id IS NOT NULL
@@ -1894,7 +1894,7 @@ WITH aggregated AS (
provider_name,
model,
CAST(COUNT(id) AS BIGINT) AS total_count
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND error_category IS NOT NULL
@@ -2183,7 +2183,7 @@ WITH aggregated AS (
0
) AS BIGINT
) AS response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND user_id IS NOT NULL
@@ -2472,7 +2472,7 @@ WITH aggregated AS (
0
) AS BIGINT
) AS successful_response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND user_id IS NOT NULL
@@ -2740,7 +2740,7 @@ WITH aggregated AS (
0
) AS BIGINT
) AS successful_response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND user_id IS NOT NULL
@@ -3008,7 +3008,7 @@ WITH aggregated AS (
0
) AS BIGINT
) AS successful_response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND user_id IS NOT NULL
@@ -3122,7 +3122,7 @@ WITH aggregated AS (
0
) AS BIGINT
) AS response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND user_id IS NOT NULL
@@ -3218,7 +3218,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -3300,7 +3300,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -3386,7 +3386,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -3473,7 +3473,7 @@ WITH aggregated AS (
0
) AS DOUBLE PRECISION
) AS estimated_full_cost
FROM usage
FROM usage_billing_facts AS usage
LEFT JOIN usage_settlement_snapshots
ON usage_settlement_snapshots.request_id = usage.request_id
WHERE usage.created_at >= $1
@@ -3700,7 +3700,7 @@ WHERE is_complete IS TRUE
"#;
const SELECT_NEXT_STATS_DAILY_BUCKET_SQL: &str = r#"
SELECT date_trunc('day', MIN(created_at)) AS next_bucket
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND status NOT IN ('pending', 'streaming')
@@ -3713,7 +3713,7 @@ WHERE is_complete IS TRUE
"#;
const SELECT_NEXT_STATS_HOURLY_BUCKET_SQL: &str = r#"
SELECT date_trunc('hour', MIN(created_at)) AS next_bucket
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND status NOT IN ('pending', 'streaming')
@@ -3723,7 +3723,7 @@ const SELECT_STATS_HOURLY_AGGREGATE_SQL: &str = r#"
SELECT
(
SELECT CAST(COUNT(cache_hit_usage.id) AS BIGINT)
FROM usage AS cache_hit_usage
FROM usage_billing_facts AS cache_hit_usage
WHERE cache_hit_usage.created_at >= $1
AND cache_hit_usage.created_at < $2
) AS cache_hit_total_requests,
@@ -3733,13 +3733,13 @@ SELECT
WHERE GREATEST(COALESCE(cache_hit_usage.cache_read_input_tokens, 0), 0) > 0
) AS BIGINT
)
FROM usage AS cache_hit_usage
FROM usage_billing_facts AS cache_hit_usage
WHERE cache_hit_usage.created_at >= $1
AND cache_hit_usage.created_at < $2
) AS cache_hit_requests,
(
SELECT CAST(COUNT(completed_usage.id) AS BIGINT)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3750,7 +3750,7 @@ SELECT
WHERE GREATEST(COALESCE(completed_usage.cache_read_input_tokens, 0), 0) > 0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3759,7 +3759,7 @@ SELECT
SELECT CAST(
COALESCE(SUM(GREATEST(COALESCE(completed_usage.input_tokens, 0), 0)), 0) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3782,7 +3782,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3794,7 +3794,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3932,7 +3932,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3949,7 +3949,7 @@ SELECT
0
) AS DOUBLE PRECISION
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3963,7 +3963,7 @@ SELECT
0
) AS DOUBLE PRECISION
)
FROM usage AS completed_usage
FROM usage_billing_facts AS completed_usage
WHERE completed_usage.created_at >= $1
AND completed_usage.created_at < $2
AND completed_usage.status = 'completed'
@@ -3973,7 +3973,7 @@ SELECT
COALESCE(SUM(COALESCE(CAST(settled_usage.total_cost_usd AS DOUBLE PRECISION), 0)), 0)
AS DOUBLE PRECISION
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -3981,7 +3981,7 @@ SELECT
) AS settled_total_cost,
(
SELECT CAST(COUNT(settled_usage.id) AS BIGINT)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -3991,7 +3991,7 @@ SELECT
SELECT CAST(
COALESCE(SUM(GREATEST(COALESCE(settled_usage.input_tokens, 0), 0)), 0) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -4001,7 +4001,7 @@ SELECT
SELECT CAST(
COALESCE(SUM(GREATEST(COALESCE(settled_usage.output_tokens, 0), 0)), 0) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -4014,7 +4014,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -4027,7 +4027,7 @@ SELECT
0
) AS BIGINT
)
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -4035,7 +4035,7 @@ SELECT
) AS settled_cache_read_tokens,
(
SELECT MIN(CAST(EXTRACT(EPOCH FROM settled_usage.finalized_at) AS BIGINT))
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -4043,7 +4043,7 @@ SELECT
) AS settled_first_finalized_at_unix_secs,
(
SELECT MAX(CAST(EXTRACT(EPOCH FROM settled_usage.finalized_at) AS BIGINT))
FROM usage AS settled_usage
FROM usage_billing_facts AS settled_usage
WHERE settled_usage.created_at >= $1
AND settled_usage.created_at < $2
AND settled_usage.billing_status = 'settled'
@@ -4101,7 +4101,7 @@ SELECT
0
) AS response_time_samples,
CAST(COALESCE(AVG(response_time_ms), 0) AS DOUBLE PRECISION) AS avg_response_time_ms
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND status NOT IN ('pending', 'streaming')
@@ -4330,7 +4330,7 @@ WITH aggregated AS (
),
0
) AS response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND user_id IS NOT NULL
@@ -4441,7 +4441,7 @@ WITH aggregated AS (
0
) AS response_time_samples,
CAST(COALESCE(AVG(response_time_ms), 0) AS DOUBLE PRECISION) AS avg_response_time_ms
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND model IS NOT NULL
@@ -4517,7 +4517,7 @@ WITH aggregated AS (
),
0
) AS response_time_samples
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND user_id IS NOT NULL
@@ -4573,7 +4573,7 @@ WITH aggregated AS (
COALESCE(SUM(input_tokens), 0) AS input_tokens,
COALESCE(SUM(output_tokens), 0) AS output_tokens,
CAST(COALESCE(SUM(total_cost_usd), 0) AS DOUBLE PRECISION) AS total_cost
FROM usage
FROM usage_billing_facts AS usage
WHERE created_at >= $1
AND created_at < $2
AND provider_name IS NOT NULL