Skip to main content

hypercall_db/traits/
integrity.rs

1//! Integrity monitoring traits (read-only, async).
2//!
3//! Powers the `/monitoring/integrity` admin endpoint and the periodic
4//! `MetricsCollector` slow-path DB checks. All queries run on a single
5//! connection for snapshot consistency.
6//!
7//! Async because both callers (monitoring handler, metrics collector) are
8//! in async Tokio contexts. The impl lives on `DieselDb` (diesel-async pool),
9//! not `DatabaseHandler` (sync r2d2 pool), eliminating the `spawn_blocking`
10//! bridge that the old sync path required.
11//!
12//! Individual sub-query methods are test-only (gated behind `test-utils`).
13//! Production code calls `get_integrity_query_results` which runs the
14//! DB-backed checks in one connection checkout.
15
16#[cfg(any(test, feature = "test-utils"))]
17use anyhow::Result;
18use async_trait::async_trait;
19#[cfg(any(test, feature = "test-utils"))]
20use rust_decimal::Decimal;
21
22use crate::IntegrityQueryResults;
23
24/// Aggregated integrity checks for the Hypercall persistence layer.
25///
26/// Used by:
27/// - `GET /monitoring/integrity` (admin endpoint, requires X-Admin-Key)
28/// - `MetricsCollector` slow-path (every 5 min, exports Prometheus gauges)
29///
30/// Each field in [`IntegrityQueryResults`] is an independent query result
31/// so a single failing check doesn't block the others.
32#[async_trait]
33pub trait IntegrityReader: Send + Sync {
34    /// Run all 9 integrity checks on a single connection and return the
35    /// aggregated results. This is the only method called in production.
36    async fn get_integrity_query_results(&self) -> IntegrityQueryResults;
37
38    /// Settlement stats: (total, applied, pending, total_payout_value).
39    /// Test-only - production uses `get_integrity_query_results`.
40    #[cfg(any(test, feature = "test-utils"))]
41    async fn get_settlement_integrity(&self) -> Result<(i64, i64, i64, Decimal)>;
42
43    /// Open interest grouped by underlying currency.
44    /// Test-only - production uses `get_integrity_query_results`.
45    #[cfg(any(test, feature = "test-utils"))]
46    async fn get_open_interest_by_underlying(&self) -> Result<Vec<(String, Decimal)>>;
47}