Skip to main content

kaizen/store/sqlite/
contracts.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3use crate::core::event::{SessionRecord, SessionStatus};
4
5/// Per-workspace activity dashboard stats.
6#[derive(Clone)]
7pub struct InsightsStats {
8    pub total_sessions: u64,
9    pub running_sessions: u64,
10    pub total_events: u64,
11    /// (day label e.g. "Mon", count) last 7 days oldest first
12    pub sessions_by_day: Vec<(String, u64)>,
13    /// Recent sessions DESC by started_at, max 3; paired with event count
14    pub recent: Vec<(SessionRecord, u64)>,
15    /// Top tools by event count, max 5
16    pub top_tools: Vec<(String, u64)>,
17    pub total_cost_usd_e6: i64,
18    pub sessions_with_cost: u64,
19}
20
21/// Sync daemon / outbox status for `kaizen sync status`.
22pub struct SyncStatusSnapshot {
23    pub pending_outbox: u64,
24    pub last_success_ms: Option<u64>,
25    pub last_error: Option<String>,
26    pub consecutive_failures: u32,
27}
28
29/// Aggregate stats across sessions + events for a workspace.
30#[derive(serde::Serialize)]
31pub struct SummaryStats {
32    pub session_count: u64,
33    pub total_cost_usd_e6: i64,
34    pub by_agent: Vec<(String, u64)>,
35    pub by_model: Vec<(String, u64)>,
36    pub top_tools: Vec<(String, u64)>,
37}
38
39/// Skill vs Cursor rule for [`GuidancePerfRow`].
40#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, serde::Serialize)]
41#[serde(rename_all = "lowercase")]
42pub enum GuidanceKind {
43    Skill,
44    Rule,
45}
46
47/// One row for `kaizen guidance` — observed references in payloads (not Cursor auto-load counts).
48#[derive(Clone, Debug, serde::Serialize)]
49pub struct GuidancePerfRow {
50    pub kind: GuidanceKind,
51    pub id: String,
52    pub sessions: u64,
53    pub sessions_pct: f64,
54    pub total_cost_usd_e6: i64,
55    pub avg_cost_per_session_usd: Option<f64>,
56    pub vs_workspace_avg_cost_per_session_usd: Option<f64>,
57    pub on_disk: bool,
58}
59
60/// Aggregated skill/rule adoption and cost proxy for a time window.
61#[derive(Clone, Debug, serde::Serialize)]
62pub struct GuidanceReport {
63    pub workspace: String,
64    pub window_start_ms: u64,
65    pub window_end_ms: u64,
66    pub sessions_in_window: u64,
67    pub workspace_avg_cost_per_session_usd: Option<f64>,
68    pub rows: Vec<GuidancePerfRow>,
69}
70
71/// Result of [`super::Store::prune_sessions_started_before`].
72#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
73pub struct PruneStats {
74    pub sessions_removed: u64,
75    pub events_removed: u64,
76}
77
78/// Row in `session_outcomes` (Tier C — post-stop test/lint snapshot).
79#[derive(Debug, Clone, Eq, PartialEq)]
80pub struct SessionOutcomeRow {
81    pub session_id: String,
82    pub test_passed: Option<i64>,
83    pub test_failed: Option<i64>,
84    pub test_skipped: Option<i64>,
85    pub build_ok: Option<bool>,
86    pub lint_errors: Option<i64>,
87    pub revert_lines_14d: Option<i64>,
88    pub pr_open: Option<i64>,
89    pub ci_ok: Option<bool>,
90    pub measured_at_ms: u64,
91    pub measure_error: Option<String>,
92}
93
94/// Aggregated process samples for retro (Tier D).
95#[derive(Debug, Clone)]
96pub struct SessionSampleAgg {
97    pub session_id: String,
98    pub sample_count: u64,
99    pub max_cpu_percent: f64,
100    pub max_rss_bytes: u64,
101}
102
103pub struct ToolSpanSyncRow {
104    pub span_id: String,
105    pub session_id: String,
106    pub tool: Option<String>,
107    pub tool_call_id: Option<String>,
108    pub status: String,
109    pub started_at_ms: Option<u64>,
110    pub ended_at_ms: Option<u64>,
111    pub lead_time_ms: Option<u64>,
112    pub tokens_in: Option<u32>,
113    pub tokens_out: Option<u32>,
114    pub reasoning_tokens: Option<u32>,
115    pub cost_usd_e6: Option<i64>,
116    pub paths: Vec<String>,
117}
118
119pub(crate) struct CaptureQualityRow {
120    pub source: String,
121    pub has_tokens: bool,
122    pub has_cost: bool,
123    pub has_latency: bool,
124    pub has_context: bool,
125    pub cache_read_tokens: u64,
126    pub cache_creation_tokens: u64,
127}
128
129pub(crate) struct TraceSpanQualityRow {
130    pub kind: String,
131    pub is_orphan: bool,
132}
133
134#[derive(Debug, Clone, Copy, Eq, PartialEq)]
135pub enum StoreOpenMode {
136    ReadWrite,
137    ReadOnlyQuery,
138}
139
140#[derive(Debug, Clone)]
141pub struct SessionStatusRow {
142    pub id: String,
143    pub status: SessionStatus,
144    pub ended_at_ms: Option<u64>,
145}
146
147#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
148pub struct SessionFilter {
149    pub agent_prefix: Option<String>,
150    pub status: Option<SessionStatus>,
151    pub since_ms: Option<u64>,
152}
153
154#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
155pub struct SessionPage {
156    pub rows: Vec<SessionRecord>,
157    pub total: usize,
158    pub next_offset: Option<usize>,
159}