Public Access
feat(meals): enforce three lower-calorie dinners with media
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from sqlalchemy import (
|
||||
Column, String, Integer, Numeric, Float, Text, Boolean, Date, DateTime,
|
||||
ForeignKey, CheckConstraint, UniqueConstraint, Enum as SQLEnum
|
||||
ForeignKey, CheckConstraint, UniqueConstraint, Index, Enum as SQLEnum
|
||||
)
|
||||
from sqlalchemy.dialects.postgresql import UUID, JSONB, ARRAY
|
||||
from sqlalchemy.orm import relationship
|
||||
@@ -85,6 +85,18 @@ class IngredientMatchSource(enum.Enum):
|
||||
MANUAL = "manual"
|
||||
|
||||
|
||||
class RecipeImportStatus(str, enum.Enum):
|
||||
PENDING = "pending"
|
||||
QUARANTINED = "quarantined"
|
||||
APPROVED = "approved"
|
||||
REJECTED = "rejected"
|
||||
|
||||
|
||||
class RecipeCatalogStatus(str, enum.Enum):
|
||||
ACTIVE = "active"
|
||||
QUARANTINED = "quarantined"
|
||||
|
||||
|
||||
class FamilyProfile(Base):
|
||||
__tablename__ = "family_profile"
|
||||
|
||||
@@ -186,6 +198,19 @@ class Recipe(Base):
|
||||
external_source = Column(String(50))
|
||||
external_id = Column(String(100))
|
||||
discovery_reason = Column(Text)
|
||||
catalog_status = Column(
|
||||
SQLEnum(
|
||||
RecipeCatalogStatus,
|
||||
name="recipe_catalog_status_enum",
|
||||
create_type=False,
|
||||
values_callable=lambda obj: [e.value for e in obj],
|
||||
),
|
||||
nullable=False,
|
||||
default=RecipeCatalogStatus.ACTIVE,
|
||||
server_default="active",
|
||||
)
|
||||
catalog_findings = Column(JSONB, nullable=False, default=list, server_default="[]")
|
||||
catalog_reviewed_at = Column(DateTime(timezone=True))
|
||||
created_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
|
||||
@@ -197,6 +222,63 @@ class Recipe(Base):
|
||||
return (self.prep_time_minutes or 0) + (self.cook_time_minutes or 0)
|
||||
|
||||
|
||||
class RecipeImportStaging(Base):
|
||||
"""Auditable, globally scoped recipe import candidate awaiting review."""
|
||||
|
||||
__tablename__ = "recipe_import_staging"
|
||||
|
||||
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
||||
source = Column(String(100), nullable=False)
|
||||
external_id = Column(String(255), nullable=False)
|
||||
source_url = Column(Text, nullable=False)
|
||||
source_revision = Column(String(255), nullable=False)
|
||||
license_name = Column(String(255), nullable=False)
|
||||
license_url = Column(Text, nullable=False)
|
||||
attribution = Column(Text, nullable=False)
|
||||
raw_payload = Column(JSONB, nullable=False)
|
||||
payload_sha256 = Column(String(64), nullable=False)
|
||||
normalized_recipe = Column(JSONB, nullable=False)
|
||||
validation_report = Column(JSONB, nullable=False)
|
||||
status = Column(
|
||||
SQLEnum(
|
||||
RecipeImportStatus,
|
||||
name="recipe_import_status_enum",
|
||||
create_type=False,
|
||||
values_callable=lambda obj: [e.value for e in obj],
|
||||
),
|
||||
nullable=False,
|
||||
default=RecipeImportStatus.PENDING,
|
||||
server_default="pending",
|
||||
)
|
||||
rejection_reason = Column(Text)
|
||||
recipe_id = Column(UUID(as_uuid=True), ForeignKey("recipe.id", ondelete="SET NULL"))
|
||||
acquired_at = Column(
|
||||
DateTime(timezone=True), nullable=False, server_default=func.now()
|
||||
)
|
||||
reviewed_at = Column(DateTime(timezone=True))
|
||||
reviewed_by = Column(String(300))
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
"source",
|
||||
"external_id",
|
||||
"source_revision",
|
||||
name="uq_recipe_import_staging_source_revision",
|
||||
),
|
||||
CheckConstraint(
|
||||
"payload_sha256 ~ '^[0-9a-f]{64}$'",
|
||||
name="ck_recipe_import_staging_payload_sha256",
|
||||
),
|
||||
CheckConstraint(
|
||||
"(reviewed_at IS NULL) = (reviewed_by IS NULL)",
|
||||
name="ck_recipe_import_staging_review_metadata",
|
||||
),
|
||||
Index("ix_recipe_import_staging_status_acquired_at", "status", "acquired_at"),
|
||||
)
|
||||
|
||||
recipe = relationship("Recipe")
|
||||
|
||||
|
||||
class MealPlan(Base):
|
||||
__tablename__ = "meal_plan"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user