use platform_core::{
OutboxPublisher, begin_transaction, claim_idempotency_key_in_tx, commit_transaction,
rollback_transaction,
};
pub use platform_core::{
AppError, AppResult, DbPool, DbTransaction, IdempotencyClaim, IdempotencyKey, OutboxEvent,
};
#[derive(Debug)]
pub struct LinkedTransaction<'a> {
transaction: DbTransaction<'a>,
}
impl<'a> LinkedTransaction<'a> {
pub async fn begin(pool: &'a DbPool) -> AppResult<Self> {
let transaction = begin_transaction(pool).await?;
Ok(Self { transaction })
}
pub async fn claim_idempotency_key(
&mut self,
key: &IdempotencyKey,
) -> AppResult<IdempotencyClaim> {
claim_idempotency_key_in_tx(&mut self.transaction, key).await
}
pub fn sql(&mut self) -> &mut DbTransaction<'a> {
&mut self.transaction
}
pub async fn publish_outbox(&mut self, event: &OutboxEvent) -> AppResult<()> {
OutboxPublisher
.publish_in_tx(&mut self.transaction, event)
.await
}
pub async fn commit(self) -> AppResult<()> {
commit_transaction(self.transaction).await
}
pub async fn rollback(self) -> AppResult<()> {
rollback_transaction(self.transaction).await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn minimal_feature_exposes_the_public_transaction_contract() {
let key = IdempotencyKey::parse("example:create", "request-1").unwrap();
assert_eq!(key.scope(), "example:create");
assert_eq!(key.value(), "request-1");
let _claim = IdempotencyClaim::Acquired;
let _begin = LinkedTransaction::begin;
}
}