1use crate::services::search;
2use crate::web;
3use crate::{Config, Database};
4use anyhow::Result;
5use std::path::Path;
6use std::time::Duration;
7
8pub async fn run(config_path: &Path, host: &str, port: u16) -> Result<()> {
9 let config = Config::load(config_path)?;
10 let db = Database::open(&config.database.path)?;
11
12 if let Ok(count) = search::rebuild_fts_index(&db) {
13 tracing::info!("Search index rebuilt: {} documents indexed", count);
14 }
15
16 if config.backup.auto_enabled {
18 let backup_config = config.backup.clone();
19 let backup_site_config = config.clone();
20 tokio::spawn(async move {
21 let interval_secs = backup_config.interval_hours.max(1) * 3600;
22 let mut interval = tokio::time::interval(Duration::from_secs(interval_secs));
23 interval.tick().await;
25 loop {
26 interval.tick().await;
27 let backup_dir = std::path::Path::new(&backup_config.directory);
28 match crate::cli::backup::create_backup(&backup_site_config, backup_dir) {
29 Ok(()) => {
30 tracing::info!("Auto-backup completed successfully");
31 let _ = crate::cli::backup::enforce_retention(
32 backup_dir,
33 backup_config.retention_count,
34 );
35 }
36 Err(e) => {
37 tracing::error!("Auto-backup failed: {}", e);
38 }
39 }
40 }
41 });
42 tracing::info!(
43 "Auto-backup enabled: every {} hours, keeping {} backups in {}",
44 config.backup.interval_hours,
45 config.backup.retention_count,
46 config.backup.directory
47 );
48 }
49
50 tracing::info!("Deploying in production mode at http://{}:{}", host, port);
51 tracing::info!("Admin routes disabled, read-only mode active");
52
53 web::serve_production(&config, config_path.to_path_buf(), host, port).await
54}