Skip to main content

backbone_integrations/presentation/dto/
integration_event_dto.rs

1//! IntegrationEvent DTOs (Data Transfer Objects)
2//!
3//! Generated by metaphor-schema. Do not edit manually.
4//!
5//! DTOs provide a clean separation between domain entities and API
6//! representations, with OpenAPI documentation support.
7
8use serde::{Deserialize, Serialize};
9use uuid::Uuid;
10use chrono::{DateTime, Utc};
11
12#[cfg(feature = "openapi")]
13#[cfg(feature = "openapi")]
14use utoipa::ToSchema;
15
16use crate::domain::entity::IntegrationEvent;
17use crate::domain::entity::AuditMetadata;
18use crate::domain::entity::IntegrationStatus;
19
20// =============================================================================
21// Create DTO
22// =============================================================================
23
24/// Request DTO for creating a new IntegrationEvent
25///
26/// Used in POST requests to create new entities.
27/// Excludes auto-generated fields (id, created_at, updated_at, deleted_at).
28#[derive(Debug, Clone, Deserialize)]
29#[cfg_attr(feature = "openapi", derive(ToSchema))]
30#[serde(rename_all = "camelCase")]
31pub struct CreateIntegrationEventDto {
32    #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
33    #[serde(alias = "connector_id")]
34    pub connector_id: Uuid,
35    #[cfg_attr(feature = "openapi", schema(example = "example"))]
36    #[serde(alias = "event_type")]
37    pub event_type: String,
38    #[cfg_attr(feature = "openapi", schema(example = "example"))]
39    #[serde(alias = "external_id")]
40    pub external_id: String,
41    #[cfg_attr(feature = "openapi", schema(example = "example"))]
42    #[serde(alias = "business_key")]
43    pub business_key: String,
44    pub status: IntegrationStatus,
45    #[cfg_attr(feature = "openapi", schema(example = "example"))]
46    pub payload: String,
47    #[serde(default, skip_serializing_if = "Option::is_none", alias = "mapped_ref_type")]
48    pub mapped_ref_type: Option<String>,
49    #[serde(default, skip_serializing_if = "Option::is_none", alias = "mapped_ref_id")]
50    pub mapped_ref_id: Option<Uuid>,
51    #[serde(default, skip_serializing_if = "Option::is_none", alias = "error_detail")]
52    pub error_detail: Option<String>,
53}
54
55// =============================================================================
56// Update DTO
57// =============================================================================
58
59/// Request DTO for full update of a IntegrationEvent
60///
61/// Used in PUT requests for full entity replacement.
62/// All fields are required (except auto-generated ones).
63#[derive(Debug, Clone, Deserialize)]
64#[cfg_attr(feature = "openapi", derive(ToSchema))]
65#[serde(rename_all = "camelCase")]
66pub struct UpdateIntegrationEventDto {
67    #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
68    #[serde(alias = "connector_id")]
69    pub connector_id: Uuid,
70    #[cfg_attr(feature = "openapi", schema(example = "example"))]
71    #[serde(alias = "event_type")]
72    pub event_type: String,
73    #[cfg_attr(feature = "openapi", schema(example = "example"))]
74    #[serde(alias = "external_id")]
75    pub external_id: String,
76    #[cfg_attr(feature = "openapi", schema(example = "example"))]
77    #[serde(alias = "business_key")]
78    pub business_key: String,
79    pub status: IntegrationStatus,
80    #[cfg_attr(feature = "openapi", schema(example = "example"))]
81    pub payload: String,
82    #[serde(default, skip_serializing_if = "Option::is_none", alias = "mapped_ref_type")]
83    pub mapped_ref_type: Option<String>,
84    #[serde(default, skip_serializing_if = "Option::is_none", alias = "mapped_ref_id")]
85    pub mapped_ref_id: Option<Uuid>,
86    #[serde(default, skip_serializing_if = "Option::is_none", alias = "error_detail")]
87    pub error_detail: Option<String>,
88}
89
90// =============================================================================
91// Patch DTO
92// =============================================================================
93
94/// Request DTO for partial update of a IntegrationEvent
95///
96/// Used in PATCH requests for partial updates.
97/// All fields are optional - only provided fields will be updated.
98#[derive(Debug, Clone, Default, Deserialize)]
99#[cfg_attr(feature = "openapi", derive(ToSchema))]
100#[serde(rename_all = "camelCase")]
101pub struct PatchIntegrationEventDto {
102    #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
103    #[serde(skip_serializing_if = "Option::is_none", alias = "connector_id")]
104    pub connector_id: Option<Uuid>,
105    #[cfg_attr(feature = "openapi", schema(example = "example"))]
106    #[serde(skip_serializing_if = "Option::is_none", alias = "event_type")]
107    pub event_type: Option<String>,
108    #[cfg_attr(feature = "openapi", schema(example = "example"))]
109    #[serde(skip_serializing_if = "Option::is_none", alias = "external_id")]
110    pub external_id: Option<String>,
111    #[cfg_attr(feature = "openapi", schema(example = "example"))]
112    #[serde(skip_serializing_if = "Option::is_none", alias = "business_key")]
113    pub business_key: Option<String>,
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub status: Option<IntegrationStatus>,
116    #[cfg_attr(feature = "openapi", schema(example = "example"))]
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub payload: Option<String>,
119    #[serde(skip_serializing_if = "Option::is_none", alias = "mapped_ref_type")]
120    pub mapped_ref_type: Option<String>,
121    #[serde(skip_serializing_if = "Option::is_none", alias = "mapped_ref_id")]
122    pub mapped_ref_id: Option<Uuid>,
123    #[serde(skip_serializing_if = "Option::is_none", alias = "error_detail")]
124    pub error_detail: Option<String>,
125}
126
127impl PatchIntegrationEventDto {
128    /// Check if any field is set
129    pub fn has_changes(&self) -> bool {
130        self.connector_id.is_some() || self.event_type.is_some() || self.external_id.is_some() || self.business_key.is_some() || self.status.is_some() || self.payload.is_some() || self.mapped_ref_type.is_some() || self.mapped_ref_id.is_some() || self.error_detail.is_some()
131    }
132}
133
134// =============================================================================
135// Response DTO
136// =============================================================================
137
138/// Response DTO for IntegrationEvent entity
139///
140/// Used in API responses for single entity.
141/// Includes all fields including metadata.
142#[derive(Debug, Clone, Serialize)]
143#[cfg_attr(feature = "openapi", derive(ToSchema))]
144#[serde(rename_all = "camelCase")]
145pub struct IntegrationEventResponseDto {
146    #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
147    pub id: Uuid,
148    #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
149    pub connector_id: Uuid,
150    #[cfg_attr(feature = "openapi", schema(example = "example"))]
151    pub event_type: String,
152    #[cfg_attr(feature = "openapi", schema(example = "example"))]
153    pub external_id: String,
154    #[cfg_attr(feature = "openapi", schema(example = "example"))]
155    pub business_key: String,
156    pub status: IntegrationStatus,
157    #[cfg_attr(feature = "openapi", schema(example = "example"))]
158    pub payload: String,
159    pub mapped_ref_type: Option<String>,
160    pub mapped_ref_id: Option<Uuid>,
161    pub error_detail: Option<String>,
162    pub metadata: AuditMetadata,
163}
164
165// =============================================================================
166// List Response DTO
167// =============================================================================
168
169/// Paginated list response for IntegrationEvent entities
170///
171/// Used in API responses for list endpoints.
172/// Includes pagination metadata.
173#[derive(Debug, Clone, Serialize)]
174#[cfg_attr(feature = "openapi", derive(ToSchema))]
175#[serde(rename_all = "camelCase")]
176pub struct IntegrationEventListResponseDto {
177    /// List of items
178    pub items: Vec<IntegrationEventResponseDto>,
179    /// Total number of items (across all pages)
180    pub total: u64,
181    /// Current page number (1-indexed)
182    pub page: u32,
183    /// Number of items per page
184    pub per_page: u32,
185    /// Total number of pages
186    pub total_pages: u32,
187    /// Whether there is a next page
188    pub has_next: bool,
189    /// Whether there is a previous page
190    pub has_prev: bool,
191}
192
193impl IntegrationEventListResponseDto {
194    /// Create a new list response from items and pagination info
195    pub fn new(items: Vec<IntegrationEventResponseDto>, total: u64, page: u32, per_page: u32) -> Self {
196        let total_pages = if per_page > 0 {
197            ((total as f64) / (per_page as f64)).ceil() as u32
198        } else {
199            0
200        };
201        Self {
202            items,
203            total,
204            page,
205            per_page,
206            total_pages,
207            has_next: page < total_pages,
208            has_prev: page > 1,
209        }
210    }
211}
212
213/// Summary DTO for list views (compact version)
214#[derive(Debug, Clone, Serialize)]
215#[cfg_attr(feature = "openapi", derive(ToSchema))]
216#[serde(rename_all = "camelCase")]
217pub struct IntegrationEventSummaryDto {
218    pub id: Uuid,
219    pub connector_id: Uuid,
220    pub event_type: String,
221    pub external_id: String,
222    pub created_at: Option<DateTime<Utc>>,
223}
224
225// =============================================================================
226// Conversions
227// =============================================================================
228
229impl From<IntegrationEvent> for IntegrationEventResponseDto {
230    fn from(entity: IntegrationEvent) -> Self {
231        Self {
232            id: entity.id,
233            connector_id: entity.connector_id,
234            event_type: entity.event_type,
235            external_id: entity.external_id,
236            business_key: entity.business_key,
237            status: entity.status,
238            payload: entity.payload,
239            mapped_ref_type: entity.mapped_ref_type,
240            mapped_ref_id: entity.mapped_ref_id,
241            error_detail: entity.error_detail,
242            metadata: entity.metadata,
243        }
244    }
245}
246
247impl From<IntegrationEvent> for IntegrationEventSummaryDto {
248    fn from(entity: IntegrationEvent) -> Self {
249        let created_at = backbone_core::PersistentEntity::created_at(&entity);
250        Self {
251            id: entity.id,
252            connector_id: entity.connector_id,
253            event_type: entity.event_type,
254            external_id: entity.external_id,
255            created_at,
256        }
257    }
258}
259
260impl From<CreateIntegrationEventDto> for IntegrationEvent {
261    fn from(dto: CreateIntegrationEventDto) -> Self {
262        Self {
263            id: Uuid::new_v4(),
264            connector_id: dto.connector_id,
265            event_type: dto.event_type,
266            external_id: dto.external_id,
267            business_key: dto.business_key,
268            status: dto.status,
269            payload: dto.payload,
270            mapped_ref_type: dto.mapped_ref_type,
271            mapped_ref_id: dto.mapped_ref_id,
272            error_detail: dto.error_detail,
273            metadata: AuditMetadata::default(),
274        }
275    }
276}
277
278impl From<&IntegrationEvent> for IntegrationEventResponseDto {
279    fn from(entity: &IntegrationEvent) -> Self {
280        Self {
281            id: entity.id.clone(),
282            connector_id: entity.connector_id.clone(),
283            event_type: entity.event_type.clone(),
284            external_id: entity.external_id.clone(),
285            business_key: entity.business_key.clone(),
286            status: entity.status.clone(),
287            payload: entity.payload.clone(),
288            mapped_ref_type: entity.mapped_ref_type.clone(),
289            mapped_ref_id: entity.mapped_ref_id.clone(),
290            error_detail: entity.error_detail.clone(),
291            metadata: entity.metadata.clone(),
292        }
293    }
294}
295
296impl backbone_core::FromCreateDto<CreateIntegrationEventDto> for IntegrationEvent {
297    fn from_create_dto(dto: CreateIntegrationEventDto) -> backbone_core::ServiceResult<Self> {
298        Ok(IntegrationEvent::from(dto))
299    }
300}
301
302impl backbone_core::ApplyUpdateDto<UpdateIntegrationEventDto> for IntegrationEvent {
303    fn apply_update(mut self, dto: UpdateIntegrationEventDto) -> backbone_core::ServiceResult<Self> {
304        self.connector_id = dto.connector_id;
305        self.event_type = dto.event_type;
306        self.external_id = dto.external_id;
307        self.business_key = dto.business_key;
308        self.status = dto.status;
309        self.payload = dto.payload;
310        self.mapped_ref_type = dto.mapped_ref_type;
311        self.mapped_ref_id = dto.mapped_ref_id;
312        self.error_detail = dto.error_detail;
313        Ok(self)
314    }
315}
316
317// =============================================================================
318// Custom DTOs
319// =============================================================================
320
321// Add custom DTOs specific to IntegrationEvent here.
322// This section will be preserved during regeneration.
323// >>> END CUSTOM DTOs
324