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