Add EventManager model with roles and permissions

Introduce the `EventManager` model to manage event roles and permissions. Roles include `OWNER`, `ADMIN`, `MODERATOR`, and `VIEWER`, each with specific default permissions. The model supports explicit permissions, relationships, constraints, and a helper method for initializing event owners.
This commit is contained in:
2025-02-27 18:23:45 +01:00
parent ca399e5c68
commit 20f9d89cd8

View File

@@ -0,0 +1,109 @@
from datetime import datetime, timezone
from enum import Enum
from sqlalchemy import Column, Boolean, ForeignKey, UniqueConstraint, Enum as SQLEnum, DateTime
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from .base import Base, TimestampMixin, UUIDMixin
class EventManagerRole(str, Enum):
OWNER = "owner"
ADMIN = "admin"
MODERATOR = "moderator"
VIEWER = "viewer"
class EventManager(Base, UUIDMixin, TimestampMixin):
__tablename__ = 'event_managers'
# Foreign Keys
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
event_id = Column(UUID(as_uuid=True), ForeignKey('events.id'), nullable=False)
assigned_by = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
# Role using Enum
role = Column(SQLEnum(EventManagerRole), nullable=False)
# Explicit permissions
can_edit = Column(Boolean, default=False, nullable=False)
can_invite = Column(Boolean, default=False, nullable=False)
can_manage_gifts = Column(Boolean, default=False, nullable=False)
can_send_updates = Column(Boolean, default=False, nullable=False)
can_view_analytics = Column(Boolean, default=False, nullable=False)
assigned_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
# Relationships
user = relationship("User", back_populates="managed_events", foreign_keys=[user_id])
event = relationship("Event", back_populates="managers")
assigner = relationship("User", foreign_keys=[assigned_by])
__table_args__ = (
UniqueConstraint('user_id', 'event_id', name='uq_user_event_manager'),
)
def __repr__(self):
return f"<EventManager user_id={self.user_id} event_id={self.event_id} role={self.role.value}>"
@property
def permissions(self):
"""Get permissions based on role"""
return ROLE_PERMISSIONS[self.role]
def has_permission(self, permission: str) -> bool:
"""Check if manager has specific permission"""
return getattr(self, permission, False) or self.permissions.get(permission, False)
# Define default permissions for each role
ROLE_PERMISSIONS = {
EventManagerRole.OWNER: {
'can_edit': True,
'can_invite': True,
'can_manage_gifts': True,
'can_send_updates': True,
'can_view_analytics': True,
'can_manage_managers': True, # Special permission for owners
},
EventManagerRole.ADMIN: {
'can_edit': True,
'can_invite': True,
'can_manage_gifts': True,
'can_send_updates': True,
'can_view_analytics': True,
'can_manage_managers': False,
},
EventManagerRole.MODERATOR: {
'can_edit': False,
'can_invite': True,
'can_manage_gifts': True,
'can_send_updates': True,
'can_view_analytics': True,
'can_manage_managers': False,
},
EventManagerRole.VIEWER: {
'can_edit': False,
'can_invite': False,
'can_manage_gifts': False,
'can_send_updates': False,
'can_view_analytics': True,
'can_manage_managers': False,
}
}
def init_event_owner(user_id: UUID, event_id: UUID) -> EventManager:
"""Helper function to create an owner manager for a new event"""
return EventManager(
user_id=user_id,
event_id=event_id,
assigned_by=user_id, # Owner is self-assigned
role=EventManagerRole.OWNER,
can_edit=True,
can_invite=True,
can_manage_gifts=True,
can_send_updates=True,
can_view_analytics=True
)