From 7457af5e3f6c2381066128633770176eff3245a8 Mon Sep 17 00:00:00 2001 From: Ashwin Kumar Date: Mon, 6 Apr 2026 19:23:47 +0200 Subject: [PATCH] feat: add admin leads endpoint and fix routing - Customers service: add admin.rs with GET /api/admin/leads returning requirements with customer info - Update customers main.rs to mount admin router at /api/admin/leads (instead of /api/admin/requirements) - Gateway: route /api/admin/leads to customers service; remove /api/admin/requirements routing - This enables Leads Management page to fetch all platform requirements - Removed redundant /admin/requirements list page from frontend (kept detail page) --- apps/customers/src/admin.rs | 45 +++++++++++++++++++++++++++++++++++++ apps/customers/src/main.rs | 2 ++ apps/gateway/src/main.rs | 4 ++-- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 apps/customers/src/admin.rs diff --git a/apps/customers/src/admin.rs b/apps/customers/src/admin.rs new file mode 100644 index 0000000..ba819eb --- /dev/null +++ b/apps/customers/src/admin.rs @@ -0,0 +1,45 @@ +use crate::AppState; +use axum::{extract::State, http::StatusCode, response::IntoResponse, routing::get, Json, Router}; +use chrono::{DateTime, Utc}; +use serde::Serialize; +use uuid::Uuid; + +#[derive(Serialize)] +pub struct AdminLeadRow { + pub id: Uuid, + pub title: String, + pub description: Option, + pub profession: Option, + pub location: Option, + pub budget_min: Option, + pub budget_max: Option, + pub status: String, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +pub fn router() -> Router { + Router::new().route("/", get(list_leads)) +} + +async fn list_leads( + State(state): State, +) -> Result { + let leads = sqlx::query_as!( + AdminLeadRow, + r#" + SELECT + r.id, r.title, r.description, r.profession_key AS "profession", + r.location, r.budget_min, r.budget_max, r.status, + r.created_at, r.updated_at + FROM requirements r + ORDER BY r.created_at DESC + LIMIT 100 + "# + ) + .fetch_all(&state.pool) + .await + .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {e}")))?; + + Ok(Json(leads)) +} diff --git a/apps/customers/src/main.rs b/apps/customers/src/main.rs index 0c43581..b904caa 100644 --- a/apps/customers/src/main.rs +++ b/apps/customers/src/main.rs @@ -1,4 +1,5 @@ mod handlers; +mod admin; use axum::{routing::get, Router}; use std::net::SocketAddr; @@ -35,6 +36,7 @@ async fn main() { let app = Router::new() .nest("/api/customers", handlers::router()) + .nest("/api/admin/leads", admin::router()) .route("/health", get(|| async { "Customers OK" })) .with_state(state); diff --git a/apps/gateway/src/main.rs b/apps/gateway/src/main.rs index 994db92..7522d0a 100644 --- a/apps/gateway/src/main.rs +++ b/apps/gateway/src/main.rs @@ -124,10 +124,10 @@ impl Services { else if path.starts_with("/api/jobseeker") { Some(self.job_seekers_url.clone()) } - // Customers + Requirements + // Customers + Leads else if path.starts_with("/api/customers") || path.starts_with("/api/admin/customers") - || path.starts_with("/api/admin/requirements") + || path.starts_with("/api/admin/leads") { Some(self.customers_url.clone()) }