allsource_core/application/dto/
projection_dto.rs1use crate::domain::entities::{
2 Projection, ProjectionConfig, ProjectionStats, ProjectionStatus, ProjectionType,
3};
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6use uuid::Uuid;
7
8#[derive(Debug, Deserialize)]
10pub struct CreateProjectionRequest {
11 pub name: String,
12 pub projection_type: ProjectionTypeDto,
13 pub tenant_id: String,
14 pub event_types: Vec<String>,
15 pub description: Option<String>,
16 pub config: Option<ProjectionConfigDto>,
17}
18
19#[derive(Debug, Deserialize)]
21pub struct UpdateProjectionRequest {
22 pub description: Option<String>,
23 pub config: Option<ProjectionConfigDto>,
24 pub event_types: Option<Vec<String>>,
25}
26
27#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
29#[serde(rename_all = "snake_case")]
30pub enum ProjectionTypeDto {
31 EntitySnapshot,
32 EventCounter,
33 Custom,
34 TimeSeries,
35 Funnel,
36}
37
38impl From<ProjectionType> for ProjectionTypeDto {
39 fn from(ptype: ProjectionType) -> Self {
40 match ptype {
41 ProjectionType::EntitySnapshot => ProjectionTypeDto::EntitySnapshot,
42 ProjectionType::EventCounter => ProjectionTypeDto::EventCounter,
43 ProjectionType::Custom => ProjectionTypeDto::Custom,
44 ProjectionType::TimeSeries => ProjectionTypeDto::TimeSeries,
45 ProjectionType::Funnel => ProjectionTypeDto::Funnel,
46 }
47 }
48}
49
50impl From<ProjectionTypeDto> for ProjectionType {
51 fn from(dto: ProjectionTypeDto) -> Self {
52 match dto {
53 ProjectionTypeDto::EntitySnapshot => ProjectionType::EntitySnapshot,
54 ProjectionTypeDto::EventCounter => ProjectionType::EventCounter,
55 ProjectionTypeDto::Custom => ProjectionType::Custom,
56 ProjectionTypeDto::TimeSeries => ProjectionType::TimeSeries,
57 ProjectionTypeDto::Funnel => ProjectionType::Funnel,
58 }
59 }
60}
61
62#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
64#[serde(rename_all = "snake_case")]
65pub enum ProjectionStatusDto {
66 Created,
67 Running,
68 Paused,
69 Failed,
70 Stopped,
71 Rebuilding,
72}
73
74impl From<ProjectionStatus> for ProjectionStatusDto {
75 fn from(status: ProjectionStatus) -> Self {
76 match status {
77 ProjectionStatus::Created => ProjectionStatusDto::Created,
78 ProjectionStatus::Running => ProjectionStatusDto::Running,
79 ProjectionStatus::Paused => ProjectionStatusDto::Paused,
80 ProjectionStatus::Failed => ProjectionStatusDto::Failed,
81 ProjectionStatus::Stopped => ProjectionStatusDto::Stopped,
82 ProjectionStatus::Rebuilding => ProjectionStatusDto::Rebuilding,
83 }
84 }
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct ProjectionConfigDto {
90 pub batch_size: Option<usize>,
91 pub checkpoint_interval: Option<usize>,
92}
93
94impl From<ProjectionConfig> for ProjectionConfigDto {
95 fn from(config: ProjectionConfig) -> Self {
96 Self {
97 batch_size: Some(config.batch_size),
98 checkpoint_interval: Some(config.checkpoint_interval),
99 }
100 }
101}
102
103impl From<ProjectionConfigDto> for ProjectionConfig {
104 fn from(dto: ProjectionConfigDto) -> Self {
105 Self {
106 batch_size: dto.batch_size.unwrap_or(100),
107 enable_checkpoints: true,
108 checkpoint_interval: dto.checkpoint_interval.unwrap_or(1000),
109 parallel_processing: false,
110 max_concurrency: 4,
111 }
112 }
113}
114
115#[derive(Debug, Clone, Serialize)]
117pub struct ProjectionStatsDto {
118 pub events_processed: u64,
119 pub last_processed_at: Option<DateTime<Utc>>,
120 pub errors_count: u64,
121 pub last_error: Option<String>,
122 pub avg_processing_time_ms: Option<f64>,
123}
124
125impl From<&ProjectionStats> for ProjectionStatsDto {
126 fn from(stats: &ProjectionStats) -> Self {
127 Self {
128 events_processed: stats.events_processed(),
129 last_processed_at: stats.last_processed_at(),
130 errors_count: stats.errors_count(),
131 last_error: None, avg_processing_time_ms: Some(stats.avg_processing_time_ms()),
133 }
134 }
135}
136
137#[derive(Debug, Serialize)]
139pub struct ProjectionDto {
140 pub id: Uuid,
141 pub name: String,
142 pub projection_type: ProjectionTypeDto,
143 pub tenant_id: String,
144 pub status: ProjectionStatusDto,
145 pub version: u32,
146 pub event_types: Vec<String>,
147 pub description: Option<String>,
148 pub config: ProjectionConfigDto,
149 pub stats: ProjectionStatsDto,
150 pub created_at: DateTime<Utc>,
151 pub updated_at: DateTime<Utc>,
152}
153
154impl From<&Projection> for ProjectionDto {
155 fn from(projection: &Projection) -> Self {
156 Self {
157 id: projection.id(),
158 name: projection.name().to_string(),
159 projection_type: projection.projection_type().into(),
160 tenant_id: projection.tenant_id().to_string(),
161 status: projection.status().into(),
162 version: projection.version(),
163 event_types: projection
164 .event_types()
165 .iter()
166 .map(|s| s.to_string())
167 .collect(),
168 description: projection.description().map(String::from),
169 config: projection.config().clone().into(),
170 stats: projection.stats().into(),
171 created_at: projection.created_at(),
172 updated_at: projection.updated_at(),
173 }
174 }
175}
176
177impl From<Projection> for ProjectionDto {
178 fn from(projection: Projection) -> Self {
179 ProjectionDto::from(&projection)
180 }
181}
182
183#[derive(Debug, Serialize)]
185pub struct CreateProjectionResponse {
186 pub projection: ProjectionDto,
187}
188
189#[derive(Debug, Serialize)]
191pub struct ListProjectionsResponse {
192 pub projections: Vec<ProjectionDto>,
193 pub count: usize,
194}
195
196#[derive(Debug, Deserialize)]
198pub struct StartProjectionRequest {
199 pub projection_id: Uuid,
200}
201
202#[derive(Debug, Deserialize)]
204pub struct PauseProjectionRequest {
205 pub projection_id: Uuid,
206}
207
208#[derive(Debug, Deserialize)]
210pub struct RebuildProjectionRequest {
211 pub projection_id: Uuid,
212}