use async_trait::async_trait;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use crate::domain::entity::UserQuota;
use crate::infrastructure::persistence::{UserQuotaRepository, PaginationParams, PaginatedResult, UserQuotaFilter};
use super::QueryHandler;
#[deprecated(since = "0.2.0", note = "Use QueryHandler<Q> trait instead")]
#[async_trait]
pub trait UserQuotaQuery: Send + Sync {
type Output;
async fn execute(&self) -> Result<Self::Output>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetUserQuotaByIdQuery {
pub id: String,
}
pub struct GetUserQuotaByIdHandler<R: UserQuotaRepository> {
repository: std::sync::Arc<R>,
}
impl<R: UserQuotaRepository> GetUserQuotaByIdHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: UserQuotaRepository + 'static> QueryHandler<GetUserQuotaByIdQuery> for GetUserQuotaByIdHandler<R> {
type Output = Option<UserQuota>;
async fn handle(&self, query: GetUserQuotaByIdQuery) -> Result<Self::Output> {
self.repository.find_by_id(&query.id).await
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListUserQuotaQuery {
pub page: u32,
pub per_page: u32,
pub filter_user_id: Option<Uuid>,
pub filter_limit_bytes: Option<i64>,
pub filter_used_bytes: Option<i64>,
pub filter_max_file_size: Option<i64>,
pub filter_tier: Option<String>,
pub filter_quota_status: Option<QuotaStatus>,
pub filter_peak_usage_bytes: Option<i64>,
}
impl Default for ListUserQuotaQuery {
fn default() -> Self {
Self {
page: 1,
per_page: 20,
filter_user_id: None,
filter_limit_bytes: None,
filter_used_bytes: None,
filter_max_file_size: None,
filter_tier: None,
filter_quota_status: None,
filter_peak_usage_bytes: None,
}
}
}
pub struct ListUserQuotaHandler<R: UserQuotaRepository> {
repository: std::sync::Arc<R>,
}
impl<R: UserQuotaRepository> ListUserQuotaHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: UserQuotaRepository + 'static> QueryHandler<ListUserQuotaQuery> for ListUserQuotaHandler<R> {
type Output = PaginatedResult<UserQuota>;
async fn handle(&self, query: ListUserQuotaQuery) -> Result<Self::Output> {
let params = PaginationParams::new(query.page, query.per_page);
let filters = UserQuotaFilter {
user_id: query.filter_user_id.clone(),
limit_bytes: query.filter_limit_bytes.clone(),
used_bytes: query.filter_used_bytes.clone(),
max_file_size: query.filter_max_file_size.clone(),
tier: query.filter_tier.clone(),
quota_status: query.filter_quota_status.clone(),
peak_usage_bytes: query.filter_peak_usage_bytes.clone(),
..Default::default()
};
if filters.has_filters() {
self.repository.list_with_filters(params, filters).await
} else {
self.repository.list(params).await
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetUserQuotaByUserIdQuery {
pub user_id: Uuid,
}
pub struct GetUserQuotaByUserIdHandler<R: UserQuotaRepository> {
repository: std::sync::Arc<R>,
}
impl<R: UserQuotaRepository> GetUserQuotaByUserIdHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: UserQuotaRepository + 'static> QueryHandler<GetUserQuotaByUserIdQuery> for GetUserQuotaByUserIdHandler<R> {
type Output = Option<UserQuota>;
async fn handle(&self, query: GetUserQuotaByUserIdQuery) -> Result<Self::Output> {
self.repository.find_by_user_id(query.user_id).await
}
}