Files
voidea/app/models/collaboration.py

107 lines
2.9 KiB
Python

"""Collaboration models for VoIdea.
Voting, threaded comments, activity log, and notifications.
"""
from typing import Optional
from sqlalchemy import Boolean, ForeignKey, String, Text, UniqueConstraint
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.orm import Mapped, mapped_column
from app.core.base import SQLBase, TimestampMixin, UUIDMixin
class IdeaVote(SQLBase, UUIDMixin, TimestampMixin):
__tablename__ = "idea_votes"
idea_id: Mapped[UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("ideas.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
user_id: Mapped[UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
vote: Mapped[str] = mapped_column(
String(4), nullable=False
)
__table_args__ = (
UniqueConstraint("idea_id", "user_id", name="uq_idea_user_vote"),
)
class IdeaComment(SQLBase, UUIDMixin, TimestampMixin):
__tablename__ = "idea_comments"
idea_id: Mapped[UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("ideas.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
user_id: Mapped[UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
content: Mapped[str] = mapped_column(Text, nullable=False)
parent_id: Mapped[Optional[UUID]] = mapped_column(
UUID(as_uuid=True),
ForeignKey("idea_comments.id", ondelete="CASCADE"),
nullable=True,
)
class IdeaActivity(SQLBase, UUIDMixin, TimestampMixin):
__tablename__ = "idea_activities"
idea_id: Mapped[UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("ideas.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
user_id: Mapped[Optional[UUID]] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="SET NULL"),
nullable=True,
index=True,
)
action: Mapped[str] = mapped_column(
String(50), nullable=False
)
details: Mapped[Optional[dict]] = mapped_column(
JSONB, nullable=True
)
class Notification(SQLBase, UUIDMixin, TimestampMixin):
__tablename__ = "notifications"
user_id: Mapped[UUID] = mapped_column(
UUID(as_uuid=True),
ForeignKey("users.id", ondelete="CASCADE"),
nullable=False,
index=True,
)
type: Mapped[str] = mapped_column(
String(50), nullable=False, index=True
)
title: Mapped[str] = mapped_column(
String(255), nullable=False
)
body: Mapped[str] = mapped_column(Text, nullable=False)
link: Mapped[Optional[str]] = mapped_column(
String(512), nullable=True
)
is_read: Mapped[bool] = mapped_column(
Boolean, default=False, nullable=False, index=True
)