athena_rs 3.26.2

Hyper performant polyglot Database driver
Documentation
//! Summary-metrics extraction for `/debug/schema`.
//!
//! This module owns deriving raw aggregate counts from expected-table evaluation
//! output and canonical still-needed aggregates before health classification and
//! final summary assembly, while staged stage-input payload assembly is
//! delegated to `debug_summary_metrics_builder_stage_input_assembly`, staged
//! payload assembly is delegated to
//! `debug_summary_metrics_builder_stage_output_assembly` and final staged
//! handoff is delegated to the stable facade in
//! `debug_summary_metrics_from_builder_stage_output_assembly`, which delegates
//! to `debug_summary_metrics_builder_stage_output_handoff_assembly`, which
//! delegates contract projection to
//! `debug_summary_metrics_builder_stage_output_contract_handoff_assembly`.

use super::debug_evaluation::ExpectedTablesEvaluation;
use super::debug_still_needed::LoggingSchemaDebugStillNeeded;
use super::debug_summary_metrics_builder_stage_input_assembly::build_debug_summary_metrics_builder_stage_input_assembly;
use super::debug_summary_metrics_builder_stage_output_assembly::build_debug_summary_metrics_builder_stage_output_assembly;
use super::debug_summary_metrics_contracts::LoggingSchemaDebugSummaryMetrics;
use super::debug_summary_metrics_from_builder_stage_output_assembly::build_debug_summary_metrics_from_builder_stage_output_assembly;

/// Builds aggregate summary metrics from expected-table evaluation output.
pub(super) fn build_debug_summary_metrics(
    evaluation: &ExpectedTablesEvaluation,
    still_needed: &LoggingSchemaDebugStillNeeded,
) -> LoggingSchemaDebugSummaryMetrics {
    let stage_input =
        build_debug_summary_metrics_builder_stage_input_assembly(evaluation, still_needed);
    let stage = build_debug_summary_metrics_builder_stage_output_assembly(stage_input);
    build_debug_summary_metrics_from_builder_stage_output_assembly(stage)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::api::schema::debug_summary_test_fixtures::build_expected_table_status_for_summary_tests;

    #[test]
    /// Counts found tables directly from expected-table evaluation rows.
    fn summary_metrics_counts_found_tables_from_evaluation_rows() {
        let mut evaluation = ExpectedTablesEvaluation::default();
        evaluation.expected_tables = vec![
            build_expected_table_status_for_summary_tests(true),
            build_expected_table_status_for_summary_tests(true),
            build_expected_table_status_for_summary_tests(false),
        ];
        let still_needed = LoggingSchemaDebugStillNeeded {
            required_missing_tables: vec!["public.gateway_request_log".to_string()],
            optional_missing_tables: Vec::new(),
            required_missing_columns: vec!["public.gateway_request_log.request_id".to_string()],
            optional_missing_columns: Vec::new(),
            relation_type_mismatches: Vec::new(),
        };

        let metrics = build_debug_summary_metrics(&evaluation, &still_needed);

        assert_eq!(metrics.found_table_count, 2);
    }

    #[test]
    /// Uses canonical still-needed aggregates for missing and mismatch counts.
    fn summary_metrics_uses_still_needed_counts_for_missing_resources() {
        let mut evaluation = ExpectedTablesEvaluation::default();
        evaluation.expected_tables = vec![build_expected_table_status_for_summary_tests(true)];
        evaluation.missing_required_tables = vec!["public.gateway_request_log".to_string(); 99];
        evaluation.missing_optional_tables = vec!["public.route_request_log".to_string(); 99];
        evaluation.required_missing_column_count = 99;
        evaluation.optional_missing_column_count = 99;
        evaluation.relation_type_mismatch_count = 99;

        let still_needed = LoggingSchemaDebugStillNeeded {
            required_missing_tables: vec![
                "public.gateway_request_log".to_string(),
                "public.gateway_operation_log".to_string(),
            ],
            optional_missing_tables: vec!["public.route_request_log".to_string()],
            required_missing_columns: vec![
                "public.gateway_request_log.request_id".to_string(),
                "public.gateway_request_log.status_code".to_string(),
            ],
            optional_missing_columns: vec!["public.route_request_log.route_path".to_string()],
            relation_type_mismatches: vec!["public.route_request_log".to_string()],
        };

        let metrics = build_debug_summary_metrics(&evaluation, &still_needed);

        assert_eq!(metrics.required_missing_table_count, 2);
        assert_eq!(metrics.optional_missing_table_count, 1);
        assert_eq!(metrics.required_missing_column_count, 2);
        assert_eq!(metrics.optional_missing_column_count, 1);
        assert_eq!(metrics.relation_type_mismatch_count, 1);
    }
}