from datetime import date from typing import Optional from sqlalchemy import Column, Integer, String, Boolean, DateTime, Date, Enum, Text, ForeignKey from sqlalchemy.orm import relationship from sqlalchemy.sql import func from app.database import Base class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True, index=True) username = Column(String(50), unique=True, index=True, nullable=False) email = Column(String(120), unique=True, index=True, nullable=False) hashed_password = Column(String(255), nullable=False) date_of_birth = Column(Date, nullable=True) is_active = Column(Boolean, default=True) role = Column(Enum("user", "moderator", "admin", name="user_role", default="user"), default="user") banned_until = Column(DateTime(timezone=True), nullable=True) suspended_until = Column(DateTime(timezone=True), nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), onupdate=func.now()) sessions = relationship("Session", back_populates="user", cascade="all, delete-orphan") worlds = relationship("World", back_populates="owner") assets = relationship("Asset", back_populates="owner") @property def is_adult(self) -> bool: """Return True if the user is 18 or older based on date_of_birth.""" if self.date_of_birth is None: return False today = date.today() age = today.year - self.date_of_birth.year # Adjust if birthday hasn't occurred yet this year if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): age -= 1 return age >= 18