athena_rs 3.26.1

Hyper performant polyglot Database driver
Documentation
//! Still-needed diagnostics aggregation for `/debug/schema`.
//!
//! This module derives normalized unresolved-requirement lists from
//! expected-table evaluation output so operators can quickly identify what the
//! logging schema still needs, while final payload assembly is delegated to
//! `debug_still_needed_output_assembly`.

use super::debug_evaluation::ExpectedTablesEvaluation;
pub use super::debug_still_needed_contracts::LoggingSchemaDebugStillNeeded;
use super::debug_still_needed_missing_columns::collect_missing_column_keys;
use super::debug_still_needed_missing_tables::collect_missing_table_keys;
use super::debug_still_needed_output_assembly::build_logging_schema_debug_still_needed_output;
use super::debug_still_needed_relation_mismatches::collect_relation_type_mismatch_keys;

/// Builds unresolved-requirement diagnostics from expected-table evaluation state.
pub(super) fn build_logging_schema_debug_still_needed(
    evaluation: &ExpectedTablesEvaluation,
) -> LoggingSchemaDebugStillNeeded {
    let (required_missing_tables, optional_missing_tables) = collect_missing_table_keys(evaluation);

    build_logging_schema_debug_still_needed_output(
        required_missing_tables,
        optional_missing_tables,
        collect_missing_column_keys(evaluation, true),
        collect_missing_column_keys(evaluation, false),
        collect_relation_type_mismatch_keys(evaluation),
    )
}

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

    /// Builds one expected-table status row for still-needed aggregation tests.
    fn expected_table_status(
        schema: &str,
        table: &str,
        required: bool,
        found: bool,
        relation_type_matches: bool,
        missing_columns: Vec<&str>,
    ) -> LoggingSchemaExpectedTableStatus {
        LoggingSchemaExpectedTableStatus {
            table_schema: schema.to_string(),
            table_name: table.to_string(),
            expected_relation_type: "BASE TABLE".to_string(),
            required,
            purpose: "test".to_string(),
            expected_columns: vec!["id".to_string()],
            found,
            found_relation_type: if found {
                Some("BASE TABLE".to_string())
            } else {
                None
            },
            relation_type_matches,
            found_columns: if found {
                vec!["id".to_string()]
            } else {
                Vec::new()
            },
            missing_columns: missing_columns
                .into_iter()
                .map(|value| value.to_string())
                .collect(),
            unexpected_columns: Vec::new(),
        }
    }

    #[test]
    /// Aggregates required/optional unresolved lists and relation mismatches deterministically.
    fn still_needed_aggregates_missing_tables_columns_and_relation_mismatches() {
        let mut evaluation = ExpectedTablesEvaluation::default();
        evaluation.missing_required_tables = vec![
            "public.gateway_request_log".to_string(),
            "public.gateway_request_log".to_string(),
        ];
        evaluation.missing_optional_tables = vec![
            "public.route_request_log".to_string(),
            "public.route_request_log".to_string(),
        ];
        evaluation.expected_tables = vec![
            expected_table_status(
                "public",
                "gateway_request_log",
                true,
                false,
                false,
                vec!["request_id", "status_code"],
            ),
            expected_table_status(
                "public",
                "route_request_log",
                false,
                true,
                false,
                vec!["route_path"],
            ),
        ];

        let still_needed = build_logging_schema_debug_still_needed(&evaluation);

        assert_eq!(
            still_needed.required_missing_tables,
            vec!["public.gateway_request_log".to_string()]
        );
        assert_eq!(
            still_needed.optional_missing_tables,
            vec!["public.route_request_log".to_string()]
        );
        assert_eq!(
            still_needed.required_missing_columns,
            vec![
                "public.gateway_request_log.request_id".to_string(),
                "public.gateway_request_log.status_code".to_string(),
            ]
        );
        assert_eq!(
            still_needed.optional_missing_columns,
            vec!["public.route_request_log.route_path".to_string()]
        );
        assert_eq!(
            still_needed.relation_type_mismatches,
            vec!["public.route_request_log".to_string()]
        );
    }
}