Skip to main content

uvb_storage_api/
transaction.rs

1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use std::time::SystemTime;
4use thiserror::Error;
5use uvb_core::{Context, Subject};
6
7#[derive(Debug, Error)]
8pub enum TransactionError {
9    #[error("transaction not found")]
10    NotFound,
11    #[error("transaction expired")]
12    Expired,
13    #[error("storage error: {0}")]
14    Storage(String),
15    #[error("serialization error: {0}")]
16    Serialization(String),
17}
18
19/// Represents a verification transaction in storage
20#[derive(Clone, Debug, Serialize, Deserialize)]
21pub struct TransactionRecord {
22    pub id: String,
23    pub subject: Subject,
24    pub context: Context,
25    pub status: TransactionStatus,
26    pub policy_id: String,
27    pub completed_factors: Vec<String>,
28    pub pending_challenges: serde_json::Value,
29    pub metadata: serde_json::Value,
30    pub created_at: SystemTime,
31    pub expires_at: SystemTime,
32    pub updated_at: SystemTime,
33}
34
35#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
36pub enum TransactionStatus {
37    InProgress,
38    Succeeded,
39    Failed,
40    Expired,
41}
42
43/// Trait for pluggable transaction storage backends
44///
45/// Implementations might be:
46/// - In-memory (HashMap)
47/// - PostgreSQL
48/// - Redis
49/// - DynamoDB
50/// - Any custom storage system
51#[async_trait]
52pub trait TransactionStore: Send + Sync {
53    /// Create a new transaction
54    async fn create(&self, record: TransactionRecord) -> Result<(), TransactionError>;
55
56    /// Get a transaction by ID
57    async fn get(&self, id: &str) -> Result<Option<TransactionRecord>, TransactionError>;
58
59    /// Update an existing transaction
60    async fn update(&self, record: TransactionRecord) -> Result<(), TransactionError>;
61
62    /// Delete a transaction
63    async fn delete(&self, id: &str) -> Result<(), TransactionError>;
64
65    /// List transactions by user_id (for admin/debugging)
66    async fn list_by_user(
67        &self,
68        user_id: &str,
69        limit: usize,
70    ) -> Result<Vec<TransactionRecord>, TransactionError>;
71
72    /// Cleanup expired transactions (for background job)
73    async fn cleanup_expired(&self) -> Result<usize, TransactionError>;
74}