koprogo_api/infrastructure/web/handlers/
marketplace_handlers.rs1use actix_web::{get, post, web, HttpResponse};
2use chrono::Datelike;
3use uuid::Uuid;
4
5use crate::application::dto::{
6 ContractEvaluationsAnnualReportDto, CreateServiceProviderDto, SearchServiceProvidersQuery,
7};
8use crate::infrastructure::web::middleware::AuthenticatedUser;
9use crate::infrastructure::web::AppState;
10
11#[get("/marketplace/providers")]
14pub async fn search_service_providers(
15 state: web::Data<AppState>,
16 query: web::Query<SearchServiceProvidersQuery>,
17) -> Result<HttpResponse, actix_web::Error> {
18 let results = state
19 .service_provider_use_cases
20 .search(&query.into_inner())
21 .await
22 .map_err(actix_web::error::ErrorInternalServerError)?;
23 Ok(HttpResponse::Ok().json(results))
24}
25
26#[get("/marketplace/providers/{slug}")]
29pub async fn get_provider_by_slug(
30 state: web::Data<AppState>,
31 slug: web::Path<String>,
32) -> Result<HttpResponse, actix_web::Error> {
33 let slug_str = slug.into_inner();
34 match state
35 .service_provider_use_cases
36 .find_by_slug(&slug_str)
37 .await
38 .map_err(actix_web::error::ErrorInternalServerError)?
39 {
40 Some(provider) => Ok(HttpResponse::Ok().json(provider)),
41 None => Ok(HttpResponse::NotFound().json(serde_json::json!({
42 "error": format!("Provider not found: {}", slug_str)
43 }))),
44 }
45}
46
47#[post("/service-providers")]
50pub async fn create_service_provider(
51 state: web::Data<AppState>,
52 request: web::Json<CreateServiceProviderDto>,
53 user: AuthenticatedUser,
54) -> Result<HttpResponse, actix_web::Error> {
55 let org_id = user
56 .organization_id
57 .ok_or_else(|| actix_web::error::ErrorBadRequest("Organization ID required"))?;
58
59 let response = state
60 .service_provider_use_cases
61 .create(org_id, request.into_inner())
62 .await
63 .map_err(actix_web::error::ErrorBadRequest)?;
64
65 Ok(HttpResponse::Created().json(response))
66}
67
68#[get("/buildings/{building_id}/reports/contract-evaluations/annual")]
71pub async fn get_contract_evaluations_annual(
72 _state: web::Data<AppState>,
73 building_id: web::Path<Uuid>,
74 web::Query(params): web::Query<std::collections::HashMap<String, String>>,
75 _user: AuthenticatedUser,
76) -> Result<HttpResponse, actix_web::Error> {
77 let building_id = building_id.into_inner();
78 let year = params
79 .get("year")
80 .and_then(|y| y.parse::<i32>().ok())
81 .unwrap_or_else(|| chrono::Local::now().year());
82
83 let report = ContractEvaluationsAnnualReportDto {
86 building_id: building_id.to_string(),
87 report_year: year,
88 total_evaluations: 0,
89 total_providers_evaluated: 0,
90 average_global_score: 0.0,
91 recommendation_rate: 0.0,
92 evaluations: vec![],
93 };
94
95 Ok(HttpResponse::Ok().json(report))
96}