koprogo_api/infrastructure/web/handlers/public_handlers.rs
1use crate::application::dto::PublicSyndicInfoResponse;
2use crate::infrastructure::web::AppState;
3use actix_web::{get, web, HttpResponse, Responder};
4
5/// GET /api/v1/public/buildings/:slug/syndic
6/// Get public syndic information for a building (no authentication required)
7///
8/// This endpoint is publicly accessible to comply with Belgian law requiring
9/// syndics to display contact information publicly.
10///
11/// # Path Parameters
12/// * `slug` - URL-friendly building identifier (e.g., "residence-les-jardins-brussels")
13///
14/// # Returns
15/// * `200 OK` - Public syndic information
16/// * `404 Not Found` - Building not found or slug invalid
17/// * `500 Internal Server Error` - Database error
18///
19/// # Example
20/// ```
21/// GET /api/v1/public/buildings/residence-les-jardins-brussels/syndic
22///
23/// Response 200 OK:
24/// {
25/// "building_name": "Résidence Les Jardins",
26/// "building_address": "123 Rue de la Paix",
27/// "building_city": "Brussels",
28/// "building_postal_code": "1000",
29/// "building_country": "Belgium",
30/// "slug": "residence-les-jardins-brussels",
31/// "syndic_name": "Syndic ASBL",
32/// "syndic_email": "contact@syndic.be",
33/// "syndic_phone": "+32 2 123 4567",
34/// "syndic_address": "Avenue Louise 123, 1000 Brussels",
35/// "syndic_office_hours": "Mon-Fri 9h-17h",
36/// "syndic_emergency_contact": "+32 475 123 456",
37/// "has_syndic_info": true
38/// }
39/// ```
40#[get("/public/buildings/{slug}/syndic")]
41pub async fn get_public_syndic_info(
42 data: web::Data<AppState>,
43 slug: web::Path<String>,
44) -> impl Responder {
45 let slug = slug.into_inner();
46
47 // Find building by slug using BuildingUseCases
48 match data.building_use_cases.find_by_slug(&slug).await {
49 Ok(Some(building)) => {
50 let response = PublicSyndicInfoResponse::from(building);
51 HttpResponse::Ok().json(response)
52 }
53 Ok(None) => HttpResponse::NotFound().json(serde_json::json!({
54 "error": format!("Building not found with slug: {}", slug)
55 })),
56 Err(e) => HttpResponse::InternalServerError().json(serde_json::json!({
57 "error": format!("Failed to fetch building information: {}", e)
58 })),
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 // Note: Full integration tests with actual AppState would require proper initialization
65 // of all use cases. These handler tests are covered by E2E tests in tests/e2e/
66
67 #[test]
68 fn test_handler_structure_public_syndic() {
69 // This test just verifies the handler function signature compiles
70 // Real testing happens in E2E tests with testcontainers
71 }
72}