From 9eb9a9a56ca3679988b0409a37152db2409eb058 Mon Sep 17 00:00:00 2001 From: Jon Seager Date: Thu, 5 Feb 2026 12:09:43 +0000 Subject: [PATCH] feat(account): display OpenRouter usage on account page Show cumulative cost, API call count, and total tokens in card layout when the user has AI usage data. --- src/application/routes/account.rs | 44 +++++++++++++++++++++++++++++++ templates/account.html | 21 +++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src/application/routes/account.rs b/src/application/routes/account.rs index 70bb5ed..ce3e1c1 100644 --- a/src/application/routes/account.rs +++ b/src/application/routes/account.rs @@ -16,6 +16,36 @@ use super::auth::is_authenticated; // --- View types --- +#[derive(Serialize)] +pub struct AiUsageView { + pub total_calls: i64, + pub total_tokens: String, + pub total_cost: String, +} + +fn format_cost(cost: f64) -> String { + if cost < 0.01 { + format!("${cost:.4}") + } else { + format!("${cost:.2}") + } +} + +fn format_number(n: i64) -> String { + if n < 1_000 { + return n.to_string(); + } + let s = n.to_string(); + let mut result = String::with_capacity(s.len() + s.len() / 3); + for (i, c) in s.chars().rev().enumerate() { + if i > 0 && i % 3 == 0 { + result.push(','); + } + result.push(c); + } + result.chars().rev().collect() +} + #[derive(Serialize)] pub struct PasskeyView { pub id: i64, @@ -43,6 +73,7 @@ fn format_date(dt: DateTime) -> String { struct AccountTemplate { nav_active: &'static str, is_authenticated: bool, + ai_usage: Option, passkeys: Vec, tokens: Vec, } @@ -91,9 +122,22 @@ pub(crate) async fn account_page( }) .collect(); + let ai_usage = state + .ai_usage_repo + .summary_for_user(auth_user.id) + .await + .ok() + .filter(|s| s.total_calls > 0) + .map(|s| AiUsageView { + total_calls: s.total_calls, + total_tokens: format_number(s.total_tokens), + total_cost: format_cost(s.total_cost), + }); + let template = AccountTemplate { nav_active: "account", is_authenticated: true, + ai_usage, passkeys, tokens, }; diff --git a/templates/account.html b/templates/account.html index c819470..270172b 100644 --- a/templates/account.html +++ b/templates/account.html @@ -212,6 +212,27 @@ + +{% if let Some(usage) = ai_usage %} +
+

OpenRouter Usage

+
+
+ Total Cost + {{ usage.total_cost }} +
+
+ API Calls + {{ usage.total_calls }} +
+
+ Total Tokens + {{ usage.total_tokens }} +
+
+
+{% endif %} +