mi6_core/model/session/
query.rs

1//! Session query types and builders.
2//!
3//! This module provides types for querying sessions:
4//! - [`SessionOrder`]: Field to order results by
5//! - [`SessionQuery`]: Fluent builder for constructing queries
6
7use chrono::{DateTime, Utc};
8
9use super::super::Order;
10
11/// Sort order for session queries
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
13pub enum SessionOrder {
14    /// Order by session start time (default: newest first)
15    #[default]
16    StartedAt,
17    /// Order by last activity time
18    LastActivity,
19    /// Order by total cost
20    Cost,
21}
22
23/// Query builder for session retrieval.
24///
25/// `SessionQuery` provides a fluent API for constructing session queries
26/// with filters, ordering, and pagination.
27///
28/// Default ordering is newest first (descending by started_at).
29#[derive(Clone)]
30pub struct SessionQuery {
31    /// Filter by machine_id (for multi-machine scenarios)
32    pub machine_id: Option<String>,
33
34    /// Filter by framework (claude, cursor, gemini, codex)
35    pub framework: Option<String>,
36
37    /// Filter to only active sessions (ended_at IS NULL)
38    pub active_only: bool,
39
40    /// Filter sessions with activity after this timestamp
41    pub active_since: Option<DateTime<Utc>>,
42
43    /// Filter sessions started after this timestamp
44    pub started_after: Option<DateTime<Utc>>,
45
46    /// Filter sessions started before this timestamp
47    pub started_before: Option<DateTime<Utc>>,
48
49    /// Filter by GitHub repository (owner/repo format)
50    pub github_repo: Option<String>,
51
52    /// Filter by GitHub issue number
53    pub github_issue: Option<i32>,
54
55    /// Filter by GitHub PR number
56    pub github_pr: Option<i32>,
57
58    /// Maximum number of sessions to return
59    pub limit: Option<usize>,
60
61    /// Order by field
62    pub order_by: SessionOrder,
63
64    /// Sort direction (default: Desc for newest first)
65    pub direction: Order,
66}
67
68impl Default for SessionQuery {
69    fn default() -> Self {
70        Self {
71            machine_id: None,
72            framework: None,
73            active_only: false,
74            active_since: None,
75            started_after: None,
76            started_before: None,
77            github_repo: None,
78            github_issue: None,
79            github_pr: None,
80            limit: None,
81            order_by: SessionOrder::default(),
82            direction: Order::Desc, // Default to newest first
83        }
84    }
85}
86
87impl SessionQuery {
88    /// Create a new empty query (defaults to recent sessions first)
89    pub fn new() -> Self {
90        Self::default()
91    }
92
93    /// Filter to only active sessions
94    pub fn active_only(mut self) -> Self {
95        self.active_only = true;
96        self
97    }
98
99    /// Filter by machine_id (for multi-machine scenarios)
100    pub fn with_machine_id(mut self, machine_id: impl Into<String>) -> Self {
101        self.machine_id = Some(machine_id.into());
102        self
103    }
104
105    /// Filter by framework
106    pub fn with_framework(mut self, framework: impl Into<String>) -> Self {
107        self.framework = Some(framework.into());
108        self
109    }
110
111    /// Filter sessions with activity since the given timestamp
112    pub fn with_active_since(mut self, ts: DateTime<Utc>) -> Self {
113        self.active_since = Some(ts);
114        self
115    }
116
117    /// Filter sessions started after the given timestamp
118    pub fn with_started_after(mut self, ts: DateTime<Utc>) -> Self {
119        self.started_after = Some(ts);
120        self
121    }
122
123    /// Filter sessions started before the given timestamp
124    pub fn with_started_before(mut self, ts: DateTime<Utc>) -> Self {
125        self.started_before = Some(ts);
126        self
127    }
128
129    /// Filter by GitHub repository (owner/repo format)
130    pub fn with_github_repo(mut self, repo: impl Into<String>) -> Self {
131        self.github_repo = Some(repo.into());
132        self
133    }
134
135    /// Filter by GitHub issue number
136    pub fn with_github_issue(mut self, issue: i32) -> Self {
137        self.github_issue = Some(issue);
138        self
139    }
140
141    /// Filter by GitHub PR number
142    pub fn with_github_pr(mut self, pr: i32) -> Self {
143        self.github_pr = Some(pr);
144        self
145    }
146
147    /// Set the maximum number of sessions to return
148    pub fn with_limit(mut self, limit: usize) -> Self {
149        self.limit = Some(limit);
150        self
151    }
152
153    /// Order by the given field
154    pub fn with_order_by(mut self, order: SessionOrder) -> Self {
155        self.order_by = order;
156        self
157    }
158
159    /// Set the sort direction (Asc/Desc).
160    ///
161    /// This method is consistent with `EventQuery::with_direction()`.
162    pub fn with_direction(mut self, direction: Order) -> Self {
163        self.direction = direction;
164        self
165    }
166
167    /// Set ascending order (convenience method).
168    ///
169    /// Equivalent to `.with_direction(Order::Asc)`.
170    pub fn ascending(self) -> Self {
171        self.with_direction(Order::Asc)
172    }
173
174    /// Set descending order (convenience method).
175    ///
176    /// Equivalent to `.with_direction(Order::Desc)`.
177    pub fn descending(self) -> Self {
178        self.with_direction(Order::Desc)
179    }
180}