use cm_domain::WorkspaceId; use sqlx::PgPool; use uuid::Uuid; use crate::DbError; /// Available credits = sum of remaining balances across all lots; credits /// never expire (ยง8.4). pub async fn balance(pool: &PgPool, workspace_id: WorkspaceId) -> Result { let row = sqlx::query!( r#"SELECT COALESCE(SUM(remaining), 0)::BIGINT AS "balance!" FROM credit_lots WHERE workspace_id = $1"#, workspace_id.as_uuid(), ) .fetch_one(pool) .await?; Ok(row.balance) } pub async fn add_lot( pool: &PgPool, workspace_id: WorkspaceId, amount: i64, source: &str, ) -> Result<(), DbError> { sqlx::query!( "INSERT INTO credit_lots (id, workspace_id, amount, remaining, source) VALUES ($1, $2, $3, $3, $4)", Uuid::now_v7(), workspace_id.as_uuid(), sqlx::types::BigDecimal::from(amount), source, ) .execute(pool) .await?; Ok(()) }