//! ObserverProfile — how loudly the observer logs this workload.
//!
//! Phase 41 decomposition: the observer's alert thresholds, escalation
//! cadence, and log retention need per-workload tuning. Hot-path
//! staffing workflows want aggressive alerting; batch backfills want
//! quieter. This profile is read by mcp-server/observer.ts at
//! activation-time.

use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ObserverProfile {
    pub id: String,
    #[serde(default)]
    pub description: String,
    /// How many consecutive failures trigger a cluster escalation to
    /// LLM Team `/v1/chat` (qwen3-coder:480b).
    #[serde(default = "default_failure_cluster_size")]
    pub failure_cluster_size: u32,
    /// Minimum seconds between alert emails for the same sig_hash.
    /// Prevents alert storms during a regression.
    #[serde(default = "default_alert_cooldown")]
    pub alert_cooldown_secs: u32,
    /// Observer ring buffer size. Older events fall off when full.
    #[serde(default = "default_ring_size")]
    pub ring_size: usize,
    /// Whether to forward events to external Langfuse
    /// (/v1/langfuse_trace). Off by default.
    #[serde(default)]
    pub forward_to_langfuse: bool,
    pub created_at: chrono::DateTime<chrono::Utc>,
    #[serde(default)]
    pub created_by: String,
}

fn default_failure_cluster_size() -> u32 { 3 }
fn default_alert_cooldown() -> u32 { 300 } // 5 minutes
fn default_ring_size() -> usize { 2000 }
