litellm-rs 0.6.0

A high-performance AI Gateway written in Rust, providing OpenAI-compatible APIs with intelligent routing, load balancing, and enterprise features
Documentation
//! Report generation system

use crate::storage::database::Database;
use crate::utils::error::gateway_error::{GatewayError, Result};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Report generator for creating detailed reports
pub struct ReportGenerator {
    /// Report templates
    templates: HashMap<String, ReportTemplate>,
}

/// Report template
#[derive(Debug, Clone)]
pub struct ReportTemplate {
    /// Template name
    pub name: String,
    /// Template description
    pub description: String,
    /// Report sections
    pub sections: Vec<ReportSection>,
    /// Output format
    pub format: ReportFormat,
}

/// Report section
#[derive(Debug, Clone)]
pub struct ReportSection {
    /// Section title
    pub title: String,
    /// Section type
    pub section_type: ReportSectionType,
    /// Data queries
    pub queries: Vec<String>,
}

/// Types of report sections
#[derive(Debug, Clone)]
pub enum ReportSectionType {
    /// Summary section
    Summary,
    /// Chart section
    Chart,
    /// Table section
    Table,
    /// Metrics section
    Metrics,
    /// Recommendations section
    Recommendations,
}

/// Report output formats
#[derive(Debug, Clone)]
pub enum ReportFormat {
    /// PDF format
    Pdf,
    /// HTML format
    Html,
    /// JSON format
    Json,
    /// CSV format
    Csv,
    /// Excel format
    Excel,
}

/// Generated report
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GeneratedReport {
    /// Report ID
    pub id: String,
    /// Report title
    pub title: String,
    /// Generation timestamp
    pub generated_at: DateTime<Utc>,
    /// Report period
    pub period_start: DateTime<Utc>,
    /// End of report period
    pub period_end: DateTime<Utc>,
    /// Report sections
    pub sections: Vec<ReportSectionData>,
    /// Summary statistics
    pub summary: ReportSummary,
}

/// Report section data
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReportSectionData {
    /// Section title
    pub title: String,
    /// Section data
    pub data: serde_json::Value,
    /// Charts or visualizations
    pub charts: Vec<ChartData>,
}

/// Chart data for visualizations
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChartData {
    /// Chart type
    pub chart_type: String,
    /// Chart title
    pub title: String,
    /// Data points
    pub data: Vec<DataPoint>,
    /// Chart configuration
    pub config: serde_json::Value,
}

/// Data point for charts
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataPoint {
    /// X-axis value
    pub x: serde_json::Value,
    /// Y-axis value
    pub y: serde_json::Value,
    /// Additional metadata
    pub metadata: Option<serde_json::Value>,
}

/// Report summary
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReportSummary {
    /// Total requests
    pub total_requests: u64,
    /// Total cost
    pub total_cost: f64,
    /// Average response time
    pub avg_response_time: f64,
    /// Success rate
    pub success_rate: f64,
    /// Top insights
    pub key_insights: Vec<String>,
    /// Recommendations
    pub recommendations: Vec<String>,
}

impl Default for ReportGenerator {
    fn default() -> Self {
        Self::new()
    }
}

impl ReportGenerator {
    /// Create a new report generator
    pub fn new() -> Self {
        Self {
            templates: Self::default_templates(),
        }
    }

    /// Generate a report
    pub async fn generate(
        &self,
        template_name: &str,
        _user_id: Option<&str>,
        start_date: DateTime<Utc>,
        end_date: DateTime<Utc>,
        _database: &Database,
    ) -> Result<GeneratedReport> {
        let template = self
            .templates
            .get(template_name)
            .ok_or_else(|| GatewayError::NotFound("Report template not found".to_string()))?;

        // Generate report sections
        let sections = Vec::new(); // Implement section generation

        Ok(GeneratedReport {
            id: uuid::Uuid::new_v4().to_string(),
            title: template.name.clone(),
            generated_at: Utc::now(),
            period_start: start_date,
            period_end: end_date,
            sections,
            summary: ReportSummary {
                total_requests: 0,
                total_cost: 0.0,
                avg_response_time: 0.0,
                success_rate: 0.0,
                key_insights: Vec::new(),
                recommendations: Vec::new(),
            },
        })
    }

    /// Get available templates
    pub fn templates(&self) -> &HashMap<String, ReportTemplate> {
        &self.templates
    }

    /// Default report templates
    fn default_templates() -> HashMap<String, ReportTemplate> {
        let mut templates = HashMap::new();

        templates.insert(
            "usage_summary".to_string(),
            ReportTemplate {
                name: "Usage Summary Report".to_string(),
                description: "Comprehensive usage and cost summary".to_string(),
                sections: vec![
                    ReportSection {
                        title: "Executive Summary".to_string(),
                        section_type: ReportSectionType::Summary,
                        queries: vec!["summary_stats".to_string()],
                    },
                    ReportSection {
                        title: "Cost Analysis".to_string(),
                        section_type: ReportSectionType::Chart,
                        queries: vec!["cost_trends".to_string()],
                    },
                ],
                format: ReportFormat::Pdf,
            },
        );

        templates
    }
}

#[cfg(test)]
#[path = "reports_tests.rs"]
mod tests;