#![allow(dead_code)] // Phase 2.5: consumed by Bootstrap screen //! Bootstrap screen state. //! //! Handles first-launch and empty-database scenarios. The schema //! preflight runs before the TUI event loop; the bootstrap screen //! guides users to sync when no data is available. // --------------------------------------------------------------------------- // DataReadiness // --------------------------------------------------------------------------- /// Result of checking whether the database has enough data to show the TUI. #[derive(Debug, Clone, PartialEq, Eq)] pub struct DataReadiness { /// Database has at least one issue. pub has_issues: bool, /// Database has at least one merge request. pub has_mrs: bool, /// Database has at least one search document. pub has_documents: bool, /// Current schema version from the schema_version table. pub schema_version: i32, } impl DataReadiness { /// Whether the database has any entity data at all. #[must_use] pub fn has_any_data(&self) -> bool { self.has_issues || self.has_mrs } } // --------------------------------------------------------------------------- // SchemaCheck // --------------------------------------------------------------------------- /// Result of schema version validation. #[derive(Debug, Clone, PartialEq, Eq)] pub enum SchemaCheck { /// Schema is at or above the minimum required version. Compatible { version: i32 }, /// No database or no schema_version table found. NoDB, /// Schema exists but is too old for this TUI version. Incompatible { found: i32, minimum: i32 }, } // --------------------------------------------------------------------------- // BootstrapState // --------------------------------------------------------------------------- /// State for the Bootstrap screen. #[derive(Debug, Default)] pub struct BootstrapState { /// Whether a data readiness check has completed. pub readiness: Option, /// Whether the user has initiated a sync from the bootstrap screen. pub sync_started: bool, } impl BootstrapState { /// Apply a data readiness result. pub fn apply_readiness(&mut self, readiness: DataReadiness) { self.readiness = Some(readiness); } /// Whether we have data (and should auto-transition to Dashboard). #[must_use] pub fn should_transition_to_dashboard(&self) -> bool { self.readiness .as_ref() .is_some_and(DataReadiness::has_any_data) } } // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- #[cfg(test)] mod tests { use super::*; #[test] fn test_data_readiness_has_any_data() { let empty = DataReadiness { has_issues: false, has_mrs: false, has_documents: false, schema_version: 26, }; assert!(!empty.has_any_data()); let with_issues = DataReadiness { has_issues: true, ..empty.clone() }; assert!(with_issues.has_any_data()); let with_mrs = DataReadiness { has_mrs: true, ..empty }; assert!(with_mrs.has_any_data()); } #[test] fn test_schema_check_variants() { let compat = SchemaCheck::Compatible { version: 26 }; assert!(matches!(compat, SchemaCheck::Compatible { version: 26 })); let no_db = SchemaCheck::NoDB; assert!(matches!(no_db, SchemaCheck::NoDB)); let incompat = SchemaCheck::Incompatible { found: 10, minimum: 20, }; assert!(matches!( incompat, SchemaCheck::Incompatible { found: 10, minimum: 20 } )); } #[test] fn test_bootstrap_state_default() { let state = BootstrapState::default(); assert!(state.readiness.is_none()); assert!(!state.sync_started); assert!(!state.should_transition_to_dashboard()); } #[test] fn test_bootstrap_state_apply_readiness_empty() { let mut state = BootstrapState::default(); state.apply_readiness(DataReadiness { has_issues: false, has_mrs: false, has_documents: false, schema_version: 26, }); assert!(!state.should_transition_to_dashboard()); } #[test] fn test_bootstrap_state_apply_readiness_with_data() { let mut state = BootstrapState::default(); state.apply_readiness(DataReadiness { has_issues: true, has_mrs: false, has_documents: false, schema_version: 26, }); assert!(state.should_transition_to_dashboard()); } }