zc2 0.0.27

P2P compute broker with credit-based billing, WAL, and broker mesh support
//! Normalized data model for the dashboard.
//!
//! Phase 1 of the terminal refactor (see `docs/TERMINAL_REFACTOR.md`).
//!
//! Both the local broker (which exposes [`crate::broker::worker::Worker`] +
//! a [`StatsCollector`]) and the remote attach mode (which fetches a
//! [`StatsResponse`] over HTTP) are reduced to a single [`Snapshot`]. The
//! dashboard renderer ([`super::monitor`]) reads only from a `Snapshot`, so
//! there is exactly one rendering code path.
//!
//! Domain metric/record types are reused verbatim; only the worker shape is
//! normalized, since local and remote disagree on its representation.

#![allow(dead_code)]

use crate::broker::stats::{BrokerMetrics, TaskOfferRecord, TransactionRecord};

/// Everything the dashboard needs to render one frame.
#[derive(Debug, Clone)]
pub struct Snapshot {
    /// Title shown in the header, e.g. "Zakuro Compute Broker".
    pub title: String,
    /// Which source produced this snapshot.
    pub mode: SourceMode,
    /// `host:port` for display.
    pub host_port: String,
    /// WireGuard IP, if connected.
    pub wireguard_ip: Option<String>,
    /// Whether the ledger (Postgres) is connected (local/P2P header dot).
    pub ledger_connected: bool,
    /// Connection state (drives the remote header dot + content fallback).
    pub connection: Connection,
    /// Aggregate broker metrics (reused verbatim).
    pub metrics: BrokerMetrics,
    /// Workers, normalized across local/remote shapes.
    pub workers: Vec<WorkerRow>,
    /// Recent transactions (reused verbatim).
    pub transactions: Vec<TransactionRecord>,
    /// Recent task offers (reused verbatim).
    pub task_offers: Vec<TaskOfferRecord>,
    /// RPS history for the sparkline.
    pub rps_history: Vec<f64>,
    /// Streaming event log (remote only; empty for local).
    pub events: Vec<String>,
}

/// Where a [`Snapshot`] came from. Drives the header badge and which panels
/// are shown (the stream panel and `r`-to-refresh are remote-only).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SourceMode {
    Local,
    P2p,
    Remote,
}

/// Connection state for the (remote) data source.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Connection {
    Connected,
    Connecting,
    Error(String),
}

/// A worker normalized from either `broker::worker::Worker` (local) or
/// `broker::stats::WorkerStats` (remote).
#[derive(Debug, Clone)]
pub struct WorkerRow {
    pub status: WorkerKind,
    pub name: String,
    pub cpus_available: f64,
    pub memory_gib: f64,
    pub avg_latency_ms: f64,
}

/// Normalized worker status.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WorkerKind {
    Healthy,
    Busy,
    Unhealthy,
    Draining,
    Unknown,
}

impl WorkerKind {
    /// Parse the remote string status (e.g. "healthy", "busy").
    pub fn from_str_status(s: &str) -> WorkerKind {
        match s {
            "healthy" => WorkerKind::Healthy,
            "busy" => WorkerKind::Busy,
            "unhealthy" => WorkerKind::Unhealthy,
            "draining" => WorkerKind::Draining,
            _ => WorkerKind::Unknown,
        }
    }

    /// Glyph shown in the workers table.
    pub fn icon(self) -> &'static str {
        match self {
            WorkerKind::Healthy => "",
            WorkerKind::Busy => "",
            WorkerKind::Unhealthy => "",
            WorkerKind::Draining => "",
            WorkerKind::Unknown => "?",
        }
    }
}