Public Access
feat: feedback-driven recipe discovery (auto-ingest via Spoonacular)
This commit is contained in:
@@ -24,6 +24,10 @@ from app.services.orchestrator.alerts import send_admin_alert
|
||||
from app.services.planner.generate import generate_meal_plan
|
||||
from app.services.scraper_service import ScraperService
|
||||
|
||||
from app.services.feedback_analyzer import FeedbackAnalyzer
|
||||
from app.services.recipe_discovery import RecipeDiscoveryService
|
||||
from app.services.recipe_ingestion import RecipeIngestionService
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sqlalchemy.orm import Session
|
||||
from app.models import WeeklyRun
|
||||
@@ -456,6 +460,32 @@ def step_finalize(run: "WeeklyRun", db: "Session") -> None:
|
||||
|
||||
run.finalized_at = datetime.now(timezone.utc)
|
||||
run.status = "completed"
|
||||
|
||||
# --- Feedback-driven recipe discovery ---
|
||||
try:
|
||||
analyzer = FeedbackAnalyzer(lookback_weeks=4)
|
||||
analysis = analyzer.analyze(db, run.family_id)
|
||||
run.feedback_analysis = analysis.to_dict()
|
||||
|
||||
if (
|
||||
analysis.discovery_queries and
|
||||
analysis.confidence >= 0.5
|
||||
):
|
||||
discovery = RecipeDiscoveryService()
|
||||
candidates = discovery.discover(analysis.discovery_queries)
|
||||
if candidates:
|
||||
ingestion = RecipeIngestionService()
|
||||
added = ingestion.ingest(db, run.family_id, candidates, analysis.to_dict())
|
||||
logger.info(
|
||||
"step_finalize: recipe discovery added %d new recipes for family %s",
|
||||
added, run.family_id,
|
||||
)
|
||||
# ingestion deliberately does not commit so orchestrator
|
||||
# can keep everything in one transaction
|
||||
db.commit()
|
||||
except Exception as exc:
|
||||
# Discovery is best-effort; never block finalization
|
||||
logger.warning("step_finalize: recipe discovery failed: %s", exc)
|
||||
db.commit()
|
||||
logger.info("step_finalize: done, %d approved meals", len(approved_items))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user