use domain::{ entities::UsageType, errors::DomainError, ports::{QuotaRepository, UsageLedgerRepository}, storage::services::{QuotaCheckResult, check_quota}, value_objects::SystemId, }; use std::sync::Arc; #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct CheckQuotaQuery { pub user_id: SystemId, pub usage_type: UsageType, pub requested_amount: u64, } pub struct CheckQuotaHandler { quota_repo: Arc, ledger_repo: Arc, } impl CheckQuotaHandler { pub fn new( quota_repo: Arc, ledger_repo: Arc, ) -> Self { Self { quota_repo, ledger_repo, } } pub async fn execute(&self, query: CheckQuotaQuery) -> Result { let quota = self.quota_repo.find_by_owner(&query.user_id).await?; let Some(quota) = quota else { return Ok(QuotaCheckResult { allowed: true, current_usage: 0, limit: 0, is_unlimited: true, }); }; let current = self .ledger_repo .sum_usage(&query.user_id, query.usage_type, None) .await?; Ok(check_quota( "a, query.usage_type, current, query.requested_amount, )) } }