pub mod presentation; pub mod sources; pub use presentation::reshape; pub use sources::{EventSource, PollerState, PollerStateStore, SourceError, run_poller}; use async_trait::async_trait; use chrono::NaiveDate; use moments_entities::{DailyCount, Event, EventQuery, ProjectSummary, SourceSummary}; #[derive(Debug, thiserror::Error)] pub enum StoreError { #[error("database error: {0}")] Database(String), } /// Read-side port consumed by `moments-api`. #[async_trait] pub trait EventReader: Send + Sync { async fn list_events(&self, query: &EventQuery) -> Result, StoreError>; async fn source_summaries(&self, include_private: bool) -> Result, StoreError>; async fn list_projects(&self) -> Result, StoreError>; async fn daily_counts(&self, from: NaiveDate, to: NaiveDate) -> Result, StoreError>; } /// Write-side port consumed by `moments-worker`. Idempotent upserts on `id`. #[async_trait] pub trait EventWriter: Send + Sync { async fn upsert_events(&self, events: &[Event]) -> Result; }