use crate::error::Result;
use async_trait::async_trait;
#[async_trait]
pub trait InvitationStore: Send + Sync {
type Invitation: Send + Sync + Clone;
type Role: Send + Sync + Clone;
async fn create(&self, invitation: &Self::Invitation) -> Result<()>;
async fn find_by_token(&self, token: &str) -> Result<Option<Self::Invitation>>;
async fn find_by_id(&self, id: &str) -> Result<Option<Self::Invitation>>;
async fn list_pending(&self, org_id: &str) -> Result<Vec<Self::Invitation>>;
async fn mark_accepted(&self, id: &str) -> Result<()>;
async fn mark_revoked(&self, id: &str) -> Result<()>;
async fn delete_expired(&self) -> Result<usize>;
fn invitation_id(&self, inv: &Self::Invitation) -> String;
fn invitation_org_id(&self, inv: &Self::Invitation) -> String;
fn invitation_email(&self, inv: &Self::Invitation) -> String;
fn invitation_role(&self, inv: &Self::Invitation) -> Self::Role;
fn invitation_token(&self, inv: &Self::Invitation) -> String;
fn invitation_expires_at(&self, inv: &Self::Invitation) -> u64;
fn is_expired(&self, inv: &Self::Invitation) -> bool;
fn is_revoked(&self, inv: &Self::Invitation) -> bool;
async fn find_pending_by_email(
&self,
org_id: &str,
email: &str,
) -> Result<Option<Self::Invitation>> {
let pending = self.list_pending(org_id).await?;
Ok(pending
.into_iter()
.find(|i| self.invitation_email(i) == email))
}
async fn count_pending(&self, org_id: &str) -> Result<u32> {
Ok(self.list_pending(org_id).await?.len() as u32)
}
}