//! Health check and client error handlers use axum::extract::State; use axum::http::StatusCode; use axum::Json; use std::sync::Arc; use crate::core::shared::state::AppState; pub async fn health_check(State(state): State>) -> (StatusCode, Json) { let db_ok = state.conn.get().is_ok(); let status = if db_ok { "healthy" } else { "degraded" }; let code = if db_ok { StatusCode::OK } else { StatusCode::SERVICE_UNAVAILABLE }; ( code, Json(serde_json::json!({ "status": status, "service": "botserver", "version": env!("CARGO_PKG_VERSION"), "database": db_ok })), ) } pub async fn health_check_simple() -> (StatusCode, Json) { ( StatusCode::OK, Json(serde_json::json!({ "status": "ok", "service": "botserver", "version": env!("CARGO_PKG_VERSION") })), ) } #[derive(serde::Deserialize)] pub struct ClientErrorsRequest { errors: Vec, } #[derive(serde::Deserialize)] pub struct ClientErrorData { #[serde(default)] r#type: String, #[serde(default)] message: String, #[serde(default)] stack: Option, #[serde(default)] url: String, #[serde(default)] timestamp: String, } pub async fn receive_client_errors( Json(payload): Json, ) -> (StatusCode, Json) { for error in &payload.errors { log::error!( "[CLIENT ERROR] {} | {} | {} | URL: {} | Stack: {}", error.timestamp, error.r#type, error.message, error.url, error.stack.as_deref().unwrap_or("") ); } ( StatusCode::OK, Json(serde_json::json!({ "status": "received", "count": payload.errors.len() })), ) }