Skip to main content

brainos_backends/
scheduling.rs

1//! Scheduling backend — persists scheduled intents to SQLite.
2
3#[derive(Clone)]
4pub struct DefaultSchedulingBackend {
5    pub db: storage::SqlitePool,
6    pub mode: brain_core::config::SchedulingMode,
7}
8
9#[async_trait::async_trait]
10impl cortex::actions::SchedulingBackend for DefaultSchedulingBackend {
11    async fn schedule(
12        &self,
13        description: &str,
14        cron: Option<&str>,
15        namespace: &str,
16    ) -> Result<cortex::actions::ScheduleOutcome, cortex::actions::ActionError> {
17        if self.mode != brain_core::config::SchedulingMode::PersistOnly {
18            return Err(cortex::actions::ActionError::InvalidArguments(format!(
19                "Unsupported scheduling mode: {:?}",
20                self.mode
21            )));
22        }
23
24        let metadata = serde_json::json!({
25            "source": "action_dispatcher",
26            "mode": "persist_only",
27        })
28        .to_string();
29
30        let schedule_id = self
31            .db
32            .insert_scheduled_intent(description, cron, namespace, Some(&metadata))
33            .map_err(|e| cortex::actions::ActionError::ExecutionFailed(e.to_string()))?;
34
35        Ok(cortex::actions::ScheduleOutcome {
36            schedule_id,
37            status: "scheduled".to_string(),
38        })
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    #[tokio::test]
47    async fn test_scheduling_backend_persists_intent() {
48        let db = storage::SqlitePool::open_memory().unwrap();
49        let backend = DefaultSchedulingBackend {
50            db: db.clone(),
51            mode: brain_core::config::SchedulingMode::PersistOnly,
52        };
53
54        let outcome = cortex::actions::SchedulingBackend::schedule(
55            &backend,
56            "ship release",
57            Some("0 9 * * 1-5"),
58            "work",
59        )
60        .await
61        .unwrap();
62
63        assert_eq!(outcome.status, "scheduled");
64        let intents = db.list_scheduled_intents(Some("work")).unwrap();
65        assert_eq!(intents.len(), 1);
66        assert_eq!(intents[0].id, outcome.schedule_id);
67        assert_eq!(intents[0].description, "ship release");
68    }
69}