Skip to main content

chainlink/db/
sessions.rs

1use anyhow::Result;
2use chrono::Utc;
3use rusqlite::params;
4
5use super::{parse_datetime, Database};
6use crate::models::Session;
7
8impl Database {
9    /// Convenience wrapper for tests — production code uses `start_session_with_agent`.
10    #[cfg(test)]
11    pub fn start_session(&self) -> Result<i64> {
12        self.start_session_with_agent(None)
13    }
14
15    pub fn start_session_with_agent(&self, agent_id: Option<&str>) -> Result<i64> {
16        let now = Utc::now().to_rfc3339();
17        self.conn.execute(
18            "INSERT INTO sessions (started_at, agent_id) VALUES (?1, ?2)",
19            params![now, agent_id],
20        )?;
21        Ok(self.conn.last_insert_rowid())
22    }
23
24    pub fn end_session(&self, id: i64, notes: Option<&str>) -> Result<bool> {
25        let now = Utc::now().to_rfc3339();
26        let rows = self.conn.execute(
27            "UPDATE sessions SET ended_at = ?1, handoff_notes = ?2 WHERE id = ?3",
28            params![now, notes, id],
29        )?;
30        Ok(rows > 0)
31    }
32
33    pub fn get_current_session(&self) -> Result<Option<Session>> {
34        let mut stmt = self.conn.prepare(
35            "SELECT id, started_at, ended_at, active_issue_id, handoff_notes, last_action, agent_id FROM sessions WHERE ended_at IS NULL ORDER BY id DESC LIMIT 1",
36        )?;
37
38        let session = stmt
39            .query_row([], |row| {
40                Ok(Session {
41                    id: row.get(0)?,
42                    started_at: parse_datetime(row.get::<_, String>(1)?),
43                    ended_at: row.get::<_, Option<String>>(2)?.map(parse_datetime),
44                    active_issue_id: row.get(3)?,
45                    handoff_notes: row.get(4)?,
46                    last_action: row.get(5)?,
47                    agent_id: row.get(6)?,
48                })
49            })
50            .ok();
51
52        Ok(session)
53    }
54
55    pub fn get_last_session(&self) -> Result<Option<Session>> {
56        let mut stmt = self.conn.prepare(
57            "SELECT id, started_at, ended_at, active_issue_id, handoff_notes, last_action, agent_id FROM sessions WHERE ended_at IS NOT NULL ORDER BY id DESC LIMIT 1",
58        )?;
59
60        let session = stmt
61            .query_row([], |row| {
62                Ok(Session {
63                    id: row.get(0)?,
64                    started_at: parse_datetime(row.get::<_, String>(1)?),
65                    ended_at: row.get::<_, Option<String>>(2)?.map(parse_datetime),
66                    active_issue_id: row.get(3)?,
67                    handoff_notes: row.get(4)?,
68                    last_action: row.get(5)?,
69                    agent_id: row.get(6)?,
70                })
71            })
72            .ok();
73
74        Ok(session)
75    }
76
77    pub fn set_session_issue(&self, session_id: i64, issue_id: i64) -> Result<bool> {
78        let rows = self.conn.execute(
79            "UPDATE sessions SET active_issue_id = ?1 WHERE id = ?2",
80            params![issue_id, session_id],
81        )?;
82        Ok(rows > 0)
83    }
84
85    pub fn set_session_action(&self, session_id: i64, action: &str) -> Result<bool> {
86        let rows = self.conn.execute(
87            "UPDATE sessions SET last_action = ?1 WHERE id = ?2",
88            params![action, session_id],
89        )?;
90        Ok(rows > 0)
91    }
92}