"""App-wide configuration that isn't tied to any single account/asset — a single-row table (id is always 1). Primary display currency (see UPDATES.md for why this doesn't do currency conversion) and the proactive-alert thresholds consumed by services/insights_service.py.""" from sqlalchemy import Integer, String from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base class AppSettings(Base): __tablename__ = "app_settings" id: Mapped[int] = mapped_column(primary_key=True) currency: Mapped[str] = mapped_column(String(3), nullable=False, default="USD") # Consecutive complete months of negative cash flow / declining net worth # before insights_service.py raises the corresponding alert. negative_cash_flow_threshold_months: Mapped[int] = mapped_column(Integer, nullable=False, default=2) net_worth_decline_threshold_months: Mapped[int] = mapped_column(Integer, nullable=False, default=2) # Max % of total capital (cash + assets) allowed in medium/high risk # tiers before insights_service.py raises risky_allocation_exceeded — # the classic "80% at zero risk, 20% at most exposed" rule. risky_allocation_threshold_percent: Mapped[int] = mapped_column(Integer, nullable=False, default=20)