from __future__ import annotations from sqlalchemy.orm import Session from packages.adapters.sqlalchemy_impl.models import WorkspaceInvitationModel from packages.domain.entities import WorkspaceInvitation from packages.ports.workspace_invitation_repository import WorkspaceInvitationRepository class SQLAlchemyWorkspaceInvitationRepository(WorkspaceInvitationRepository): def __init__(self, session: Session): self.session = session def save(self, invitation: WorkspaceInvitation) -> None: model = self.session.get(WorkspaceInvitationModel, invitation.id) if model is None: model = WorkspaceInvitationModel(id=invitation.id) self.session.add(model) model.workspace_id = invitation.workspace_id model.inviter_user_id = invitation.inviter_user_id model.invitee_email = invitation.invitee_email.strip().lower() model.role = str(invitation.role) model.invitation_token = invitation.invitation_token model.status = str(invitation.status) model.expires_at = invitation.expires_at model.accepted_at = invitation.accepted_at model.created_at = invitation.created_at self.session.commit() self.session.refresh(model) def find_by_id(self, invitation_id: str) -> WorkspaceInvitation | None: return self._to_entity(self.session.get(WorkspaceInvitationModel, invitation_id)) def find_by_token(self, token: str) -> WorkspaceInvitation | None: model = ( self.session.query(WorkspaceInvitationModel) .filter(WorkspaceInvitationModel.invitation_token == token) .first() ) return self._to_entity(model) def find_pending_by_workspace_and_email(self, workspace_id: str, email: str) -> WorkspaceInvitation | None: model = ( self.session.query(WorkspaceInvitationModel) .filter( WorkspaceInvitationModel.workspace_id == workspace_id, WorkspaceInvitationModel.invitee_email == email.strip().lower(), WorkspaceInvitationModel.status == "pending", ) .first() ) return self._to_entity(model) def delete(self, invitation_id: str) -> bool: model = self.session.get(WorkspaceInvitationModel, invitation_id) if model is None: return False self.session.delete(model) self.session.commit() return True @staticmethod def _to_entity(model: WorkspaceInvitationModel | None) -> WorkspaceInvitation | None: if model is None: return None return WorkspaceInvitation( id=model.id, workspace_id=model.workspace_id, inviter_user_id=model.inviter_user_id, invitee_email=model.invitee_email, role=model.role, invitation_token=model.invitation_token, status=model.status, expires_at=model.expires_at, accepted_at=model.accepted_at, created_at=model.created_at, )