use async_trait::async_trait;
use llm_cost_ops::{Result, UsageRecord};
use super::models::{IngestionResponse, UsageWebhookPayload};
#[async_trait]
pub trait IngestionHandler: Send + Sync + Clone {
async fn handle_single(&self, payload: UsageWebhookPayload) -> Result<IngestionResponse>;
async fn handle_batch(&self, payloads: Vec<UsageWebhookPayload>)
-> Result<IngestionResponse>;
fn name(&self) -> &str;
async fn health_check(&self) -> Result<bool>;
}
#[async_trait]
pub trait IngestionStorage: Send + Sync {
async fn store_usage(&self, record: UsageRecord) -> Result<()>;
async fn store_batch(&self, records: Vec<UsageRecord>) -> Result<Vec<Result<()>>>;
async fn health(&self) -> Result<bool>;
}
pub trait PayloadValidator: Send + Sync {
fn validate(&self, payload: &UsageWebhookPayload) -> Result<()>;
fn validate_batch(&self, payloads: &[UsageWebhookPayload]) -> Vec<Result<()>>;
}
#[async_trait]
pub trait RateLimiter: Send + Sync {
async fn check_rate_limit(&self, organization_id: &str) -> Result<bool>;
async fn record_request(&self, organization_id: &str) -> Result<()>;
}
#[async_trait]
pub trait RecordBuffer: Send + Sync {
async fn add(&self, record: UsageRecord) -> Result<()>;
async fn flush(&self) -> Result<Vec<UsageRecord>>;
async fn size(&self) -> usize;
async fn should_flush(&self) -> bool;
}