1mod artifacts;
7pub mod fleet;
8mod key_store;
9mod memory;
10mod postgres;
11mod sqlite;
12
13pub use artifacts::ObjectArtifactStore;
14pub use fleet::{FleetStore, InMemoryFleetStore};
15pub use key_store::{InMemoryKeyStore, KeyRecord, KeyStore, SqliteKeyStore, hash_key, key_prefix};
16pub use memory::InMemoryStore;
17pub use postgres::PostgresStore;
18pub use sqlite::SqliteStore;
19pub(crate) use sqlite::open_configured_connection as open_configured_sqlite_connection;
20
21use crate::error::StoreError;
22use crate::models::{
23 AuditEvent, BaselineRecord, BaselineVersion, DecisionRecord, ListAuditEventsQuery,
24 ListAuditEventsResponse, ListBaselinesQuery, ListBaselinesResponse, ListDecisionsQuery,
25 ListDecisionsResponse, ListVerdictsQuery, ListVerdictsResponse, PoolMetrics,
26 PruneDecisionsResponse, VerdictRecord,
27};
28use async_trait::async_trait;
29use chrono::{DateTime, Utc};
30
31#[derive(Debug, Clone)]
33pub struct ArtifactMeta {
34 pub path: String,
36 pub last_modified: DateTime<Utc>,
38 pub size: u64,
40}
41
42#[async_trait]
44pub trait ArtifactStore: std::fmt::Debug + Send + Sync {
45 async fn put(&self, path: &str, data: Vec<u8>) -> Result<(), StoreError>;
47
48 async fn get(&self, path: &str) -> Result<Vec<u8>, StoreError>;
50
51 async fn delete(&self, path: &str) -> Result<(), StoreError>;
53
54 async fn list(&self, prefix: Option<&str>) -> Result<Vec<ArtifactMeta>, StoreError>;
56}
57
58#[async_trait]
63pub trait BaselineStore: Send + Sync {
64 async fn create(&self, record: &BaselineRecord) -> Result<(), StoreError>;
66
67 async fn get(
69 &self,
70 project: &str,
71 benchmark: &str,
72 version: &str,
73 ) -> Result<Option<BaselineRecord>, StoreError>;
74
75 async fn get_latest(
77 &self,
78 project: &str,
79 benchmark: &str,
80 ) -> Result<Option<BaselineRecord>, StoreError>;
81
82 async fn list(
84 &self,
85 project: &str,
86 query: &ListBaselinesQuery,
87 ) -> Result<ListBaselinesResponse, StoreError>;
88
89 async fn update(&self, record: &BaselineRecord) -> Result<(), StoreError>;
91
92 async fn delete(
94 &self,
95 project: &str,
96 benchmark: &str,
97 version: &str,
98 ) -> Result<bool, StoreError>;
99
100 async fn hard_delete(
102 &self,
103 project: &str,
104 benchmark: &str,
105 version: &str,
106 ) -> Result<bool, StoreError>;
107
108 async fn list_versions(
110 &self,
111 project: &str,
112 benchmark: &str,
113 ) -> Result<Vec<BaselineVersion>, StoreError>;
114
115 async fn health_check(&self) -> Result<StorageHealth, StoreError>;
117
118 fn backend_type(&self) -> &'static str;
120
121 fn pool_metrics(&self) -> Option<PoolMetrics> {
126 None
127 }
128
129 async fn create_verdict(&self, record: &VerdictRecord) -> Result<(), StoreError>;
131
132 async fn list_verdicts(
134 &self,
135 project: &str,
136 query: &ListVerdictsQuery,
137 ) -> Result<ListVerdictsResponse, StoreError>;
138
139 async fn create_decision(&self, record: &DecisionRecord) -> Result<(), StoreError>;
141
142 async fn latest_decision(&self, project: &str) -> Result<Option<DecisionRecord>, StoreError>;
144
145 async fn list_decisions(
147 &self,
148 project: &str,
149 query: &ListDecisionsQuery,
150 ) -> Result<ListDecisionsResponse, StoreError>;
151
152 async fn prune_decisions(
154 &self,
155 project: &str,
156 older_than: DateTime<Utc>,
157 dry_run: bool,
158 ) -> Result<PruneDecisionsResponse, StoreError>;
159}
160
161#[async_trait]
166pub trait AuditStore: Send + Sync {
167 async fn log_event(&self, event: &AuditEvent) -> Result<(), StoreError>;
169
170 async fn list_events(
172 &self,
173 query: &ListAuditEventsQuery,
174 ) -> Result<ListAuditEventsResponse, StoreError>;
175}
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq)]
179pub enum StorageHealth {
180 Healthy,
182 Degraded,
184 Unhealthy,
186}
187
188impl StorageHealth {
189 pub fn as_str(&self) -> &'static str {
191 match self {
192 Self::Healthy => "healthy",
193 Self::Degraded => "degraded",
194 Self::Unhealthy => "unhealthy",
195 }
196 }
197}
198
199impl std::fmt::Display for StorageHealth {
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201 write!(f, "{}", self.as_str())
202 }
203}