Preserve dashboard daily breakdown rows

This commit is contained in:
RWDai
2026-05-28 22:02:42 +08:00
parent 14ad6e9b75
commit 6d285410c2
3 changed files with 56 additions and 57 deletions
@@ -4389,7 +4389,7 @@ ORDER BY date ASC, total_cost_usd DESC, model ASC, provider_name ASC
r#"
SELECT
TO_CHAR(
date_trunc('day', "usage".created_at + (
date_trunc('day', ("usage".created_at AT TIME ZONE 'UTC') + (
"#,
);
builder.push_bind(query.tz_offset_minutes);
@@ -4484,53 +4484,12 @@ ORDER BY date ASC, total_cost_usd DESC, "usage".model ASC, "usage".provider_name
Ok(items)
}
async fn list_dashboard_daily_breakdown_aggregate_segments(
&self,
query: &UsageDashboardDailyBreakdownQuery,
) -> Result<Vec<StoredUsageDashboardDailyBreakdownRow>, DataLayerError> {
let cutoff_utc = match self.read_stats_daily_cutoff_date().await {
Ok(value) => value,
Err(err) if dashboard_should_fallback_to_raw_on_aggregate_error(&err) => {
return Ok(Vec::new());
}
Err(err) => return Err(err),
};
let Some(cutoff_utc) = cutoff_utc else {
return Ok(Vec::new());
};
let start_utc = dashboard_unix_secs_to_utc(query.created_from_unix_secs);
let end_utc = dashboard_unix_secs_to_utc(query.created_until_unix_secs);
let split = split_dashboard_daily_aggregate_range(start_utc, end_utc, cutoff_utc);
let Some((aggregate_start, aggregate_end)) = split.aggregate else {
return Ok(Vec::new());
};
self.list_dashboard_daily_breakdown_from_daily_aggregates(
aggregate_start,
aggregate_end,
query.user_id.as_deref(),
)
.await
}
pub async fn list_dashboard_daily_breakdown(
&self,
query: &UsageDashboardDailyBreakdownQuery,
) -> Result<Vec<StoredUsageDashboardDailyBreakdownRow>, DataLayerError> {
if query.tz_offset_minutes != 0 {
let mut items = self
.list_dashboard_daily_breakdown_aggregate_segments(query)
.await?;
let mut aggregate_dates = items
.iter()
.map(|item| item.date.clone())
.collect::<std::collections::BTreeSet<_>>();
for item in self.list_dashboard_daily_breakdown_raw(query).await? {
if aggregate_dates.insert(item.date.clone()) {
items.push(item);
}
}
return Ok(finalize_dashboard_daily_breakdown_rows(items));
return self.list_dashboard_daily_breakdown_raw(query).await;
}
let cutoff_utc = match self.read_stats_daily_cutoff_date().await {
@@ -452,14 +452,32 @@ fn usage_sql_daily_cutoff_falls_back_to_imported_stats_daily() {
#[test]
fn usage_sql_dashboard_daily_breakdown_falls_back_to_daily_totals() {
let source = include_str!("mod.rs");
assert!(source.contains("list_dashboard_daily_breakdown_aggregate_segments"));
assert!(source.contains("list_dashboard_daily_breakdown_from_daily_totals"));
assert!(source.contains("'aggregate'::TEXT AS model"));
assert!(source.contains("FROM stats_daily"));
assert!(source.contains("FROM stats_user_daily"));
assert!(source.contains("detailed_dates.contains(&item.date)"));
assert!(source.contains("query.tz_offset_minutes != 0"));
assert!(source.contains("aggregate_dates.insert(item.date.clone())"));
assert!(source.contains("return self.list_dashboard_daily_breakdown_raw(query).await;"));
assert!(!source.contains("aggregate_dates.insert(item.date.clone())"));
}
#[test]
fn usage_sql_dashboard_daily_breakdown_keeps_all_local_day_model_provider_rows() {
let source = include_str!("mod.rs");
let raw_breakdown = source
.split("async fn list_dashboard_daily_breakdown_raw")
.nth(1)
.and_then(|tail| {
tail.split("pub async fn list_dashboard_daily_breakdown")
.next()
})
.expect("raw daily breakdown function should be present");
assert!(raw_breakdown.contains("GROUP BY date, \"usage\".model, \"usage\".provider_name"));
assert!(raw_breakdown.contains("ORDER BY date ASC, total_cost_usd DESC"));
assert!(raw_breakdown.contains("(\"usage\".created_at AT TIME ZONE 'UTC')"));
assert!(!raw_breakdown.contains("date_trunc('day', \"usage\".created_at +"));
assert!(!source.contains("if aggregate_dates.insert(item.date.clone())"));
}
#[test]