# /opt/docker/dev/service_finder/backend/app/models/social.py import enum from datetime import datetime from typing import Optional, List from sqlalchemy import String, Integer, ForeignKey, DateTime, Boolean, Text, UniqueConstraint, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.dialects.postgresql import ENUM as PG_ENUM from sqlalchemy.sql import func from app.db.base_class import Base class ModerationStatus(str, enum.Enum): pending = "pending" approved = "approved" rejected = "rejected" class SourceType(str, enum.Enum): manual = "manual" ocr = "ocr" api_import = "import" class ServiceProvider(Base): """ Közösség által beküldött szolgáltatók (v1.3.1). """ __tablename__ = "service_providers" id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) name: Mapped[str] = mapped_column(String, nullable=False) address: Mapped[str] = mapped_column(String, nullable=False) category: Mapped[Optional[str]] = mapped_column(String) status: Mapped[ModerationStatus] = mapped_column( PG_ENUM(ModerationStatus, name="moderation_status", inherit_schema=True), default=ModerationStatus.pending ) source: Mapped[SourceType] = mapped_column( PG_ENUM(SourceType, name="source_type", inherit_schema=True), default=SourceType.manual ) validation_score: Mapped[int] = mapped_column(Integer, default=0) evidence_image_path: Mapped[Optional[str]] = mapped_column(String) added_by_user_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id")) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) class Vote(Base): """ Közösségi validációs szavazatok. """ __tablename__ = "votes" __table_args__ = ( UniqueConstraint('user_id', 'provider_id', name='uq_user_provider_vote'), ) id: Mapped[int] = mapped_column(Integer, primary_key=True) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=False) provider_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.service_providers.id"), nullable=False) vote_value: Mapped[int] = mapped_column(Integer, nullable=False) # +1 vagy -1 class Competition(Base): """ Gamifikált versenyek (pl. Januári Feltöltő Verseny). """ __tablename__ = "competitions" id: Mapped[int] = mapped_column(Integer, primary_key=True) name: Mapped[str] = mapped_column(String, nullable=False) description: Mapped[Optional[str]] = mapped_column(Text) start_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) end_date: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) is_active: Mapped[bool] = mapped_column(Boolean, default=True) class UserScore(Base): """ Versenyenkénti ranglista pontszámok. """ __tablename__ = "user_scores" __table_args__ = ( UniqueConstraint('user_id', 'competition_id', name='uq_user_competition_score'), ) id: Mapped[int] = mapped_column(Integer, primary_key=True) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id")) competition_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.competitions.id")) points: Mapped[int] = mapped_column(Integer, default=0) last_updated: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())