átlagos kiegészítséek jó sok
This commit is contained in:
144
backend/app/models/gamification/gamification.py
Executable file
144
backend/app/models/gamification/gamification.py
Executable file
@@ -0,0 +1,144 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/models/gamification/gamification.py
|
||||
import uuid
|
||||
from datetime import datetime, date
|
||||
from typing import Optional, List, TYPE_CHECKING
|
||||
from sqlalchemy import ForeignKey, String, Integer, DateTime, func, Boolean, Text, text, Date
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from sqlalchemy.dialects.postgresql import UUID as PG_UUID, JSONB
|
||||
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": "gamification", "extend_existing": True}
|
||||
|
||||
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": "gamification", "extend_existing": True}
|
||||
|
||||
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": "gamification", "extend_existing": True}
|
||||
|
||||
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": "gamification", "extend_existing": True}
|
||||
|
||||
# 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)
|
||||
penalty_quota_remaining: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
||||
places_discovered: Mapped[int] = mapped_column(Integer, default=0, server_default=text("0"))
|
||||
places_validated: Mapped[int] = mapped_column(Integer, default=0, server_default=text("0"))
|
||||
banned_until: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
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": "gamification", "extend_existing": True}
|
||||
|
||||
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": "gamification", "extend_existing": True}
|
||||
|
||||
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("gamification.badges.id"))
|
||||
|
||||
earned_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
user: Mapped["User"] = relationship("User")
|
||||
|
||||
|
||||
class UserContribution(Base):
|
||||
"""
|
||||
Felhasználói hozzájárulások nyilvántartása (szerviz beküldés, validálás, jelentés).
|
||||
Ez a tábla tárolja, hogy melyik felhasználó milyen tevékenységet végzett és milyen jutalmat kapott.
|
||||
"""
|
||||
__tablename__ = "user_contributions"
|
||||
__table_args__ = {"schema": "gamification"}
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
|
||||
user_id: Mapped[int] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=False, index=True)
|
||||
season_id: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("gamification.seasons.id"), nullable=True, index=True)
|
||||
|
||||
# --- HIÁNYZÓ MEZŐK PÓTOLVA A SPAM VÉDELEMHEZ ---
|
||||
service_fingerprint: Mapped[Optional[str]] = mapped_column(String(255), index=True)
|
||||
cooldown_end: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True))
|
||||
|
||||
action_type: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
earned_xp: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
contribution_type: Mapped[str] = mapped_column(String(50), nullable=False, index=True) # 'service_submission', 'service_validation', 'report_abuse'
|
||||
entity_type: Mapped[Optional[str]] = mapped_column(String(50), index=True) # 'service', 'review', 'comment'
|
||||
entity_id: Mapped[Optional[int]] = mapped_column(Integer, index=True) # ID of the contributed entity
|
||||
|
||||
points_awarded: Mapped[int] = mapped_column(Integer, default=0)
|
||||
xp_awarded: Mapped[int] = mapped_column(Integer, default=0)
|
||||
|
||||
status: Mapped[str] = mapped_column(String(20), default="pending", index=True) # 'pending', 'approved', 'rejected'
|
||||
reviewed_by: Mapped[Optional[int]] = mapped_column(Integer, ForeignKey("identity.users.id"), nullable=True)
|
||||
reviewed_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||
|
||||
# --- JAVÍTOTT FOGLALT SZÓ ---
|
||||
provided_fields: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True)
|
||||
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
# Relationships
|
||||
user: Mapped["User"] = relationship("User", foreign_keys=[user_id])
|
||||
reviewer: Mapped[Optional["User"]] = relationship("User", foreign_keys=[reviewed_by])
|
||||
season: Mapped[Optional["Season"]] = relationship("Season")
|
||||
|
||||
|
||||
class Season(Base):
|
||||
""" Szezonális versenyek tárolása. """
|
||||
__tablename__ = "seasons"
|
||||
__table_args__ = {"schema": "gamification"}
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True)
|
||||
name: Mapped[str] = mapped_column(String(100), nullable=False)
|
||||
start_date: Mapped[date] = mapped_column(Date, nullable=False)
|
||||
end_date: Mapped[date] = mapped_column(Date, nullable=False)
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
|
||||
Reference in New Issue
Block a user