//! Scheduled-prompt row shape on the wire, shared by the dashboard and //! agent surfaces (mirrors `hive-c0re`'s internal `scheduled_prompts::Schedule`). use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; /// Schedule row shape on the wire — mirror of /// `scheduled_prompts::Schedule` but in the public crate so the /// dashboard and agent surfaces can deserialize without depending /// on hive-c0re-internal types. Kept structurally identical to the /// in-process type; the conversion is field-by-field in /// `manager_server` / `dashboard`. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WireSchedule { pub id: i64, pub owner: String, pub body: String, #[serde(default, skip_serializing_if = "Option::is_none")] pub interval_seconds: Option, pub next_fire_at_unix: DateTime, pub created_at_unix: DateTime, pub source: WireScheduleSource, #[serde(default, skip_serializing_if = "Option::is_none")] pub cancelled_at_unix: Option>, /// Set while the schedule is paused. Worker skips paused rows; /// they keep their `next_fire_at_unix` so resuming at any time /// fires at the next intended instant (no catch-up clamp needed /// — a paused schedule simply slips its next fire). #[serde(default, skip_serializing_if = "Option::is_none")] pub paused_at_unix: Option>, #[serde(default, skip_serializing_if = "Option::is_none")] pub description: Option, pub targets: Vec, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(tag = "kind", rename_all = "snake_case")] pub enum WireScheduleSource { Operator, Approval { id: i64 }, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WireScheduleTarget { pub target: String, #[serde(default, skip_serializing_if = "Option::is_none")] pub cancelled_at_unix: Option>, #[serde(default, skip_serializing_if = "Option::is_none")] pub last_fired_at_unix: Option>, #[serde(default, skip_serializing_if = "Option::is_none")] pub last_result: Option, }