Skip to main content

koprogo_api/application/dto/
technical_inspection_dto.rs

1//! Technical inspection DTOs — les montants utilisent `rust_decimal::Decimal`
2//! (ADR-0007/0008).
3//!
4//! `validator` ne sait pas borner un `Decimal` : l'invariant « coût ≥ 0 » que
5//! portait `#[validate(range(min = 0.0))]` descend dans le domaine
6//! (`TechnicalInspection::set_cost`), où il couvre tous les appelants et plus
7//! seulement la route HTTP.
8//!
9//! `serde::float_option` préserve la représentation JSON numérique (un
10//! `Decimal` nu sérialiserait en chaîne) ; `default` conserve le comportement
11//! « champ absent = non modifié » d'une mise à jour partielle.
12
13use crate::domain::entities::{InspectionStatus, InspectionType};
14use rust_decimal::Decimal;
15use serde::{Deserialize, Serialize};
16use validator::Validate;
17
18#[derive(Debug, Deserialize, Validate, Clone)]
19pub struct CreateTechnicalInspectionDto {
20    pub organization_id: String,
21    pub building_id: String,
22
23    #[validate(length(min = 1, max = 255))]
24    pub title: String,
25
26    pub description: Option<String>,
27    pub inspection_type: InspectionType,
28
29    #[validate(length(min = 1, max = 255))]
30    pub inspector_name: String,
31
32    #[validate(length(max = 255))]
33    pub inspector_company: Option<String>,
34
35    #[validate(length(max = 100))]
36    pub inspector_certification: Option<String>,
37
38    pub inspection_date: String, // ISO 8601 format
39
40    pub result_summary: Option<String>,
41    pub defects_found: Option<String>,
42    pub recommendations: Option<String>,
43
44    pub compliant: Option<bool>,
45
46    #[validate(length(max = 100))]
47    pub compliance_certificate_number: Option<String>,
48
49    pub compliance_valid_until: Option<String>, // ISO 8601 format
50
51    #[serde(default, with = "rust_decimal::serde::float_option")]
52    pub cost: Option<Decimal>,
53
54    #[validate(length(max = 100))]
55    pub invoice_number: Option<String>,
56
57    pub notes: Option<String>,
58}
59
60#[derive(Debug, Deserialize, Validate, Clone)]
61pub struct UpdateTechnicalInspectionDto {
62    #[validate(length(min = 1, max = 255))]
63    pub title: Option<String>,
64
65    pub description: Option<String>,
66    pub inspection_type: Option<InspectionType>,
67
68    #[validate(length(min = 1, max = 255))]
69    pub inspector_name: Option<String>,
70
71    #[validate(length(max = 255))]
72    pub inspector_company: Option<String>,
73
74    #[validate(length(max = 100))]
75    pub inspector_certification: Option<String>,
76
77    pub inspection_date: Option<String>,
78    pub status: Option<InspectionStatus>,
79
80    pub result_summary: Option<String>,
81    pub defects_found: Option<String>,
82    pub recommendations: Option<String>,
83
84    pub compliant: Option<bool>,
85
86    #[validate(length(max = 100))]
87    pub compliance_certificate_number: Option<String>,
88
89    pub compliance_valid_until: Option<String>,
90
91    #[serde(default, with = "rust_decimal::serde::float_option")]
92    pub cost: Option<Decimal>,
93
94    #[validate(length(max = 100))]
95    pub invoice_number: Option<String>,
96
97    pub notes: Option<String>,
98}
99
100#[derive(Debug, Serialize)]
101pub struct TechnicalInspectionResponseDto {
102    pub id: String,
103    pub organization_id: String,
104    pub building_id: String,
105    pub title: String,
106    pub description: Option<String>,
107    pub inspection_type: InspectionType,
108    pub inspector_name: String,
109    pub inspector_company: Option<String>,
110    pub inspector_certification: Option<String>,
111    pub inspection_date: String,
112    pub next_due_date: String,
113    pub status: InspectionStatus,
114    pub result_summary: Option<String>,
115    pub defects_found: Option<String>,
116    pub recommendations: Option<String>,
117    pub compliant: Option<bool>,
118    pub compliance_certificate_number: Option<String>,
119    pub compliance_valid_until: Option<String>,
120    #[serde(default, with = "rust_decimal::serde::float_option")]
121    pub cost: Option<Decimal>,
122    pub invoice_number: Option<String>,
123    pub reports: Vec<String>,
124    pub photos: Vec<String>,
125    pub certificates: Vec<String>,
126    pub notes: Option<String>,
127    pub is_overdue: bool,
128    pub days_until_due: i64,
129    pub created_at: String,
130    pub updated_at: String,
131}
132
133#[derive(Debug, Deserialize, Validate)]
134pub struct AddReportDto {
135    #[validate(length(min = 1))]
136    pub report_path: String,
137}
138
139#[derive(Debug, Deserialize, Validate)]
140pub struct AddInspectionPhotoDto {
141    #[validate(length(min = 1))]
142    pub photo_path: String,
143}
144
145#[derive(Debug, Deserialize, Validate)]
146pub struct AddCertificateDto {
147    #[validate(length(min = 1))]
148    pub certificate_path: String,
149}
150
151#[derive(Debug, Serialize)]
152pub struct TechnicalInspectionListResponseDto {
153    pub inspections: Vec<TechnicalInspectionResponseDto>,
154    pub total: i64,
155    pub page: i64,
156    pub page_size: i64,
157}
158
159#[derive(Debug, Serialize)]
160pub struct InspectionStatusDto {
161    pub inspection_id: String,
162    pub title: String,
163    pub inspection_type: InspectionType,
164    pub next_due_date: String,
165    pub status: InspectionStatus,
166    pub is_overdue: bool,
167    pub days_until_due: i64,
168}