use async_trait::async_trait;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use crate::domain::entity::AccessLog;
use crate::infrastructure::persistence::{AccessLogRepository, PaginationParams, PaginatedResult, AccessLogFilter};
use super::QueryHandler;
#[deprecated(since = "0.2.0", note = "Use QueryHandler<Q> trait instead")]
#[async_trait]
pub trait AccessLogQuery: Send + Sync {
type Output;
async fn execute(&self) -> Result<Self::Output>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GetAccessLogByIdQuery {
pub id: String,
}
pub struct GetAccessLogByIdHandler<R: AccessLogRepository> {
repository: std::sync::Arc<R>,
}
impl<R: AccessLogRepository> GetAccessLogByIdHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: AccessLogRepository + 'static> QueryHandler<GetAccessLogByIdQuery> for GetAccessLogByIdHandler<R> {
type Output = Option<AccessLog>;
async fn handle(&self, query: GetAccessLogByIdQuery) -> Result<Self::Output> {
self.repository.find_by_id(&query.id).await
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListAccessLogQuery {
pub page: u32,
pub per_page: u32,
pub filter_file_id: Option<Uuid>,
pub filter_bucket_id: Option<Uuid>,
pub filter_action: Option<AccessAction>,
pub filter_user_id: Option<Uuid>,
pub filter_share_id: Option<Uuid>,
pub filter_is_owner: Option<bool>,
pub filter_is_shared: Option<bool>,
pub filter_is_public: Option<bool>,
pub filter_ip_address: Option<String>,
pub filter_user_agent: Option<String>,
pub filter_referer: Option<String>,
pub filter_country_code: Option<String>,
pub filter_city: Option<String>,
pub filter_bytes_transferred: Option<i64>,
pub filter_duration_ms: Option<i32>,
pub filter_success: Option<bool>,
pub filter_error_message: Option<String>,
}
impl Default for ListAccessLogQuery {
fn default() -> Self {
Self {
page: 1,
per_page: 20,
filter_file_id: None,
filter_bucket_id: None,
filter_action: None,
filter_user_id: None,
filter_share_id: None,
filter_is_owner: None,
filter_is_shared: None,
filter_is_public: None,
filter_ip_address: None,
filter_user_agent: None,
filter_referer: None,
filter_country_code: None,
filter_city: None,
filter_bytes_transferred: None,
filter_duration_ms: None,
filter_success: None,
filter_error_message: None,
}
}
}
pub struct ListAccessLogHandler<R: AccessLogRepository> {
repository: std::sync::Arc<R>,
}
impl<R: AccessLogRepository> ListAccessLogHandler<R> {
pub fn new(repository: std::sync::Arc<R>) -> Self {
Self { repository }
}
}
#[async_trait]
impl<R: AccessLogRepository + 'static> QueryHandler<ListAccessLogQuery> for ListAccessLogHandler<R> {
type Output = PaginatedResult<AccessLog>;
async fn handle(&self, query: ListAccessLogQuery) -> Result<Self::Output> {
let params = PaginationParams::new(query.page, query.per_page);
let filters = AccessLogFilter {
file_id: query.filter_file_id.clone(),
bucket_id: query.filter_bucket_id.clone(),
action: query.filter_action.clone(),
user_id: query.filter_user_id.clone(),
share_id: query.filter_share_id.clone(),
is_owner: query.filter_is_owner.clone(),
is_shared: query.filter_is_shared.clone(),
is_public: query.filter_is_public.clone(),
ip_address: query.filter_ip_address.clone(),
user_agent: query.filter_user_agent.clone(),
referer: query.filter_referer.clone(),
country_code: query.filter_country_code.clone(),
city: query.filter_city.clone(),
bytes_transferred: query.filter_bytes_transferred.clone(),
duration_ms: query.filter_duration_ms.clone(),
success: query.filter_success.clone(),
error_message: query.filter_error_message.clone(),
..Default::default()
};
if filters.has_filters() {
self.repository.list_with_filters(params, filters).await
} else {
self.repository.list(params).await
}
}
}