use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::time::{Duration, SystemTime};
use thiserror::Error;
use uvb_core::TenantId;
#[derive(Debug, Error)]
pub enum SessionError {
#[error("session not found")]
NotFound,
#[error("session expired")]
Expired,
#[error("storage error: {0}")]
Storage(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SessionRecord {
pub id: String,
pub user_id: String,
pub tenant_id: TenantId,
pub transaction_id: String,
pub factors_used: Vec<String>,
pub assurance_level: i32,
pub metadata: serde_json::Value,
pub created_at: SystemTime,
pub expires_at: SystemTime,
pub last_activity_at: SystemTime,
}
#[async_trait]
pub trait SessionStore: Send + Sync {
async fn create(&self, record: SessionRecord) -> Result<String, SessionError>;
async fn get(&self, id: &str) -> Result<Option<SessionRecord>, SessionError>;
async fn update(&self, record: SessionRecord) -> Result<(), SessionError>;
async fn delete(&self, id: &str) -> Result<(), SessionError>;
async fn delete_by_user(
&self,
user_id: &str,
tenant_id: &TenantId,
) -> Result<usize, SessionError>;
async fn extend(&self, id: &str, duration: Duration) -> Result<(), SessionError>;
async fn touch(&self, id: &str) -> Result<(), SessionError>;
async fn cleanup_expired(&self) -> Result<usize, SessionError>;
async fn list_by_user(
&self,
user_id: &str,
tenant_id: &TenantId,
) -> Result<Vec<SessionRecord>, SessionError>;
}