darpan 0.2.0

Linux developer service monitoring utility with auto-detection, real-time health checks, and interactive TUI for databases, APIs, Docker containers, and more
Documentation
use crate::models::health::{HealthCheckConfig, HealthResult};
use chrono::{DateTime, Utc, Duration};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Service {
    /// Unique identifier (auto-generated)
    pub id: String,
    
    /// Display name
    pub name: String,
    
    /// Service type
    pub service_type: ServiceType,
    
    /// How this service was detected
    pub source: DetectionSource,
    
    /// Host (usually localhost)
    pub host: String,
    
    /// Primary port
    pub port: u16,
    
    /// Additional ports used by this service
    pub additional_ports: Vec<u16>,
    
    /// Process ID (if applicable)
    pub pid: Option<u32>,
    
    /// Process name
    pub process_name: Option<String>,
    
    /// Full command line
    pub command_line: Option<String>,
    
    /// Docker container ID (for log streaming)
    pub container_id: Option<String>,
    
    /// Systemd unit name (for journalctl logs)
    pub systemd_unit: Option<String>,
    
    /// Custom log file path
    pub log_file_path: Option<String>,
    
    /// Health check configuration
    pub health_check: HealthCheckConfig,
    
    /// Project path
    pub project_path: String,
    
    /// Tags for categorization
    pub tags: Vec<String>,
    
    /// Service IDs this depends on
    pub dependencies: Vec<String>,
    
    /// Current health status
    #[serde(skip)]
    pub health_status: Option<HealthResult>,
    
    /// When the service was first detected
    pub first_seen: DateTime<Utc>,
    
    /// When the service was last seen healthy
    pub last_seen: DateTime<Utc>,
}

impl Service {
    pub fn new(
        name: String,
        service_type: ServiceType,
        host: String,
        port: u16,
        source: DetectionSource,
        project_path: String,
    ) -> Self {
        let now = Utc::now();
        let id = format!("{}:{}", name.to_lowercase().replace(' ', "-"), port);
        
        Self {
            id,
            name,
            service_type,
            source,
            host,
            port,
            additional_ports: Vec::new(),
            pid: None,
            process_name: None,
            command_line: None,
            container_id: None,
            systemd_unit: None,
            log_file_path: None,
            health_check: HealthCheckConfig::default(),
            project_path,
            tags: Vec::new(),
            dependencies: Vec::new(),
            health_status: None,
            first_seen: now,
            last_seen: now,
        }
    }

    pub fn is_healthy(&self) -> bool {
        self.health_status
            .as_ref()
            .map(|h| matches!(h.status, crate::models::HealthStatus::Healthy))
            .unwrap_or(false)
    }

    pub fn uptime(&self) -> Duration {
        Utc::now() - self.first_seen
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum ServiceType {
    HttpServer,
    Database(DatabaseType),
    MessageQueue(QueueType),
    Cache(CacheType),
    Search(SearchType),
    DockerContainer,
    Custom,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DatabaseType {
    Postgres,
    MySQL,
    MongoDB,
    SQLite,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum QueueType {
    RabbitMQ,
    Kafka,
    Redis,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum CacheType {
    Redis,
    Memcached,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum SearchType {
    Elasticsearch,
    Meilisearch,
    Typesense,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum DetectionSource {
    ExplicitConfig,
    DockerCompose,
    PortScan,
    ProcessScan,
    AutoDetected,
}