# /opt/docker/dev/service_finder/backend/app/models/gamification.py import uuid from datetime import datetime from typing import Optional, List, TYPE_CHECKING from sqlalchemy import ForeignKey, String, Integer, DateTime, func, Boolean, Text, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.dialects.postgresql import UUID as PG_UUID from app.database import Base # MB 2.0: Központi Base if TYPE_CHECKING: from app.models.identity import User class PointRule(Base): __tablename__ = "point_rules" __table_args__ = {"schema": "data"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) action_key: Mapped[str] = mapped_column(String, unique=True, index=True) points: Mapped[int] = mapped_column(Integer, default=0) description: Mapped[Optional[str]] = mapped_column(String) is_active: Mapped[bool] = mapped_column(Boolean, default=True) class LevelConfig(Base): __tablename__ = "level_configs" __table_args__ = {"schema": "data"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) level_number: Mapped[int] = mapped_column(Integer, unique=True) min_points: Mapped[int] = mapped_column(Integer) rank_name: Mapped[str] = mapped_column(String) class PointsLedger(Base): __tablename__ = "points_ledger" __table_args__ = {"schema": "data"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) # MB 2.0: User az identity sémában lakik! user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id")) points: Mapped[int] = mapped_column(Integer, default=0) penalty_change: Mapped[int] = mapped_column(Integer, server_default=text("0"), default=0) reason: Mapped[str] = mapped_column(String) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) user: Mapped["User"] = relationship("User") class UserStats(Base): __tablename__ = "user_stats" __table_args__ = {"schema": "data"} # MB 2.0: User az identity sémában lakik! user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"), primary_key=True) total_xp: Mapped[int] = mapped_column(Integer, default=0) social_points: Mapped[int] = mapped_column(Integer, default=0) current_level: Mapped[int] = mapped_column(Integer, default=1) penalty_points: Mapped[int] = mapped_column(Integer, server_default=text("0"), default=0) restriction_level: Mapped[int] = mapped_column(Integer, server_default=text("0"), default=0) updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) user: Mapped["User"] = relationship("User", back_populates="stats") class Badge(Base): __tablename__ = "badges" __table_args__ = {"schema": "data"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) name: Mapped[str] = mapped_column(String, unique=True) description: Mapped[str] = mapped_column(String) icon_url: Mapped[Optional[str]] = mapped_column(String) class UserBadge(Base): __tablename__ = "user_badges" __table_args__ = {"schema": "data"} id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True) # MB 2.0: User az identity sémában lakik! user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id")) badge_id: Mapped[int] = mapped_column(Integer, ForeignKey("data.badges.id")) earned_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) user: Mapped["User"] = relationship("User")