Files
finance_bot/app/db/models/family.py
2025-12-10 22:09:31 +09:00

99 lines
3.6 KiB
Python

"""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"<Family(id={self.id}, name={self.name}, currency={self.currency})>"
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"<FamilyMember(family_id={self.family_id}, user_id={self.user_id}, role={self.role})>"
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"<FamilyInvite(id={self.id}, family_id={self.family_id})>"