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"" @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 )