backbone-bucket 0.4.4

Bucket Bounded Context: File Storage Module for Backbone Framework
Documentation
//! Commands for Thumbnail aggregate
//!
//! Generated by backbone-schema. Do not edit manually.
//!
//! CQRS Commands represent intent to change state.

use async_trait::async_trait;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

use crate::domain::entity::Thumbnail;
use crate::infrastructure::persistence::ThumbnailRepository;
use super::CommandHandler;

// ============================================================================
// COMMAND TRAIT (DEPRECATED)
// ============================================================================

/// Command trait for Thumbnail operations
///
/// **DEPRECATED**: Use the generic `CommandHandler<C>` trait from `mod.rs` instead.
/// This trait is kept for backwards compatibility.
#[deprecated(since = "0.2.0", note = "Use CommandHandler<C> trait instead")]
#[async_trait]
pub trait ThumbnailCommand: Send + Sync {
    type Output;
    async fn execute(&self) -> Result<Self::Output>;
}

// ============================================================================
// CREATE COMMAND
// ============================================================================

/// Command to create a new thumbnail
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateThumbnailCommand {
    pub file_id: Uuid,
    pub size: ThumbnailSize,
    pub width: i32,
    pub height: i32,
    pub storage_key: String,
    pub storage_backend: String,
    pub mime_type: String,
    pub format: String,
    pub quality: i32,
    pub size_bytes: i64,
    pub generated_at: DateTime<Utc>,
    pub generation_time_ms: Option<i32>,
    pub source_version: i32,
    pub cdn_url: Option<String>,
    pub cache_expires_at: Option<DateTime<Utc>>,
    pub is_stale: bool,
    pub metadata: serde_json::Value,
}

/// Handler for CreateThumbnailCommand
pub struct CreateThumbnailHandler<R: ThumbnailRepository> {
    repository: std::sync::Arc<R>,
}

impl<R: ThumbnailRepository> CreateThumbnailHandler<R> {
    pub fn new(repository: std::sync::Arc<R>) -> Self {
        Self { repository }
    }
}

#[async_trait]
impl<R: ThumbnailRepository + 'static> CommandHandler<CreateThumbnailCommand> for CreateThumbnailHandler<R> {
    type Output = Thumbnail;

    async fn handle(&self, cmd: CreateThumbnailCommand) -> Result<Self::Output> {
        let entity = Thumbnail::builder()
            .id(Uuid::new_v4().to_string())
            .file_id(cmd.file_id)
            .size(cmd.size)
            .width(cmd.width)
            .height(cmd.height)
            .storage_key(cmd.storage_key)
            .storage_backend(cmd.storage_backend)
            .mime_type(cmd.mime_type)
            .format(cmd.format)
            .quality(cmd.quality)
            .size_bytes(cmd.size_bytes)
            .generated_at(cmd.generated_at)
            .generation_time_ms(cmd.generation_time_ms)
            .source_version(cmd.source_version)
            .cdn_url(cmd.cdn_url)
            .cache_expires_at(cmd.cache_expires_at)
            .is_stale(cmd.is_stale)
            .metadata(cmd.metadata)
            .build()?;

        self.repository.save(&entity).await
    }
}

// ============================================================================
// UPDATE COMMAND
// ============================================================================

/// Command to update an existing thumbnail
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateThumbnailCommand {
    pub id: String,
    pub file_id: Option<Uuid>,
    pub size: Option<ThumbnailSize>,
    pub width: Option<i32>,
    pub height: Option<i32>,
    pub storage_key: Option<String>,
    pub storage_backend: Option<String>,
    pub mime_type: Option<String>,
    pub format: Option<String>,
    pub quality: Option<i32>,
    pub size_bytes: Option<i64>,
    pub generated_at: Option<DateTime<Utc>>,
    pub generation_time_ms: Option<i32>,
    pub source_version: Option<i32>,
    pub cdn_url: Option<String>,
    pub cache_expires_at: Option<DateTime<Utc>>,
    pub is_stale: Option<bool>,
    pub metadata: Option<serde_json::Value>,
}

/// Handler for UpdateThumbnailCommand
pub struct UpdateThumbnailHandler<R: ThumbnailRepository> {
    repository: std::sync::Arc<R>,
}

impl<R: ThumbnailRepository> UpdateThumbnailHandler<R> {
    pub fn new(repository: std::sync::Arc<R>) -> Self {
        Self { repository }
    }
}

#[async_trait]
impl<R: ThumbnailRepository + 'static> CommandHandler<UpdateThumbnailCommand> for UpdateThumbnailHandler<R> {
    type Output = Option<Thumbnail>;

    async fn handle(&self, cmd: UpdateThumbnailCommand) -> Result<Self::Output> {
        let existing = self.repository.find_by_id(&cmd.id).await?;

        let Some(mut entity) = existing else {
            return Ok(None);
        };

        // Apply updates
        if let Some(value) = cmd.file_id {
            entity.file_id = value;
        }
        if let Some(value) = cmd.size {
            entity.size = value;
        }
        if let Some(value) = cmd.width {
            entity.width = value;
        }
        if let Some(value) = cmd.height {
            entity.height = value;
        }
        if let Some(value) = cmd.storage_key {
            entity.storage_key = value;
        }
        if let Some(value) = cmd.storage_backend {
            entity.storage_backend = value;
        }
        if let Some(value) = cmd.mime_type {
            entity.mime_type = value;
        }
        if let Some(value) = cmd.format {
            entity.format = value;
        }
        if let Some(value) = cmd.quality {
            entity.quality = value;
        }
        if let Some(value) = cmd.size_bytes {
            entity.size_bytes = value;
        }
        if let Some(value) = cmd.generated_at {
            entity.generated_at = value;
        }
        entity.generation_time_ms = cmd.generation_time_ms;
        if let Some(value) = cmd.source_version {
            entity.source_version = value;
        }
        entity.cdn_url = cmd.cdn_url;
        entity.cache_expires_at = cmd.cache_expires_at;
        if let Some(value) = cmd.is_stale {
            entity.is_stale = value;
        }
        if let Some(value) = cmd.metadata {
            entity.metadata = value;
        }

        self.repository.update(&cmd.id, &entity).await
    }
}

// ============================================================================
// DELETE COMMAND
// ============================================================================

/// Command to delete a thumbnail
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeleteThumbnailCommand {
    pub id: String,
    pub hard_delete: bool,
}

/// Handler for DeleteThumbnailCommand
pub struct DeleteThumbnailHandler<R: ThumbnailRepository> {
    repository: std::sync::Arc<R>,
}

impl<R: ThumbnailRepository> DeleteThumbnailHandler<R> {
    pub fn new(repository: std::sync::Arc<R>) -> Self {
        Self { repository }
    }
}

#[async_trait]
impl<R: ThumbnailRepository + 'static> CommandHandler<DeleteThumbnailCommand> for DeleteThumbnailHandler<R> {
    type Output = bool;

    async fn handle(&self, cmd: DeleteThumbnailCommand) -> Result<Self::Output> {
        if cmd.hard_delete {
            self.repository.delete(&cmd.id).await
        } else {
            self.repository.soft_delete(&cmd.id).await
        }
    }
}

// ============================================================================
// CUSTOM COMMANDS
// ============================================================================
// <<< CUSTOM COMMANDS START >>>

// <<< CUSTOM COMMANDS START >>>
// Add your custom commands here
// Example:
//
// #[derive(Debug, Clone, Serialize, Deserialize)]
// pub struct ActivateThumbnailCommand {
//     pub id: String,
// }
// <<< CUSTOM COMMANDS END >>>