//! Metrics API endpoints use axum::{ extract::{Path, Query, State}, http::StatusCode, Json, }; use chrono::{DateTime, Utc}; use serde::Deserialize; use uuid::Uuid; use crate::auth::AuthUser; use crate::db::{self, Metrics, MetricsSummary}; use crate::AppState; /// Query parameters for metrics #[derive(Debug, Deserialize)] pub struct MetricsQuery { /// Number of records to return (default: 100) pub limit: Option, /// Start time for range query pub start: Option>, /// End time for range query pub end: Option>, } /// Get metrics for a specific agent /// Requires authentication. pub async fn get_agent_metrics( State(state): State, _user: AuthUser, Path(id): Path, Query(query): Query, ) -> Result>, (StatusCode, String)> { // First verify the agent exists let _agent = db::get_agent_by_id(&state.db, id) .await .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? .ok_or((StatusCode::NOT_FOUND, "Agent not found".to_string()))?; let metrics = if let (Some(start), Some(end)) = (query.start, query.end) { // Range query db::get_agent_metrics_range(&state.db, id, start, end) .await .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? } else { // Simple limit query let limit = query.limit.unwrap_or(100).min(1000); // Cap at 1000 db::get_agent_metrics(&state.db, id, limit) .await .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))? }; Ok(Json(metrics)) } /// Get summary metrics across all agents /// Requires authentication. pub async fn get_summary( State(state): State, _user: AuthUser, ) -> Result, (StatusCode, String)> { let summary = db::get_metrics_summary(&state.db) .await .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?; Ok(Json(summary)) }