metis_core/application/
mod.rs1pub mod services;
2
3use crate::dal::Database;
4use crate::{MetisError, Result};
5use std::path::Path;
6
7pub struct Application {
10 database: Database,
11}
12
13impl Application {
14 pub fn new(database: Database) -> Self {
16 Self { database }
17 }
18
19 pub fn with_database<F, R>(&mut self, f: F) -> R
21 where
22 F: FnOnce(&mut services::DatabaseService) -> R,
23 {
24 let repository = self
25 .database
26 .repository()
27 .expect("Failed to get database repository");
28 let mut service = services::DatabaseService::new(repository);
29 f(&mut service)
30 }
31
32 pub fn with_sync<F, R>(&mut self, f: F) -> R
34 where
35 F: FnOnce(&mut services::SyncService) -> R,
36 {
37 let repository = self
38 .database
39 .repository()
40 .expect("Failed to get database repository");
41 let mut db_service = services::DatabaseService::new(repository);
42 let mut sync_service = services::SyncService::new(&mut db_service);
43 f(&mut sync_service)
44 }
45
46 pub async fn sync_directory<P: AsRef<Path>>(
54 self,
55 dir_path: P,
56 ) -> Result<Vec<services::synchronization::SyncResult>> {
57 let workspace_path = dir_path.as_ref().to_path_buf();
58 let db_path = workspace_path.join("metis.db");
59
60 if services::workspace::ConfigurationRecoveryService::needs_recovery(&workspace_path) {
62 tracing::warn!("Database recovery needed, initiating full recovery");
63
64 if !db_path.exists() {
66 tracing::info!("Creating new database at {}", db_path.display());
67 let _ = Database::new(db_path.to_str().unwrap())
68 .map_err(|e| MetisError::FileSystem(e.to_string()))?;
69 }
70
71 let report = services::workspace::ConfigurationRecoveryService::recover_configuration(
73 &workspace_path,
74 &db_path,
75 )?;
76
77 if report.had_recovery_actions() {
78 tracing::info!(
79 "Recovery complete: config_created={}, prefix_synced={}, flight_levels_synced={}, counters_recovered={}",
80 report.config_file_created,
81 report.prefix_synced,
82 report.flight_levels_synced,
83 report.counters_recovered
84 );
85 }
86 } else {
87 match services::workspace::ConfigurationRecoveryService::sync_config_to_database(
89 &workspace_path,
90 &db_path,
91 ) {
92 Ok(synced) => {
93 if synced {
94 tracing::info!("Synced configuration from config.toml to database");
95 }
96 }
97 Err(e) => {
98 tracing::warn!("Failed to sync configuration: {}, continuing with file sync", e);
99 }
100 }
101 }
102
103 let mut db_service = services::DatabaseService::new(self.database.into_repository());
105 let mut sync_service =
106 services::SyncService::new(&mut db_service).with_workspace_dir(&workspace_path);
107 sync_service.sync_directory(dir_path).await
108 }
109
110 pub fn database(&mut self) -> &mut Database {
112 &mut self.database
113 }
114}