use std::sync::Arc;
use anyhow::Result;
use async_trait::async_trait;
use super::UseCase;
use crate::domain::entity::AccessLog;
use crate::infrastructure::persistence::AccessLogRepository;
#[derive(Debug, Clone)]
pub struct CreateAccessLogInput {
pub file_id: Uuid,
pub bucket_id: Uuid,
pub action: AccessAction,
pub user_id: Uuid,
pub share_id: Uuid,
pub is_owner: bool,
pub is_shared: bool,
pub is_public: bool,
pub ip_address: String,
pub user_agent: String,
pub referer: String,
pub country_code: String,
pub city: String,
pub bytes_transferred: i64,
pub duration_ms: i32,
pub success: bool,
pub error_message: String,
pub accessed_at: DateTime<Utc>,
pub metadata: serde_json::Value,
}
#[derive(Debug, Clone)]
pub struct CreateAccessLogOutput {
pub access_log: AccessLog,
}
pub struct CreateAccessLogUseCase {
repository: Arc<AccessLogRepository>,
}
impl CreateAccessLogUseCase {
pub fn new(repository: Arc<AccessLogRepository>) -> Self {
Self { repository }
}
}
#[async_trait]
impl UseCase for CreateAccessLogUseCase {
type Input = CreateAccessLogInput;
type Output = CreateAccessLogOutput;
async fn execute(&self, input: Self::Input) -> Result<Self::Output> {
let entity = AccessLog {
id: None,
file_id: input.file_id,
bucket_id: input.bucket_id,
action: input.action,
user_id: input.user_id,
share_id: input.share_id,
is_owner: input.is_owner,
is_shared: input.is_shared,
is_public: input.is_public,
ip_address: input.ip_address,
user_agent: input.user_agent,
referer: input.referer,
country_code: input.country_code,
city: input.city,
bytes_transferred: input.bytes_transferred,
duration_ms: input.duration_ms,
success: input.success,
error_message: input.error_message,
accessed_at: input.accessed_at,
metadata: input.metadata,
};
let created = self.repository.create(entity).await?;
Ok(CreateAccessLogOutput { access_log: created })
}
}