use anyhow::Result; use std::sync::Arc; /// Unit of Work pattern for managing transactional boundaries pub trait UnitOfWork: Send + Sync { /// Begin a new transaction fn begin(&self) -> Result>; } /// Transaction interface for atomic operations pub trait Transaction: Send + Sync { /// Commit all changes in this transaction fn commit(self: Box) -> Result<()>; /// Rollback all changes in this transaction fn rollback(self: Box) -> Result<()>; /// Get repositories within this transaction context fn client_repository(&self) -> Arc; fn auth_code_repository(&self) -> Arc; fn token_repository(&self) -> Arc; fn audit_repository(&self) -> Arc; } /// OAuth2-specific transactional operations pub struct OAuthUnitOfWork { uow: Arc, } impl OAuthUnitOfWork { pub fn new(uow: Arc) -> Self { Self { uow } } /// Execute OAuth2 authorization code exchange atomically pub fn exchange_authorization_code(&self, operation: F) -> Result<()> where F: FnOnce(&dyn Transaction) -> Result<()>, { let tx = self.uow.begin()?; match operation(tx.as_ref()) { Ok(_) => tx.commit(), Err(e) => { let _ = tx.rollback(); // Log but don't override original error Err(e) } } } /// Execute token refresh atomically pub fn refresh_tokens(&self, operation: F) -> Result<()> where F: FnOnce(&dyn Transaction) -> Result<()>, { let tx = self.uow.begin()?; match operation(tx.as_ref()) { Ok(_) => tx.commit(), Err(e) => { let _ = tx.rollback(); Err(e) } } } }