Skip to main content

allsource_core/application/dto/
tenant_dto.rs

1use crate::domain::entities::{Tenant, TenantQuotas};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6/// DTO for creating a new tenant
7#[derive(Debug, Deserialize)]
8pub struct CreateTenantRequest {
9    pub tenant_id: String,
10    pub name: String,
11    pub quotas: Option<TenantQuotasDto>,
12}
13
14/// DTO for updating a tenant
15#[derive(Debug, Deserialize)]
16pub struct UpdateTenantRequest {
17    pub name: Option<String>,
18    pub quotas: Option<TenantQuotasDto>,
19}
20
21/// DTO for tenant quotas
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct TenantQuotasDto {
24    pub max_events_per_day: Option<usize>,
25    pub max_storage_bytes: Option<u64>,
26    pub max_queries_per_hour: Option<usize>,
27    pub max_api_keys: Option<usize>,
28    pub max_projections: Option<usize>,
29    pub max_pipelines: Option<usize>,
30}
31
32impl From<TenantQuotas> for TenantQuotasDto {
33    fn from(quotas: TenantQuotas) -> Self {
34        Self {
35            max_events_per_day: if quotas.max_events_per_day() == 0 {
36                None
37            } else {
38                Some(quotas.max_events_per_day() as usize)
39            },
40            max_storage_bytes: if quotas.max_storage_bytes() == 0 {
41                None
42            } else {
43                Some(quotas.max_storage_bytes())
44            },
45            max_queries_per_hour: if quotas.max_queries_per_hour() == 0 {
46                None
47            } else {
48                Some(quotas.max_queries_per_hour() as usize)
49            },
50            max_api_keys: if quotas.max_api_keys() == 0 {
51                None
52            } else {
53                Some(quotas.max_api_keys() as usize)
54            },
55            max_projections: if quotas.max_projections() == 0 {
56                None
57            } else {
58                Some(quotas.max_projections() as usize)
59            },
60            max_pipelines: if quotas.max_pipelines() == 0 {
61                None
62            } else {
63                Some(quotas.max_pipelines() as usize)
64            },
65        }
66    }
67}
68
69impl From<TenantQuotasDto> for TenantQuotas {
70    fn from(dto: TenantQuotasDto) -> Self {
71        TenantQuotas::new(
72            dto.max_events_per_day.map_or(0, |v| v as u64),
73            dto.max_storage_bytes.unwrap_or(0),
74            dto.max_queries_per_hour.map_or(0, |v| v as u64),
75            dto.max_api_keys.map_or(0, |v| v as u32),
76            dto.max_projections.map_or(0, |v| v as u32),
77            dto.max_pipelines.map_or(0, |v| v as u32),
78        )
79    }
80}
81
82/// DTO for tenant response
83#[derive(Debug, Serialize)]
84pub struct TenantDto {
85    pub id: Uuid,
86    pub tenant_id: String,
87    pub name: String,
88    pub is_active: bool,
89    pub is_demo: bool,
90    pub quotas: TenantQuotasDto,
91    pub created_at: DateTime<Utc>,
92    pub updated_at: DateTime<Utc>,
93}
94
95impl From<&Tenant> for TenantDto {
96    fn from(tenant: &Tenant) -> Self {
97        Self {
98            id: Uuid::new_v4(), // Tenant uses TenantId as ID, not UUID
99            tenant_id: tenant.id().to_string(),
100            name: tenant.name().to_string(),
101            is_active: tenant.is_active(),
102            is_demo: tenant.is_demo(),
103            quotas: tenant.quotas().clone().into(),
104            created_at: tenant.created_at(),
105            updated_at: tenant.updated_at(),
106        }
107    }
108}
109
110impl From<Tenant> for TenantDto {
111    fn from(tenant: Tenant) -> Self {
112        TenantDto::from(&tenant)
113    }
114}
115
116/// Response for tenant creation
117#[derive(Debug, Serialize)]
118pub struct CreateTenantResponse {
119    pub tenant: TenantDto,
120}
121
122/// Response for tenant update
123#[derive(Debug, Serialize)]
124pub struct UpdateTenantResponse {
125    pub tenant: TenantDto,
126}
127
128/// Response for listing tenants
129#[derive(Debug, Serialize)]
130pub struct ListTenantsResponse {
131    pub tenants: Vec<TenantDto>,
132    pub count: usize,
133}