koprogo_api/infrastructure/web/handlers/
age_request_handlers.rs1use crate::application::dto::age_request_dto::{
2 AddCosignatoryDto, CreateAgeRequestDto, SyndicResponseDto,
3};
4use crate::infrastructure::web::{AppState, AuthenticatedUser};
5use actix_web::{delete, get, post, put, web, HttpResponse, Responder};
6use uuid::Uuid;
7
8#[post("/buildings/{building_id}/age-requests")]
10pub async fn create_age_request(
11 state: web::Data<AppState>,
12 user: AuthenticatedUser,
13 path: web::Path<Uuid>,
14 body: web::Json<CreateAgeRequestDtoWithoutBuildingId>,
15) -> impl Responder {
16 let organization_id = match user.require_organization() {
17 Ok(id) => id,
18 Err(e) => {
19 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
20 }
21 };
22
23 let building_id = path.into_inner();
24 let dto = CreateAgeRequestDto {
25 building_id,
26 title: body.title.clone(),
27 description: body.description.clone(),
28 };
29
30 match state
31 .age_request_use_cases
32 .create(organization_id, user.user_id, dto)
33 .await
34 {
35 Ok(req) => HttpResponse::Created().json(req),
36 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
37 }
38}
39
40#[get("/buildings/{building_id}/age-requests")]
42pub async fn list_age_requests(
43 state: web::Data<AppState>,
44 user: AuthenticatedUser,
45 path: web::Path<Uuid>,
46) -> impl Responder {
47 let organization_id = match user.require_organization() {
48 Ok(id) => id,
49 Err(e) => {
50 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
51 }
52 };
53
54 match state
55 .age_request_use_cases
56 .list_by_building(path.into_inner(), organization_id)
57 .await
58 {
59 Ok(reqs) => HttpResponse::Ok().json(reqs),
60 Err(e) => HttpResponse::InternalServerError().json(serde_json::json!({"error": e})),
61 }
62}
63
64#[get("/age-requests/{id}")]
66pub async fn get_age_request(
67 state: web::Data<AppState>,
68 user: AuthenticatedUser,
69 path: web::Path<Uuid>,
70) -> impl Responder {
71 let organization_id = match user.require_organization() {
72 Ok(id) => id,
73 Err(e) => {
74 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
75 }
76 };
77
78 match state
79 .age_request_use_cases
80 .get(path.into_inner(), organization_id)
81 .await
82 {
83 Ok(req) => HttpResponse::Ok().json(req),
84 Err(e) => {
85 if e.contains("introuvable") {
86 HttpResponse::NotFound().json(serde_json::json!({"error": e}))
87 } else if e.contains("refusé") {
88 HttpResponse::Forbidden().json(serde_json::json!({"error": e}))
89 } else {
90 HttpResponse::InternalServerError().json(serde_json::json!({"error": e}))
91 }
92 }
93 }
94}
95
96#[put("/age-requests/{id}/open")]
98pub async fn open_age_request(
99 state: web::Data<AppState>,
100 user: AuthenticatedUser,
101 path: web::Path<Uuid>,
102) -> impl Responder {
103 let organization_id = match user.require_organization() {
104 Ok(id) => id,
105 Err(e) => {
106 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
107 }
108 };
109
110 match state
111 .age_request_use_cases
112 .open(path.into_inner(), organization_id, user.user_id)
113 .await
114 {
115 Ok(req) => HttpResponse::Ok().json(req),
116 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
117 }
118}
119
120#[post("/age-requests/{id}/cosignatories")]
122pub async fn add_cosignatory(
123 state: web::Data<AppState>,
124 user: AuthenticatedUser,
125 path: web::Path<Uuid>,
126 body: web::Json<AddCosignatoryDto>,
127) -> impl Responder {
128 let organization_id = match user.require_organization() {
129 Ok(id) => id,
130 Err(e) => {
131 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
132 }
133 };
134
135 match state
136 .age_request_use_cases
137 .add_cosignatory(path.into_inner(), organization_id, body.into_inner())
138 .await
139 {
140 Ok(req) => HttpResponse::Ok().json(req),
141 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
142 }
143}
144
145#[delete("/age-requests/{id}/cosignatories/{owner_id}")]
147pub async fn remove_cosignatory(
148 state: web::Data<AppState>,
149 user: AuthenticatedUser,
150 path: web::Path<(Uuid, Uuid)>,
151) -> impl Responder {
152 let organization_id = match user.require_organization() {
153 Ok(id) => id,
154 Err(e) => {
155 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
156 }
157 };
158
159 let (id, owner_id) = path.into_inner();
160 match state
161 .age_request_use_cases
162 .remove_cosignatory(id, owner_id, organization_id)
163 .await
164 {
165 Ok(req) => HttpResponse::Ok().json(req),
166 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
167 }
168}
169
170#[post("/age-requests/{id}/submit")]
172pub async fn submit_age_request(
173 state: web::Data<AppState>,
174 user: AuthenticatedUser,
175 path: web::Path<Uuid>,
176) -> impl Responder {
177 let organization_id = match user.require_organization() {
178 Ok(id) => id,
179 Err(e) => {
180 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
181 }
182 };
183
184 match state
185 .age_request_use_cases
186 .submit_to_syndic(path.into_inner(), organization_id, user.user_id)
187 .await
188 {
189 Ok(req) => HttpResponse::Ok().json(req),
190 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
191 }
192}
193
194#[put("/age-requests/{id}/syndic-response")]
196pub async fn syndic_response(
197 state: web::Data<AppState>,
198 user: AuthenticatedUser,
199 path: web::Path<Uuid>,
200 body: web::Json<SyndicResponseDto>,
201) -> impl Responder {
202 let organization_id = match user.require_organization() {
203 Ok(id) => id,
204 Err(e) => {
205 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
206 }
207 };
208
209 match state
210 .age_request_use_cases
211 .syndic_response(path.into_inner(), organization_id, body.into_inner())
212 .await
213 {
214 Ok(req) => HttpResponse::Ok().json(req),
215 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
216 }
217}
218
219#[post("/age-requests/{id}/auto-convocation")]
222pub async fn trigger_auto_convocation(
223 state: web::Data<AppState>,
224 user: AuthenticatedUser,
225 path: web::Path<Uuid>,
226) -> impl Responder {
227 let organization_id = match user.require_organization() {
228 Ok(id) => id,
229 Err(e) => {
230 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
231 }
232 };
233
234 match state
235 .age_request_use_cases
236 .trigger_auto_convocation(path.into_inner(), organization_id)
237 .await
238 {
239 Ok(req) => HttpResponse::Ok().json(req),
240 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
241 }
242}
243
244#[post("/age-requests/{id}/withdraw")]
246pub async fn withdraw_age_request(
247 state: web::Data<AppState>,
248 user: AuthenticatedUser,
249 path: web::Path<Uuid>,
250) -> impl Responder {
251 let organization_id = match user.require_organization() {
252 Ok(id) => id,
253 Err(e) => {
254 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
255 }
256 };
257
258 match state
259 .age_request_use_cases
260 .withdraw(path.into_inner(), organization_id, user.user_id)
261 .await
262 {
263 Ok(req) => HttpResponse::Ok().json(req),
264 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({"error": e})),
265 }
266}
267
268#[delete("/age-requests/{id}")]
270pub async fn delete_age_request(
271 state: web::Data<AppState>,
272 user: AuthenticatedUser,
273 path: web::Path<Uuid>,
274) -> impl Responder {
275 let organization_id = match user.require_organization() {
276 Ok(id) => id,
277 Err(e) => {
278 return HttpResponse::Unauthorized().json(serde_json::json!({"error": e.to_string()}))
279 }
280 };
281
282 match state
283 .age_request_use_cases
284 .delete(path.into_inner(), organization_id, user.user_id)
285 .await
286 {
287 Ok(()) => HttpResponse::NoContent().finish(),
288 Err(e) => {
289 if e.contains("introuvable") {
290 HttpResponse::NotFound().json(serde_json::json!({"error": e}))
291 } else if e.contains("refusé") {
292 HttpResponse::Forbidden().json(serde_json::json!({"error": e}))
293 } else {
294 HttpResponse::BadRequest().json(serde_json::json!({"error": e}))
295 }
296 }
297 }
298}
299
300#[derive(serde::Deserialize)]
302pub struct CreateAgeRequestDtoWithoutBuildingId {
303 pub title: String,
304 pub description: Option<String>,
305}