237 lines
7.2 KiB
Python
237 lines
7.2 KiB
Python
# app/exceptions/team.py
|
|
"""
|
|
Team management specific exceptions.
|
|
"""
|
|
|
|
from typing import Any, Dict, Optional
|
|
from .base import (
|
|
ResourceNotFoundException,
|
|
ConflictException,
|
|
ValidationException,
|
|
AuthorizationException,
|
|
BusinessLogicException
|
|
)
|
|
|
|
|
|
class TeamMemberNotFoundException(ResourceNotFoundException):
|
|
"""Raised when a team member is not found."""
|
|
|
|
def __init__(self, user_id: int, vendor_id: Optional[int] = None):
|
|
details = {"user_id": user_id}
|
|
if vendor_id:
|
|
details["vendor_id"] = vendor_id
|
|
message = f"Team member with user ID '{user_id}' not found in vendor {vendor_id}"
|
|
else:
|
|
message = f"Team member with user ID '{user_id}' not found"
|
|
|
|
super().__init__(
|
|
resource_type="TeamMember",
|
|
identifier=str(user_id),
|
|
message=message,
|
|
error_code="TEAM_MEMBER_NOT_FOUND",
|
|
details=details,
|
|
)
|
|
|
|
|
|
class TeamMemberAlreadyExistsException(ConflictException):
|
|
"""Raised when trying to add a user who is already a team member."""
|
|
|
|
def __init__(self, user_id: int, vendor_id: int):
|
|
super().__init__(
|
|
message=f"User {user_id} is already a team member of vendor {vendor_id}",
|
|
error_code="TEAM_MEMBER_ALREADY_EXISTS",
|
|
details={
|
|
"user_id": user_id,
|
|
"vendor_id": vendor_id,
|
|
},
|
|
)
|
|
|
|
|
|
class TeamInvitationNotFoundException(ResourceNotFoundException):
|
|
"""Raised when a team invitation is not found."""
|
|
|
|
def __init__(self, invitation_token: str):
|
|
super().__init__(
|
|
resource_type="TeamInvitation",
|
|
identifier=invitation_token,
|
|
message=f"Team invitation with token '{invitation_token}' not found or expired",
|
|
error_code="TEAM_INVITATION_NOT_FOUND",
|
|
)
|
|
|
|
|
|
class TeamInvitationExpiredException(BusinessLogicException):
|
|
"""Raised when trying to accept an expired invitation."""
|
|
|
|
def __init__(self, invitation_token: str):
|
|
super().__init__(
|
|
message=f"Team invitation has expired",
|
|
error_code="TEAM_INVITATION_EXPIRED",
|
|
details={"invitation_token": invitation_token},
|
|
)
|
|
|
|
|
|
class TeamInvitationAlreadyAcceptedException(ConflictException):
|
|
"""Raised when trying to accept an already accepted invitation."""
|
|
|
|
def __init__(self, invitation_token: str):
|
|
super().__init__(
|
|
message="Team invitation has already been accepted",
|
|
error_code="TEAM_INVITATION_ALREADY_ACCEPTED",
|
|
details={"invitation_token": invitation_token},
|
|
)
|
|
|
|
|
|
class UnauthorizedTeamActionException(AuthorizationException):
|
|
"""Raised when user tries to perform team action without permission."""
|
|
|
|
def __init__(self, action: str, user_id: Optional[int] = None, required_permission: Optional[str] = None):
|
|
details = {"action": action}
|
|
if user_id:
|
|
details["user_id"] = user_id
|
|
if required_permission:
|
|
details["required_permission"] = required_permission
|
|
|
|
super().__init__(
|
|
message=f"Unauthorized to perform action: {action}",
|
|
error_code="UNAUTHORIZED_TEAM_ACTION",
|
|
details=details,
|
|
)
|
|
|
|
|
|
class CannotRemoveOwnerException(BusinessLogicException):
|
|
"""Raised when trying to remove the vendor owner from team."""
|
|
|
|
def __init__(self, user_id: int, vendor_id: int):
|
|
super().__init__(
|
|
message="Cannot remove vendor owner from team",
|
|
error_code="CANNOT_REMOVE_OWNER",
|
|
details={
|
|
"user_id": user_id,
|
|
"vendor_id": vendor_id,
|
|
},
|
|
)
|
|
|
|
|
|
class CannotModifyOwnRoleException(BusinessLogicException):
|
|
"""Raised when user tries to modify their own role."""
|
|
|
|
def __init__(self, user_id: int):
|
|
super().__init__(
|
|
message="Cannot modify your own role",
|
|
error_code="CANNOT_MODIFY_OWN_ROLE",
|
|
details={"user_id": user_id},
|
|
)
|
|
|
|
|
|
class RoleNotFoundException(ResourceNotFoundException):
|
|
"""Raised when a role is not found."""
|
|
|
|
def __init__(self, role_id: int, vendor_id: Optional[int] = None):
|
|
details = {"role_id": role_id}
|
|
if vendor_id:
|
|
details["vendor_id"] = vendor_id
|
|
message = f"Role with ID '{role_id}' not found in vendor {vendor_id}"
|
|
else:
|
|
message = f"Role with ID '{role_id}' not found"
|
|
|
|
super().__init__(
|
|
resource_type="Role",
|
|
identifier=str(role_id),
|
|
message=message,
|
|
error_code="ROLE_NOT_FOUND",
|
|
details=details,
|
|
)
|
|
|
|
|
|
class InvalidRoleException(ValidationException):
|
|
"""Raised when role data is invalid."""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str = "Invalid role data",
|
|
field: Optional[str] = None,
|
|
details: Optional[Dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message,
|
|
field=field,
|
|
details=details,
|
|
)
|
|
self.error_code = "INVALID_ROLE_DATA"
|
|
|
|
|
|
class InsufficientPermissionsException(AuthorizationException):
|
|
"""Raised when user lacks required permissions for an action."""
|
|
|
|
def __init__(
|
|
self,
|
|
required_permission: str,
|
|
user_id: Optional[int] = None,
|
|
action: Optional[str] = None,
|
|
):
|
|
details = {"required_permission": required_permission}
|
|
if user_id:
|
|
details["user_id"] = user_id
|
|
if action:
|
|
details["action"] = action
|
|
|
|
message = f"Insufficient permissions. Required: {required_permission}"
|
|
|
|
super().__init__(
|
|
message=message,
|
|
error_code="INSUFFICIENT_PERMISSIONS",
|
|
details=details,
|
|
)
|
|
|
|
|
|
class MaxTeamMembersReachedException(BusinessLogicException):
|
|
"""Raised when vendor has reached maximum team members limit."""
|
|
|
|
def __init__(self, max_members: int, vendor_id: int):
|
|
super().__init__(
|
|
message=f"Maximum number of team members reached ({max_members})",
|
|
error_code="MAX_TEAM_MEMBERS_REACHED",
|
|
details={
|
|
"max_members": max_members,
|
|
"vendor_id": vendor_id,
|
|
},
|
|
)
|
|
|
|
|
|
class TeamValidationException(ValidationException):
|
|
"""Raised when team operation validation fails."""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str = "Team operation validation failed",
|
|
field: Optional[str] = None,
|
|
validation_errors: Optional[Dict[str, str]] = None,
|
|
):
|
|
details = {}
|
|
if validation_errors:
|
|
details["validation_errors"] = validation_errors
|
|
|
|
super().__init__(
|
|
message=message,
|
|
field=field,
|
|
details=details,
|
|
)
|
|
self.error_code = "TEAM_VALIDATION_FAILED"
|
|
|
|
|
|
class InvalidInvitationDataException(ValidationException):
|
|
"""Raised when team invitation data is invalid."""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str = "Invalid invitation data",
|
|
field: Optional[str] = None,
|
|
details: Optional[Dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message,
|
|
field=field,
|
|
details=details,
|
|
)
|
|
self.error_code = "INVALID_INVITATION_DATA"
|