collab: Return `trial_started_at` alongside billing preferences (#30143)

Marshall Bowers created

This PR updates the `GET /billing/preferences` endpoint to return the
user's `trial_started_at` timestamp alongside the billing preferences.

Release Notes:

- N/A

Change summary

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

Detailed changes

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

@@ -71,6 +71,7 @@ struct GetBillingPreferencesParams {
 
 #[derive(Debug, Serialize)]
 struct BillingPreferencesResponse {
+    trial_started_at: Option<String>,
     max_monthly_llm_usage_spending_in_cents: i32,
     model_request_overages_enabled: bool,
     model_request_overages_spend_limit_in_cents: i32,
@@ -86,9 +87,17 @@ async fn get_billing_preferences(
         .await?
         .ok_or_else(|| anyhow!("user not found"))?;
 
+    let billing_customer = app.db.get_billing_customer_by_user_id(user.id).await?;
     let preferences = app.db.get_billing_preferences(user.id).await?;
 
     Ok(Json(BillingPreferencesResponse {
+        trial_started_at: billing_customer
+            .and_then(|billing_customer| billing_customer.trial_started_at)
+            .map(|trial_started_at| {
+                trial_started_at
+                    .and_utc()
+                    .to_rfc3339_opts(SecondsFormat::Millis, true)
+            }),
         max_monthly_llm_usage_spending_in_cents: preferences
             .as_ref()
             .map_or(DEFAULT_MAX_MONTHLY_SPEND.0 as i32, |preferences| {
@@ -127,6 +136,8 @@ async fn update_billing_preferences(
         .await?
         .ok_or_else(|| anyhow!("user not found"))?;
 
+    let billing_customer = app.db.get_billing_customer_by_user_id(user.id).await?;
+
     let max_monthly_llm_usage_spending_in_cents =
         body.max_monthly_llm_usage_spending_in_cents.max(0);
     let model_request_overages_spend_limit_in_cents =
@@ -182,6 +193,13 @@ async fn update_billing_preferences(
     rpc_server.refresh_llm_tokens_for_user(user.id).await;
 
     Ok(Json(BillingPreferencesResponse {
+        trial_started_at: billing_customer
+            .and_then(|billing_customer| billing_customer.trial_started_at)
+            .map(|trial_started_at| {
+                trial_started_at
+                    .and_utc()
+                    .to_rfc3339_opts(SecondsFormat::Millis, true)
+            }),
         max_monthly_llm_usage_spending_in_cents: billing_preferences
             .max_monthly_llm_usage_spending_in_cents,
         model_request_overages_enabled: billing_preferences.model_request_overages_enabled,