refactor: remove serde from domain entities for Clean Architecture compliance
- Remove Serialize/Deserialize from File, Folder, Session, User, Contact entities - Create contact_persistence_dto.rs for JSONB persistence in infrastructure layer - Update contact_pg_repository to use persistence DTOs - Fix dependency on zip crate (downgrade from 7.2.0 to 2.1.0) - Fix unused variable warnings in main.rs - Move PathService import from domain to infrastructure - Add missing fields to CoreServices and RepositoryServices - Create proper service initialization in main.rs Clean Architecture improvements: - Domain layer no longer depends on serde framework - Persistence concerns isolated to infrastructure layer - TokenClaims in auth_service.rs is only exception (required for JWT)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use sqlx::{PgPool, Transaction, Postgres, Error as SqlxError, Executor};
|
||||
use sqlx::{PgPool, Transaction, Postgres, Error as SqlxError};
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
@@ -50,81 +50,4 @@ where
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Variant that accepts a transaction isolation level
|
||||
pub async fn with_transaction_isolation<F, T, E>(
|
||||
pool: &Arc<PgPool>,
|
||||
operation_name: &str,
|
||||
isolation_level: TransactionIsolationLevel,
|
||||
operation: F,
|
||||
) -> Result<T, E>
|
||||
where
|
||||
F: for<'c> FnOnce(&'c mut Transaction<'_, Postgres>) -> futures::future::BoxFuture<'c, Result<T, E>>,
|
||||
E: From<SqlxError> + std::fmt::Display,
|
||||
{
|
||||
debug!("Starting database transaction with isolation level {:?} for: {}",
|
||||
isolation_level, operation_name);
|
||||
|
||||
// Begin transaction with specific isolation level
|
||||
let mut tx = pool.begin().await.map_err(|e| {
|
||||
error!("Failed to begin transaction for {}: {}", operation_name, e);
|
||||
E::from(e)
|
||||
})?;
|
||||
|
||||
// Set isolation level
|
||||
tx.execute(&format!("SET TRANSACTION ISOLATION LEVEL {}", isolation_level.to_string())[..])
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("Failed to set isolation level for {}: {}", operation_name, e);
|
||||
E::from(e)
|
||||
})?;
|
||||
|
||||
// Execute the operation within the transaction
|
||||
match operation(&mut tx).await {
|
||||
Ok(result) => {
|
||||
// If operation succeeds, commit the transaction
|
||||
match tx.commit().await {
|
||||
Ok(_) => {
|
||||
debug!("Transaction committed successfully for: {}", operation_name);
|
||||
Ok(result)
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Failed to commit transaction for {}: {}", operation_name, e);
|
||||
Err(E::from(e))
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
// If operation fails, rollback the transaction
|
||||
if let Err(rollback_err) = tx.rollback().await {
|
||||
error!("Failed to rollback transaction for {}: {}", operation_name, rollback_err);
|
||||
// Still return the original error
|
||||
} else {
|
||||
info!("Transaction rolled back for {}: {}", operation_name, e);
|
||||
}
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transaction isolation levels from SQL standard
|
||||
#[derive(Debug)]
|
||||
pub enum TransactionIsolationLevel {
|
||||
/// Read committed isolation level
|
||||
ReadCommitted,
|
||||
/// Repeatable read isolation level
|
||||
RepeatableRead,
|
||||
/// Serializable isolation level
|
||||
Serializable,
|
||||
}
|
||||
|
||||
impl ToString for TransactionIsolationLevel {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
TransactionIsolationLevel::ReadCommitted => "READ COMMITTED".to_string(),
|
||||
TransactionIsolationLevel::RepeatableRead => "REPEATABLE READ".to_string(),
|
||||
TransactionIsolationLevel::Serializable => "SERIALIZABLE".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user