use crate::error::Result;
use async_trait::async_trait;
#[async_trait]
pub trait OrganizationStore: Send + Sync {
type Organization: Send + Sync + Clone;
async fn create(&self, org: &Self::Organization) -> Result<()>;
async fn find_by_id(&self, id: &str) -> Result<Option<Self::Organization>>;
async fn find_by_slug(&self, slug: &str) -> Result<Option<Self::Organization>>;
async fn update(&self, org: &Self::Organization) -> Result<()>;
async fn delete(&self, id: &str) -> Result<()>;
fn org_id(&self, org: &Self::Organization) -> String;
fn org_name(&self, org: &Self::Organization) -> String;
fn org_slug(&self, org: &Self::Organization) -> String;
fn owner_id(&self, org: &Self::Organization) -> String;
fn contact_email(&self, org: &Self::Organization) -> String;
async fn list_for_user(&self, user_id: &str) -> Result<Vec<Self::Organization>>;
async fn count_owned_by_user(&self, user_id: &str) -> Result<u32>;
async fn is_slug_available(&self, slug: &str) -> Result<bool> {
Ok(self.find_by_slug(slug).await?.is_none())
}
async fn create_with_rollback<F, Fut>(&self, org: &Self::Organization, setup: F) -> Result<()>
where
F: FnOnce() -> Fut + Send,
Fut: std::future::Future<Output = Result<()>> + Send,
{
self.create(org).await?;
if let Err(e) = setup().await {
let _ = self.delete(&self.org_id(org)).await;
return Err(e);
}
Ok(())
}
}