backbone-bucket 0.4.4

Bucket Bounded Context: File Storage Module for Backbone Framework
Documentation
//! Commands for FileShare 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::FileShare;
use crate::infrastructure::persistence::FileShareRepository;
use super::CommandHandler;

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

/// Command trait for FileShare 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 FileShareCommand: Send + Sync {
    type Output;
    async fn execute(&self) -> Result<Self::Output>;
}

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

/// Command to create a new file_share
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateFileShareCommand {
    pub file_id: Uuid,
    pub owner_id: Uuid,
    pub token: String,
    pub share_type: ShareType,
    pub permission: SharePermission,
    pub shared_with: Vec<Uuid>,
    pub password_hash: Option<String>,
    pub max_downloads: Option<i32>,
    pub download_count: i32,
    pub expires_at: Option<DateTime<Utc>>,
    pub status: ShareStatus,
    pub revoked_at: Option<DateTime<Utc>>,
    pub revoked_by: Option<Uuid>,
    pub message: Option<String>,
    pub metadata: serde_json::Value,
}

/// Handler for CreateFileShareCommand
pub struct CreateFileShareHandler<R: FileShareRepository> {
    repository: std::sync::Arc<R>,
}

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

#[async_trait]
impl<R: FileShareRepository + 'static> CommandHandler<CreateFileShareCommand> for CreateFileShareHandler<R> {
    type Output = FileShare;

    async fn handle(&self, cmd: CreateFileShareCommand) -> Result<Self::Output> {
        let entity = FileShare::builder()
            .id(Uuid::new_v4().to_string())
            .file_id(cmd.file_id)
            .owner_id(cmd.owner_id)
            .token(cmd.token)
            .share_type(cmd.share_type)
            .permission(cmd.permission)
            .shared_with(cmd.shared_with)
            .password_hash(cmd.password_hash)
            .max_downloads(cmd.max_downloads)
            .download_count(cmd.download_count)
            .expires_at(cmd.expires_at)
            .status(cmd.status)
            .revoked_at(cmd.revoked_at)
            .revoked_by(cmd.revoked_by)
            .message(cmd.message)
            .metadata(cmd.metadata)
            .build()?;

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

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

/// Command to update an existing file_share
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateFileShareCommand {
    pub id: String,
    pub file_id: Option<Uuid>,
    pub owner_id: Option<Uuid>,
    pub token: Option<String>,
    pub share_type: Option<ShareType>,
    pub permission: Option<SharePermission>,
    pub shared_with: Option<Vec<Uuid>>,
    pub password_hash: Option<String>,
    pub max_downloads: Option<i32>,
    pub download_count: Option<i32>,
    pub expires_at: Option<DateTime<Utc>>,
    pub status: Option<ShareStatus>,
    pub revoked_at: Option<DateTime<Utc>>,
    pub revoked_by: Option<Uuid>,
    pub message: Option<String>,
    pub metadata: Option<serde_json::Value>,
}

/// Handler for UpdateFileShareCommand
pub struct UpdateFileShareHandler<R: FileShareRepository> {
    repository: std::sync::Arc<R>,
}

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

#[async_trait]
impl<R: FileShareRepository + 'static> CommandHandler<UpdateFileShareCommand> for UpdateFileShareHandler<R> {
    type Output = Option<FileShare>;

    async fn handle(&self, cmd: UpdateFileShareCommand) -> 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.owner_id {
            entity.owner_id = value;
        }
        if let Some(value) = cmd.token {
            entity.token = value;
        }
        if let Some(value) = cmd.share_type {
            entity.share_type = value;
        }
        if let Some(value) = cmd.permission {
            entity.permission = value;
        }
        if let Some(value) = cmd.shared_with {
            entity.shared_with = value;
        }
        entity.password_hash = cmd.password_hash;
        entity.max_downloads = cmd.max_downloads;
        if let Some(value) = cmd.download_count {
            entity.download_count = value;
        }
        entity.expires_at = cmd.expires_at;
        if let Some(value) = cmd.status {
            entity.status = value;
        }
        entity.revoked_at = cmd.revoked_at;
        entity.revoked_by = cmd.revoked_by;
        entity.message = cmd.message;
        if let Some(value) = cmd.metadata {
            entity.metadata = value;
        }

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

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

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

/// Handler for DeleteFileShareCommand
pub struct DeleteFileShareHandler<R: FileShareRepository> {
    repository: std::sync::Arc<R>,
}

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

#[async_trait]
impl<R: FileShareRepository + 'static> CommandHandler<DeleteFileShareCommand> for DeleteFileShareHandler<R> {
    type Output = bool;

    async fn handle(&self, cmd: DeleteFileShareCommand) -> 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 ActivateFileShareCommand {
//     pub id: String,
// }
// <<< CUSTOM COMMANDS END >>>