backbone-mailing 0.3.30

Email marketing — mass-mail engine: audiences, subscriptions, hand-set mailing lifecycle, seeded A/B testing, per-recipient traces, cycle-44 bridge targets (Odoo mass_mailing port)
//! DTOs (Data Transfer Objects)
//!
//! Generated by metaphor-schema. Do not edit manually.
//!
//! This module provides DTOs for the presentation layer,
//! with validation and OpenAPI schema support.

pub mod mailing_ab_test_dto;
pub mod mailing_audience_dto;
pub mod mailing_contact_dto;
pub mod mailing_subscription_dto;
pub mod opt_out_reason_dto;
pub mod mailing_dto;
pub mod mailing_trace_dto;
pub mod mailing_filter_dto;

// Re-exports
pub use mailing_ab_test_dto::{
    CreateMailingAbTestDto,
    UpdateMailingAbTestDto,
    PatchMailingAbTestDto,
    MailingAbTestResponseDto,
    MailingAbTestListResponseDto,
    MailingAbTestSummaryDto,
};
pub use mailing_audience_dto::{
    CreateMailingAudienceDto,
    UpdateMailingAudienceDto,
    PatchMailingAudienceDto,
    MailingAudienceResponseDto,
    MailingAudienceListResponseDto,
    MailingAudienceSummaryDto,
};
pub use mailing_contact_dto::{
    CreateMailingContactDto,
    UpdateMailingContactDto,
    PatchMailingContactDto,
    MailingContactResponseDto,
    MailingContactListResponseDto,
    MailingContactSummaryDto,
};
pub use mailing_subscription_dto::{
    CreateMailingSubscriptionDto,
    UpdateMailingSubscriptionDto,
    PatchMailingSubscriptionDto,
    MailingSubscriptionResponseDto,
    MailingSubscriptionListResponseDto,
    MailingSubscriptionSummaryDto,
};
pub use opt_out_reason_dto::{
    CreateOptOutReasonDto,
    UpdateOptOutReasonDto,
    PatchOptOutReasonDto,
    OptOutReasonResponseDto,
    OptOutReasonListResponseDto,
    OptOutReasonSummaryDto,
};
pub use mailing_dto::{
    CreateMailingDto,
    UpdateMailingDto,
    PatchMailingDto,
    MailingResponseDto,
    MailingListResponseDto,
    MailingSummaryDto,
};
pub use mailing_trace_dto::{
    CreateMailingTraceDto,
    UpdateMailingTraceDto,
    PatchMailingTraceDto,
    MailingTraceResponseDto,
    MailingTraceListResponseDto,
    MailingTraceSummaryDto,
};
pub use mailing_filter_dto::{
    CreateMailingFilterDto,
    UpdateMailingFilterDto,
    PatchMailingFilterDto,
    MailingFilterResponseDto,
    MailingFilterListResponseDto,
    MailingFilterSummaryDto,
};

// Common pagination types
use serde::Serialize;

#[cfg(feature = "openapi")]
#[cfg(feature = "openapi")]
use utoipa::ToSchema;

/// Pagination parameters for list requests
#[derive(Debug, Clone, Default, serde::Deserialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
pub struct PaginationParams {
    /// Page number (1-indexed)
    #[serde(default = "default_page")]
    pub page: u32,
    /// Items per page
    #[serde(default = "default_per_page")]
    pub per_page: u32,
    /// Field to sort by
    pub sort_by: Option<String>,
    /// Sort order (asc/desc)
    pub sort_order: Option<String>,
}

fn default_page() -> u32 { 1 }
fn default_per_page() -> u32 { 20 }

/// API response wrapper
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "camelCase")]
pub struct ApiResponse<T> {
    pub success: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub data: Option<T>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub error: Option<ApiError>,
}

#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
pub struct ApiError {
    pub code: String,
    pub message: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub details: Option<serde_json::Value>,
}

impl<T> ApiResponse<T> {
    pub fn ok(data: T) -> Self {
        Self { success: true, data: Some(data), error: None }
    }

    pub fn err(code: impl Into<String>, message: impl Into<String>) -> Self {
        Self {
            success: false,
            data: None,
            error: Some(ApiError {
                code: code.into(),
                message: message.into(),
                details: None,
            }),
        }
    }
}