Introduce a new /billing/monthly_spend API (#19354)

Antonio Scandurra created

Fixes https://github.com/zed-industries/zed/issues/19353

Release Notes:

- N/A

Change summary

crates/collab/src/api/billing.rs | 37 ++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)

Detailed changes

crates/collab/src/api/billing.rs 🔗

@@ -50,6 +50,7 @@ pub fn router() -> Router {
             "/billing/subscriptions/manage",
             post(manage_billing_subscription),
         )
+        .route("/billing/monthly_spend", get(get_monthly_spend))
 }
 
 #[derive(Debug, Deserialize)]
@@ -672,6 +673,42 @@ async fn handle_customer_subscription_event(
     Ok(())
 }
 
+#[derive(Debug, Deserialize)]
+struct GetMonthlySpendParams {
+    github_user_id: i32,
+}
+
+#[derive(Debug, Serialize)]
+struct GetMonthlySpendResponse {
+    monthly_spend_in_cents: i32,
+}
+
+async fn get_monthly_spend(
+    Extension(app): Extension<Arc<AppState>>,
+    Query(params): Query<GetMonthlySpendParams>,
+) -> Result<Json<GetMonthlySpendResponse>> {
+    let user = app
+        .db
+        .get_user_by_github_user_id(params.github_user_id)
+        .await?
+        .ok_or_else(|| anyhow!("user not found"))?;
+
+    let Some(llm_db) = app.llm_db.clone() else {
+        return Err(Error::http(
+            StatusCode::NOT_IMPLEMENTED,
+            "LLM database not available".into(),
+        ));
+    };
+
+    let monthly_spend = llm_db
+        .get_user_spending_for_month(user.id, Utc::now())
+        .await?;
+
+    Ok(Json(GetMonthlySpendResponse {
+        monthly_spend_in_cents: monthly_spend.0 as i32,
+    }))
+}
+
 impl From<SubscriptionStatus> for StripeSubscriptionStatus {
     fn from(value: SubscriptionStatus) -> Self {
         match value {