koprogo_api/infrastructure/web/handlers/
seed_handlers.rs

1use crate::infrastructure::database::DatabaseSeeder;
2use crate::infrastructure::web::AppState;
3use actix_web::{delete, post, web, HttpRequest, HttpResponse, Responder};
4
5/// Seed demo data (SuperAdmin only)
6#[post("/seed/demo")]
7pub async fn seed_demo_data(data: web::Data<AppState>, req: HttpRequest) -> impl Responder {
8    // Extract and verify token
9    let auth_header = match req.headers().get("Authorization") {
10        Some(header) => match header.to_str() {
11            Ok(s) => s,
12            Err(_) => {
13                return HttpResponse::BadRequest().json(serde_json::json!({
14                    "error": "Invalid authorization header"
15                }))
16            }
17        },
18        None => {
19            return HttpResponse::Unauthorized().json(serde_json::json!({
20                "error": "Missing authorization header"
21            }))
22        }
23    };
24
25    let token = auth_header.trim_start_matches("Bearer ").trim();
26
27    // Verify token and check role
28    match data.auth_use_cases.verify_token(token) {
29        Ok(claims) => {
30            // Only SuperAdmin can seed data
31            if claims.role != "superadmin" {
32                return HttpResponse::Forbidden().json(serde_json::json!({
33                    "error": "Only SuperAdmin can seed demo data"
34                }));
35            }
36
37            // Create seeder
38            let seeder = DatabaseSeeder::new(data.pool.clone());
39
40            // Seed demo data
41            match seeder.seed_demo_data().await {
42                Ok(message) => HttpResponse::Ok().json(serde_json::json!({
43                    "success": true,
44                    "message": message
45                })),
46                Err(e) => HttpResponse::BadRequest().json(serde_json::json!({
47                    "error": e
48                })),
49            }
50        }
51        Err(e) => HttpResponse::Unauthorized().json(serde_json::json!({
52            "error": e
53        })),
54    }
55}
56
57/// Clear demo data (SuperAdmin only)
58#[post("/seed/clear")]
59pub async fn clear_demo_data(data: web::Data<AppState>, req: HttpRequest) -> impl Responder {
60    let auth_header = match req.headers().get("Authorization") {
61        Some(header) => match header.to_str() {
62            Ok(s) => s,
63            Err(_) => {
64                return HttpResponse::BadRequest().json(serde_json::json!({
65                    "error": "Invalid authorization header"
66                }))
67            }
68        },
69        None => {
70            return HttpResponse::Unauthorized().json(serde_json::json!({
71                "error": "Missing authorization header"
72            }))
73        }
74    };
75
76    let token = auth_header.trim_start_matches("Bearer ").trim();
77
78    match data.auth_use_cases.verify_token(token) {
79        Ok(claims) => {
80            if claims.role != "superadmin" {
81                return HttpResponse::Forbidden().json(serde_json::json!({
82                    "error": "Only SuperAdmin can clear demo data"
83                }));
84            }
85
86            let seeder = DatabaseSeeder::new(data.pool.clone());
87
88            match seeder.clear_demo_data().await {
89                Ok(message) => HttpResponse::Ok().json(serde_json::json!({
90                    "success": true,
91                    "message": message
92                })),
93                Err(e) => HttpResponse::BadRequest().json(serde_json::json!({
94                    "error": e
95                })),
96            }
97        }
98        Err(e) => HttpResponse::Unauthorized().json(serde_json::json!({
99            "error": e
100        })),
101    }
102}
103
104/// Seed scenario world "Résidence du Parc Royal" (SuperAdmin only)
105#[post("/seed/scenario/world")]
106pub async fn seed_scenario_world(data: web::Data<AppState>, req: HttpRequest) -> impl Responder {
107    let auth_header = match req.headers().get("Authorization") {
108        Some(header) => match header.to_str() {
109            Ok(s) => s,
110            Err(_) => {
111                return HttpResponse::BadRequest().json(serde_json::json!({
112                    "error": "Invalid authorization header"
113                }))
114            }
115        },
116        None => {
117            return HttpResponse::Unauthorized().json(serde_json::json!({
118                "error": "Missing authorization header"
119            }))
120        }
121    };
122
123    let token = auth_header.trim_start_matches("Bearer ").trim();
124
125    match data.auth_use_cases.verify_token(token) {
126        Ok(claims) => {
127            if claims.role != "superadmin" {
128                return HttpResponse::Forbidden().json(serde_json::json!({
129                    "error": "Only SuperAdmin can seed scenario world"
130                }));
131            }
132
133            let seeder = DatabaseSeeder::new(data.pool.clone());
134
135            match seeder.seed_scenario_world().await {
136                Ok(result) => HttpResponse::Ok().json(serde_json::json!({
137                    "success": true,
138                    "message": "Scenario world seeded successfully (Résidence du Parc Royal)",
139                    "data": result
140                })),
141                Err(e) => HttpResponse::BadRequest().json(serde_json::json!({
142                    "error": e
143                })),
144            }
145        }
146        Err(e) => HttpResponse::Unauthorized().json(serde_json::json!({
147            "error": e
148        })),
149    }
150}
151
152/// Clear scenario world "Résidence du Parc Royal" (SuperAdmin only)
153#[delete("/seed/scenario/world")]
154pub async fn clear_scenario_world(data: web::Data<AppState>, req: HttpRequest) -> impl Responder {
155    let auth_header = match req.headers().get("Authorization") {
156        Some(header) => match header.to_str() {
157            Ok(s) => s,
158            Err(_) => {
159                return HttpResponse::BadRequest().json(serde_json::json!({
160                    "error": "Invalid authorization header"
161                }))
162            }
163        },
164        None => {
165            return HttpResponse::Unauthorized().json(serde_json::json!({
166                "error": "Missing authorization header"
167            }))
168        }
169    };
170
171    let token = auth_header.trim_start_matches("Bearer ").trim();
172
173    match data.auth_use_cases.verify_token(token) {
174        Ok(claims) => {
175            if claims.role != "superadmin" {
176                return HttpResponse::Forbidden().json(serde_json::json!({
177                    "error": "Only SuperAdmin can clear scenario world"
178                }));
179            }
180
181            let seeder = DatabaseSeeder::new(data.pool.clone());
182
183            match seeder.clear_scenario_world().await {
184                Ok(message) => HttpResponse::Ok().json(serde_json::json!({
185                    "success": true,
186                    "message": message
187                })),
188                Err(e) => HttpResponse::BadRequest().json(serde_json::json!({
189                    "error": e
190                })),
191            }
192        }
193        Err(e) => HttpResponse::Unauthorized().json(serde_json::json!({
194            "error": e
195        })),
196    }
197}
198
199// NOTE: Realistic seed disabled - we only use ONE seed (demo)
200// The demo seed is comprehensive enough for all testing purposes
201// Kept commented for reference if needed in the future
202
203// /// Seed realistic data for load testing (SuperAdmin only)
204// #[post("/seed/realistic")]
205// pub async fn seed_realistic_data(data: web::Data<AppState>, req: HttpRequest) -> impl Responder {
206//     let auth_header = match req.headers().get("Authorization") {
207//         Some(header) => match header.to_str() {
208//             Ok(s) => s,
209//             Err(_) => {
210//                 return HttpResponse::BadRequest().json(serde_json::json!({
211//                     "error": "Invalid authorization header"
212//                 }))
213//             }
214//         },
215//         None => {
216//             return HttpResponse::Unauthorized().json(serde_json::json!({
217//                 "error": "Missing authorization header"
218//             }))
219//         }
220//     };
221//
222//     let token = auth_header.trim_start_matches("Bearer ").trim();
223//
224//     match data.auth_use_cases.verify_token(token) {
225//         Ok(claims) => {
226//             if claims.role != "superadmin" {
227//                 return HttpResponse::Forbidden().json(serde_json::json!({
228//                     "error": "Only SuperAdmin can seed realistic data"
229//                 }));
230//             }
231//
232//             let seeder = DatabaseSeeder::new(data.pool.clone());
233//
234//             match seeder.seed_realistic_data().await {
235//                 Ok(message) => HttpResponse::Ok().json(serde_json::json!({
236//                     "success": true,
237//                     "message": message
238//                 })),
239//                 Err(e) => HttpResponse::BadRequest().json(serde_json::json!({
240//                     "error": e
241//                 })),
242//             }
243//         }
244//         Err(e) => HttpResponse::Unauthorized().json(serde_json::json!({
245//             "error": e
246//         })),
247//     }
248// }