RTIX / src /application /services /arbitration.rs
github-actions
deploy: clean backend production release
c33971d
use crate::domain::error::AppResult;
use crate::infrastructure::db::DbPool;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct DisputeEvidence {
pub evidence_id: Uuid,
pub transaction_id: String,
pub evidence_url: String,
pub uploader_role: String,
pub metadata: serde_json::Value,
}
pub struct ArbitrationService {
pool: DbPool,
}
impl ArbitrationService {
pub fn new(pool: DbPool) -> Self {
Self { pool }
}
pub async fn upload_evidence(
&self,
transaction_id: &str,
evidence_url: &str,
role: &str,
) -> AppResult<Uuid> {
let evidence_id = Uuid::new_v4();
sqlx::query(
"INSERT INTO dispute_evidence (evidence_id, transaction_id, evidence_url, uploader_role) VALUES ($1, $2, $3, $4)"
)
.bind(evidence_id)
.bind(transaction_id)
.bind(evidence_url)
.bind(role)
.execute(&self.pool)
.await?;
Ok(evidence_id)
}
pub async fn get_evidence_for_transaction(
&self,
transaction_id: &str,
) -> AppResult<Vec<DisputeEvidence>> {
let evidence = sqlx::query_as::<_, DisputeEvidence>(
r#"SELECT evidence_id, transaction_id, evidence_url, uploader_role, metadata FROM dispute_evidence WHERE transaction_id = $1"#
)
.bind(transaction_id)
.fetch_all(&self.pool)
.await?;
Ok(evidence)
}
pub async fn resolve_dispute(
&self,
transaction_id: &str,
resolution: &str, // 'SETTLED', 'REVERSED'
) -> AppResult<()> {
let status = match resolution {
"SETTLED" => crate::domain::constants::ORDER_STATUS_SETTLED,
"REVERSED" => "REVERSED", // New status
_ => {
return Err(crate::domain::error::AppError::BadRequest(
"Invalid resolution".into(),
))
}
};
sqlx::query("UPDATE orders SET status = $1 WHERE transaction_id = $2")
.bind(status)
.bind(transaction_id)
.execute(&self.pool)
.await?;
Ok(())
}
}