"""Family and Family-related models""" from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Enum from sqlalchemy.orm import relationship from datetime import datetime from enum import Enum as PyEnum from app.db.database import Base class FamilyRole(str, PyEnum): """Roles in family""" OWNER = "owner" MEMBER = "member" RESTRICTED = "restricted" class Family(Base): """Family model - represents a family group""" __tablename__ = "families" id = Column(Integer, primary_key=True) owner_id = Column(Integer, ForeignKey("users.id"), nullable=False) name = Column(String(255), nullable=False) description = Column(String(500), nullable=True) currency = Column(String(3), default="RUB") # ISO 4217 code invite_code = Column(String(20), unique=True, nullable=False, index=True) # Settings notification_level = Column(String(50), default="all") # all, important, none accounting_period = Column(String(20), default="month") # week, month, year # Status is_active = Column(Boolean, default=True) # Timestamps created_at = Column(DateTime, default=datetime.utcnow, nullable=False) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) # Relationships members = relationship("FamilyMember", back_populates="family", cascade="all, delete-orphan") invites = relationship("FamilyInvite", back_populates="family", cascade="all, delete-orphan") accounts = relationship("Account", back_populates="family", cascade="all, delete-orphan") categories = relationship("Category", back_populates="family", cascade="all, delete-orphan") budgets = relationship("Budget", back_populates="family", cascade="all, delete-orphan") goals = relationship("Goal", back_populates="family", cascade="all, delete-orphan") def __repr__(self) -> str: return f"" class FamilyMember(Base): """Family member model - user membership in family""" __tablename__ = "family_members" id = Column(Integer, primary_key=True) family_id = Column(Integer, ForeignKey("families.id"), nullable=False, index=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False, index=True) role = Column(Enum(FamilyRole), default=FamilyRole.MEMBER) # Permissions can_edit_budget = Column(Boolean, default=True) can_manage_members = Column(Boolean, default=False) # Timestamps joined_at = Column(DateTime, default=datetime.utcnow, nullable=False) # Relationships family = relationship("Family", back_populates="members") user = relationship("User", back_populates="family_members") def __repr__(self) -> str: return f"" class FamilyInvite(Base): """Family invite model - pending invitations""" __tablename__ = "family_invites" id = Column(Integer, primary_key=True) family_id = Column(Integer, ForeignKey("families.id"), nullable=False, index=True) invite_code = Column(String(20), unique=True, nullable=False, index=True) created_by_id = Column(Integer, ForeignKey("users.id"), nullable=False) # Invite validity is_active = Column(Boolean, default=True) expires_at = Column(DateTime, nullable=True) # Timestamps created_at = Column(DateTime, default=datetime.utcnow, nullable=False) # Relationships family = relationship("Family", back_populates="invites") def __repr__(self) -> str: return f""