backbone_integrations/presentation/dto/
integration_connector_dto.rs1use 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::IntegrationConnector;
17use crate::domain::entity::AuditMetadata;
18use crate::domain::entity::ConnectorDirection;
19use crate::domain::entity::ConnectorKind;
20use crate::domain::entity::ConnectorStatus;
21
22#[derive(Debug, Clone, Deserialize)]
31#[cfg_attr(feature = "openapi", derive(ToSchema))]
32#[serde(rename_all = "camelCase")]
33pub struct CreateIntegrationConnectorDto {
34 #[cfg_attr(feature = "openapi", schema(example = "example"))]
35 pub provider: String,
36 pub kind: ConnectorKind,
37 pub direction: ConnectorDirection,
38 pub status: ConnectorStatus,
39}
40
41#[derive(Debug, Clone, Deserialize)]
50#[cfg_attr(feature = "openapi", derive(ToSchema))]
51#[serde(rename_all = "camelCase")]
52pub struct UpdateIntegrationConnectorDto {
53 #[cfg_attr(feature = "openapi", schema(example = "example"))]
54 pub provider: String,
55 pub kind: ConnectorKind,
56 pub direction: ConnectorDirection,
57 pub status: ConnectorStatus,
58}
59
60#[derive(Debug, Clone, Default, Deserialize)]
69#[cfg_attr(feature = "openapi", derive(ToSchema))]
70#[serde(rename_all = "camelCase")]
71pub struct PatchIntegrationConnectorDto {
72 #[cfg_attr(feature = "openapi", schema(example = "example"))]
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub provider: Option<String>,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub kind: Option<ConnectorKind>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub direction: Option<ConnectorDirection>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub status: Option<ConnectorStatus>,
81}
82
83impl PatchIntegrationConnectorDto {
84 pub fn has_changes(&self) -> bool {
86 self.provider.is_some() || self.kind.is_some() || self.direction.is_some() || self.status.is_some()
87 }
88}
89
90#[derive(Debug, Clone, Serialize)]
99#[cfg_attr(feature = "openapi", derive(ToSchema))]
100#[serde(rename_all = "camelCase")]
101pub struct IntegrationConnectorResponseDto {
102 #[cfg_attr(feature = "openapi", schema(example = "550e8400-e29b-41d4-a716-446655440000"))]
103 pub id: Uuid,
104 #[cfg_attr(feature = "openapi", schema(example = "example"))]
105 pub provider: String,
106 pub kind: ConnectorKind,
107 pub direction: ConnectorDirection,
108 pub status: ConnectorStatus,
109 pub metadata: AuditMetadata,
110}
111
112#[derive(Debug, Clone, Serialize)]
121#[cfg_attr(feature = "openapi", derive(ToSchema))]
122#[serde(rename_all = "camelCase")]
123pub struct IntegrationConnectorListResponseDto {
124 pub items: Vec<IntegrationConnectorResponseDto>,
126 pub total: u64,
128 pub page: u32,
130 pub per_page: u32,
132 pub total_pages: u32,
134 pub has_next: bool,
136 pub has_prev: bool,
138}
139
140impl IntegrationConnectorListResponseDto {
141 pub fn new(items: Vec<IntegrationConnectorResponseDto>, total: u64, page: u32, per_page: u32) -> Self {
143 let total_pages = if per_page > 0 {
144 ((total as f64) / (per_page as f64)).ceil() as u32
145 } else {
146 0
147 };
148 Self {
149 items,
150 total,
151 page,
152 per_page,
153 total_pages,
154 has_next: page < total_pages,
155 has_prev: page > 1,
156 }
157 }
158}
159
160#[derive(Debug, Clone, Serialize)]
162#[cfg_attr(feature = "openapi", derive(ToSchema))]
163#[serde(rename_all = "camelCase")]
164pub struct IntegrationConnectorSummaryDto {
165 pub id: Uuid,
166 pub provider: String,
167 pub kind: ConnectorKind,
168 pub direction: ConnectorDirection,
169 pub created_at: Option<DateTime<Utc>>,
170}
171
172impl From<IntegrationConnector> for IntegrationConnectorResponseDto {
177 fn from(entity: IntegrationConnector) -> Self {
178 Self {
179 id: entity.id,
180 provider: entity.provider,
181 kind: entity.kind,
182 direction: entity.direction,
183 status: entity.status,
184 metadata: entity.metadata,
185 }
186 }
187}
188
189impl From<IntegrationConnector> for IntegrationConnectorSummaryDto {
190 fn from(entity: IntegrationConnector) -> Self {
191 let created_at = backbone_core::PersistentEntity::created_at(&entity);
192 Self {
193 id: entity.id,
194 provider: entity.provider,
195 kind: entity.kind,
196 direction: entity.direction,
197 created_at,
198 }
199 }
200}
201
202impl From<CreateIntegrationConnectorDto> for IntegrationConnector {
203 fn from(dto: CreateIntegrationConnectorDto) -> Self {
204 Self {
205 id: Uuid::new_v4(),
206 provider: dto.provider,
207 kind: dto.kind,
208 direction: dto.direction,
209 status: dto.status,
210 metadata: AuditMetadata::default(),
211 }
212 }
213}
214
215impl From<&IntegrationConnector> for IntegrationConnectorResponseDto {
216 fn from(entity: &IntegrationConnector) -> Self {
217 Self {
218 id: entity.id.clone(),
219 provider: entity.provider.clone(),
220 kind: entity.kind.clone(),
221 direction: entity.direction.clone(),
222 status: entity.status.clone(),
223 metadata: entity.metadata.clone(),
224 }
225 }
226}
227
228impl backbone_core::FromCreateDto<CreateIntegrationConnectorDto> for IntegrationConnector {
229 fn from_create_dto(dto: CreateIntegrationConnectorDto) -> backbone_core::ServiceResult<Self> {
230 Ok(IntegrationConnector::from(dto))
231 }
232}
233
234impl backbone_core::ApplyUpdateDto<UpdateIntegrationConnectorDto> for IntegrationConnector {
235 fn apply_update(mut self, dto: UpdateIntegrationConnectorDto) -> backbone_core::ServiceResult<Self> {
236 self.provider = dto.provider;
237 self.kind = dto.kind;
238 self.direction = dto.direction;
239 self.status = dto.status;
240 Ok(self)
241 }
242}
243
244