Skip to main content

nexus_core/app/
usage.rs

1//! The `/usage` popup's domain half: aggregate token/cache/cost analytics
2//! drawn from the per-request `usage_log`. Content-free — only
3//! backend/model/tokens — so it works even for sessions long compacted
4//! away. The popup's cursor/range flow lives in the view layer.
5
6use super::App;
7
8use crate::db::{UsageByBackend, UsageByModel, UsageRow, UsageTotals};
9
10/// Snapshot of the aggregates the popup renders, loaded on open (and on
11/// Ctrl+R refresh).
12pub struct UsageData {
13    pub totals: UsageTotals,
14    pub by_backend: Vec<UsageByBackend>,
15    pub by_model: Vec<UsageByModel>,
16    pub recent: Vec<UsageRow>,
17}
18
19impl App {
20    /// Load the aggregates for the currently selected range (the view owns
21    /// the cursor; the range is a persisted core preference).
22    pub fn load_usage(&self) -> UsageData {
23        let since = self.usage_range.since().map(|t| t.to_rfc3339());
24        UsageData {
25            totals: self.db.usage_totals(since.as_deref()).unwrap_or_default(),
26            by_backend: self
27                .db
28                .usage_by_backend(since.as_deref())
29                .unwrap_or_default(),
30            by_model: self
31                .db
32                .usage_by_model(10, since.as_deref())
33                .unwrap_or_default(),
34            recent: self
35                .db
36                .usage_recent(200, since.as_deref())
37                .unwrap_or_default(),
38        }
39    }
40
41    /// Domain half of the range cycle: persist the choice (the view switches
42    /// `usage_range` and reloads).
43    pub fn persist_usage_range(&mut self) {
44        let _ = self.db.set_setting("usage_range", self.usage_range.key());
45    }
46
47    /// Recompute historical costs from the current catalog before rendering —
48    /// rows logged before pricing existed stay accurate. Called on popup open
49    /// and refresh.
50    pub fn backfill_usage_costs(&mut self) {
51        let _ = self.db.backfill_usage_costs();
52    }
53}