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

@@ -8,7 +8,7 @@ use tracing::{error, info, warn};
static MIGRATOR: Migrator = sqlx::migrate!("./migrations");
static BASELINE_V2_SQL: &str = include_str!("../bootstrap/20260413020000_baseline_v2.sql");
const BASELINE_V2_CUTOFF_VERSION: i64 = 20260423000000;
const BASELINE_V2_CUTOFF_VERSION: i64 = 20260424000000;
const MIGRATIONS_TABLE_EXISTS_SQL: &str =
"SELECT to_regclass('public._sqlx_migrations') IS NOT NULL";
const PUBLIC_BASE_TABLE_COUNT_SQL: &str = r#"
@@ -663,6 +663,7 @@ SELECT EXISTS (
20260422110000,
20260422120000,
20260423000000,
20260424000000,
]
);
}
@@ -683,6 +684,10 @@ SELECT EXISTS (
.contains("CREATE TABLE IF NOT EXISTS public.usage_settlement_snapshots"));
assert!(BASELINE_V2_SQL.contains("billing_snapshot_schema_version"));
assert!(BASELINE_V2_SQL.contains("price_per_request"));
assert!(BASELINE_V2_SQL.contains("settlement_snapshot_schema_version"));
assert!(BASELINE_V2_SQL.contains("billing_effective_input_tokens"));
assert!(BASELINE_V2_SQL.contains("CREATE OR REPLACE VIEW public.usage_billing_facts"));
assert!(BASELINE_V2_SQL.contains("usage_settlement_snapshots.billing_total_cost_usd"));
assert!(BASELINE_V2_SQL.contains("candidate_index integer"));
assert!(BASELINE_V2_SQL.contains("CREATE TABLE IF NOT EXISTS public.stats_user_summary"));
assert!(
@@ -810,6 +815,7 @@ SELECT EXISTS (
20260422110000,
20260422120000,
20260423000000,
20260424000000,
]
);
}

File diff suppressed because it is too large Load Diff