import datetime from sqlalchemy import Date, ForeignKey, Integer, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from fooder.domain.base import Base, CommonMixin from fooder.domain.meal import Meal class Diary(Base, CommonMixin): """Diary represents user diary for given day.""" __table_args__ = (UniqueConstraint("user_id", "date"),) meals: Mapped[list[Meal]] = relationship( lazy="selectin", order_by=Meal.order.desc() ) date: Mapped[datetime.date] = mapped_column(Date) user_id: Mapped[int] = mapped_column(Integer, ForeignKey("user.id")) # snapshot of user settings at diary creation time — intentionally decoupled # from UserSettings so historical goals don't change when settings are updated protein_goal: Mapped[float] carb_goal: Mapped[float] fat_goal: Mapped[float] fiber_goal: Mapped[float] calories_goal: Mapped[float] @property def calories(self) -> float: return sum(meal.calories for meal in self.meals) @property def protein(self) -> float: return sum(meal.protein for meal in self.meals) @property def carb(self) -> float: return sum(meal.carb for meal in self.meals) @property def fat(self) -> float: return sum(meal.fat for meal in self.meals) @property def fiber(self) -> float: return sum(meal.fiber for meal in self.meals)