wsb 0.164.718

Workspace - A tool suite for file operations, version management, and development workflow automation
use crate::prelude::*;
use tokio::sync::broadcast;

use crate::logging::{LogLine, LogRingBuffer};
use crate::persist::global::{DatabaseConfig, DatabaseService, WsbRepos};

#[derive(Clone)]
pub struct AppContext {
    pub db: Arc<WsbRepos>,
    pub db_service: Arc<DatabaseService>,
    pub workspace_root: PathBuf,
}

impl AppContext {
    pub fn bootstrap(workspace_root: &Path) -> Result<Self> {
        let db_path = workspace_root.join(".wsb").join("wsb.db");
        let config = DatabaseConfig::new(&db_path);
        let service = DatabaseService::new(&config)?;
        let service = Arc::new(service);
        let repos = Arc::new(WsbRepos::new(&service));
        Ok(Self {
            db: repos,
            db_service: service,
            workspace_root: workspace_root.to_path_buf(),
        })
    }
}

#[derive(Clone)]
pub struct AppState {
    pub ctx: AppContext,
    pub debug: bool,
    pub port: u16,
    pub log_tx: broadcast::Sender<LogLine>,
    pub log_ring: LogRingBuffer,
}

impl AppState {
    pub fn new(
        ctx: AppContext,
        debug: bool,
        port: u16,
        log_tx: broadcast::Sender<LogLine>,
        log_ring: LogRingBuffer,
    ) -> Self {
        Self {
            ctx,
            debug,
            port,
            log_tx,
            log_ring,
        }
    }
}

#[derive(Clone, Debug, serde::Serialize)]
pub struct SyncProgress {
    pub phase: SyncPhase,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub current_project: Option<String>,
    pub sessions_total: usize,
    pub sessions_done: usize,
    pub messages_indexed: usize,
}

#[derive(Clone, Debug, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum SyncPhase {
    Idle,
    Discovering,
    Syncing,
    Done,
}