use serde::{Deserialize, Serialize};
use std::sync::Arc;
use crate::{
common::{ApiError, ApiResponse},
endpoints,
security::AuthContext,
v1::dtos::{HealthCheckResponseV1, ReadinessCheckResponseV1},
};
use feagi_services::AnalyticsService;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZmqRequest {
pub method: String,
pub path: String,
pub body: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ZmqResponse {
pub status: u16,
pub body: serde_json::Value,
}
#[derive(Clone)]
pub struct ZmqApiState {
pub analytics_service: Arc<dyn AnalyticsService + Send + Sync>,
}
pub async fn route_zmq_request(
request: ZmqRequest,
state: &ZmqApiState,
) -> ZmqResponse {
let auth_ctx = AuthContext::anonymous();
match (request.method.as_str(), request.path.as_str()) {
("GET", "/health") | ("GET", "/v1/system/health_check") => {
handle_health_check(&auth_ctx, state).await
}
("GET", "/ready") | ("GET", "/v1/system/readiness_check") => {
handle_readiness_check(&auth_ctx, state).await
}
_ => {
let error = ApiError::not_found("Endpoint", &request.path);
ZmqResponse {
status: 404,
body: serde_json::to_value(error).unwrap_or(serde_json::json!({"detail": "Not found"})),
}
}
}
}
async fn handle_health_check(
auth_ctx: &AuthContext,
state: &ZmqApiState,
) -> ZmqResponse {
match endpoints::health::health_check(auth_ctx, state.analytics_service.clone()).await {
Ok(health_data) => {
let response: ApiResponse<HealthCheckResponseV1> = ApiResponse::success(health_data);
ZmqResponse {
status: 200,
body: serde_json::to_value(response).unwrap_or(serde_json::json!({"success": false})),
}
}
Err(error) => {
ZmqResponse {
status: 500,
body: serde_json::to_value(error).unwrap_or(serde_json::json!({"detail": "Internal error"})),
}
}
}
}
async fn handle_readiness_check(
auth_ctx: &AuthContext,
state: &ZmqApiState,
) -> ZmqResponse {
match endpoints::health::readiness_check(auth_ctx, state.analytics_service.clone()).await {
Ok(readiness_data) => {
let response: ApiResponse<ReadinessCheckResponseV1> = ApiResponse::success(readiness_data);
ZmqResponse {
status: 200,
body: serde_json::to_value(response).unwrap_or(serde_json::json!({"success": false})),
}
}
Err(error) => {
ZmqResponse {
status: 500,
body: serde_json::to_value(error).unwrap_or(serde_json::json!({"detail": "Internal error"})),
}
}
}
}
pub async fn handle_api_control_request(
method: String,
path: String,
body: Option<serde_json::Value>,
state: &ZmqApiState,
) -> ZmqResponse {
let request = ZmqRequest { method, path, body };
route_zmq_request(request, state).await
}