from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey, Enum as SQLEnum from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.sql import func import uuid import enum from app.database import Base class SharePermission(str, enum.Enum): """Permission levels for map sharing.""" READ = "read" # Read-only access EDIT = "edit" # Can edit map items class MapShare(Base): """Map sharing with specific users.""" __tablename__ = "map_shares" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) map_id = Column(UUID(as_uuid=True), ForeignKey("maps.id", ondelete="CASCADE"), nullable=False, index=True) user_id = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True) permission = Column(SQLEnum(SharePermission, values_callable=lambda x: [e.value for e in x]), nullable=False, default=SharePermission.READ) shared_by = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) class MapShareLink(Base): """Public/guest share links for maps.""" __tablename__ = "map_share_links" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) map_id = Column(UUID(as_uuid=True), ForeignKey("maps.id", ondelete="CASCADE"), nullable=False, index=True) token = Column(String(64), unique=True, nullable=False, index=True) # Random token for the share URL permission = Column(SQLEnum(SharePermission, values_callable=lambda x: [e.value for e in x]), nullable=False, default=SharePermission.READ) is_active = Column(Boolean, default=True, nullable=False) created_by = Column(UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True) expires_at = Column(DateTime(timezone=True), nullable=True) # Optional expiration created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)