From 03ced28ead09ced6756584ed54cb1f1f54f9038c Mon Sep 17 00:00:00 2001 From: Peter Woolery Date: Thu, 7 May 2026 06:21:40 -0700 Subject: [PATCH] feat: WeeklyRun model + FamilyProfile.pending_approval_policy Co-Authored-By: Claude Sonnet 4.6 (1M context) --- backend/app/models/__init__.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py index ad17efb..ced626f 100644 --- a/backend/app/models/__init__.py +++ b/backend/app/models/__init__.py @@ -95,6 +95,7 @@ class FamilyProfile(Base): dietary_notes = Column(Text) budget_per_meal = Column(Numeric(10, 2), default=50.00) calorie_target = Column(Integer) + pending_approval_policy = Column(String(10), nullable=False, server_default="approve") created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) @@ -110,6 +111,9 @@ class FamilyProfile(Base): pantry_items = relationship("HomePantry", back_populates="family_profile", cascade="all, delete-orphan") feedbacks = relationship("Feedback", back_populates="family_profile") never_suggests = relationship("NeverSuggest", back_populates="family_profile", cascade="all, delete-orphan") + weekly_runs = relationship( + "WeeklyRun", back_populates="family_profile", cascade="all, delete-orphan" + ) class FamilyMember(Base): @@ -405,3 +409,33 @@ class IngredientGroceryMatch(Base): ingredient = relationship("Ingredient", back_populates="matches") grocery_item = relationship("GroceryItem") + + +class WeeklyRun(Base): + __tablename__ = "weekly_run" + + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + family_id = Column( + UUID(as_uuid=True), + ForeignKey("family_profile.id", ondelete="CASCADE"), + nullable=False, + ) + week_start_date = Column(Date, nullable=False) + status = Column(String(20), nullable=False, default="pending") + scraped_at = Column(DateTime(timezone=True)) + generated_at = Column(DateTime(timezone=True)) + emailed_at = Column(DateTime(timezone=True)) + deadline_passed_at = Column(DateTime(timezone=True)) + finalized_at = Column(DateTime(timezone=True)) + used_stale_data = Column(Boolean, nullable=False, default=False) + error_step = Column(String(50)) + error_message = Column(Text) + created_at = Column(DateTime(timezone=True), nullable=False, server_default=func.now()) + + __table_args__ = ( + UniqueConstraint( + "family_id", "week_start_date", name="uq_weekly_run_family_week" + ), + ) + + family_profile = relationship("FamilyProfile", back_populates="weekly_runs")