use axum::{Json, extract::State};
use fraiseql_core::db::traits::DatabaseAdapter;
use serde::{Deserialize, Serialize};
use crate::routes::graphql::app_state::AppState;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AdminHealthResponse {
pub uptime_secs: u64,
pub version: String,
pub pool_active: u32,
pub pool_idle: u32,
pub pool_max: u32,
pub cache_hit_rate: Option<f64>,
pub cache_entries: Option<u64>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AdminSchemaResponse {
pub schema: serde_json::Value,
}
#[must_use]
pub fn extract_bearer_token(auth_header: Option<&str>) -> Option<&str> {
let header = auth_header?;
header.strip_prefix("Bearer ")
}
pub async fn schema_handler<A>(
State(state): State<AppState<A>>,
) -> impl axum::response::IntoResponse
where
A: DatabaseAdapter + Clone + Send + Sync + 'static,
{
let schema = state.executor.load().schema().clone();
let value = serde_json::to_value(&schema).unwrap_or(serde_json::Value::Null);
Json(AdminSchemaResponse { schema: value })
}
pub async fn health_handler<A>(
State(_state): State<AppState<A>>,
) -> impl axum::response::IntoResponse
where
A: DatabaseAdapter + Clone + Send + Sync + 'static,
{
let uptime_secs = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
Json(AdminHealthResponse {
uptime_secs,
version: env!("CARGO_PKG_VERSION").to_string(),
pool_active: 0,
pool_idle: 0,
pool_max: 0,
cache_hit_rate: None,
cache_entries: None,
})
}