use super::{Commerce, CommerceBackend};
use chrono::{DateTime, Utc};
use stateset_core::OrderFilter;
use stateset_db::Database;
use stateset_observability::{Metrics, MetricsSnapshot};
#[cfg(all(feature = "sqlite", feature = "vector"))]
use stateset_core::CommerceError;
#[cfg(all(feature = "sqlite", feature = "vector"))]
use crate::Vector;
#[derive(Debug, Clone)]
pub struct CommerceHealth {
pub healthy: bool,
pub backend: CommerceBackend,
pub database_reachable: bool,
pub database_error: Option<String>,
pub metrics: MetricsSnapshot,
#[cfg(feature = "events")]
pub event_subscribers: usize,
pub checked_at: DateTime<Utc>,
}
impl Commerce {
#[must_use]
pub fn database(&self) -> &dyn Database {
&*self.db
}
#[must_use]
pub const fn backend(&self) -> CommerceBackend {
self.backend
}
#[must_use]
pub const fn metrics(&self) -> &Metrics {
&self.metrics
}
#[must_use]
pub fn metrics_snapshot(&self) -> MetricsSnapshot {
self.metrics.snapshot()
}
#[must_use]
pub fn health_check(&self) -> CommerceHealth {
let probe = self.db.orders().count(OrderFilter::default());
let metrics = self.metrics_snapshot();
CommerceHealth {
healthy: probe.is_ok(),
backend: self.backend,
database_reachable: probe.is_ok(),
database_error: probe.err().map(|e| e.to_string()),
metrics,
#[cfg(feature = "events")]
event_subscribers: self.event_system.subscriber_count(),
checked_at: Utc::now(),
}
}
#[cfg(all(feature = "sqlite", feature = "vector"))]
pub fn vector(&self, api_key: String) -> Result<Vector, CommerceError> {
match &self.sqlite_db {
Some(db) => Ok(Vector::new(db.vector(), api_key)),
None => Err(CommerceError::NotPermitted(
"Vector search requires SQLite database. Use Commerce::new() instead of with_database() or with_postgres().".to_string()
)),
}
}
}