koprogo_api/application/dto/board_alert_dto.rs
1use serde::{Deserialize, Serialize};
2use validator::Validate;
3
4/// DTO pour créer une alerte du conseil de copropriété (Story 4.7 / #582).
5///
6/// `building_id` n'y figure pas : il vient du chemin de la route
7/// (`/buildings/{building_id}/cdc/alerts`), pas du corps — une route scopée
8/// ne doit pas laisser le corps affirmer un autre immeuble que celui de
9/// l'URL.
10///
11/// `target_meeting_id` est fourni par l'appelant plutôt que résolu
12/// automatiquement — cf. `CdcUseCases::create_alert` pour la justification.
13#[derive(Debug, Serialize, Deserialize, Validate, Clone, utoipa::ToSchema)]
14pub struct CreateBoardAlertDto {
15 #[validate(length(min = 1, message = "Alert text cannot be empty"))]
16 pub text: String,
17
18 /// "info", "warning" ou "critical".
19 pub severity: String,
20
21 pub target_meeting_id: String,
22}
23
24/// DTO pour la réponse API d'une alerte du conseil.
25#[derive(Debug, Serialize, Deserialize, Clone, utoipa::ToSchema)]
26pub struct BoardAlertResponseDto {
27 pub id: String,
28 pub building_id: String,
29 pub raised_by_board_member_id: String,
30 pub text: String,
31 pub severity: String,
32 pub target_meeting_id: String,
33 pub created_at: String,
34}
35
36/// Un candidat à élire au conseil de copropriété.
37#[derive(Debug, Serialize, Deserialize, Validate, Clone, utoipa::ToSchema)]
38pub struct CdcCandidateDto {
39 pub owner_id: String,
40 pub position: String, // "president", "treasurer" ou "member"
41}
42
43/// DTO pour élire les membres du conseil à l'issue d'une AG (Story 4.7).
44///
45/// `building_id` vient du chemin (`/buildings/{building_id}/cdc/elections`),
46/// pas du corps — même raison que `CreateBoardAlertDto`.
47///
48/// L'AG référencée par `meeting_id` doit être `Completed` : sa clôture
49/// prouve déjà le quorum double (Art. 3.87 §5 CC) via
50/// `Meeting::assert_can_complete`. Cf. `CdcUseCases::elect_members`.
51#[derive(Debug, Serialize, Deserialize, Validate, Clone, utoipa::ToSchema)]
52pub struct ElectCdcMembersDto {
53 pub meeting_id: String,
54 #[validate(length(min = 1, message = "At least one candidate is required"))]
55 pub candidates: Vec<CdcCandidateDto>,
56}