from __future__ import annotations import datetime from typing import List import aiosqlite from fastapi import APIRouter, Depends, Query import meals from api.deps import get_db, get_household_from_slug router = APIRouter(prefix="/households/{householdSlug}/meals", tags=["meals-v2"]) @router.get( "/upcoming", operation_id="getUpcomingMealsV2", summary="List upcoming meals in a date range (scoped)", ) async def get_upcoming_meals_scoped( household=Depends(get_household_from_slug), date_from: datetime.datetime = Query(..., alias="from"), to: datetime.datetime = Query(...), conn: aiosqlite.Connection = Depends(get_db), ) -> List[meals.Meal]: hid = household["id"] # Use a scoped repository function, falling back to filtering in SQL until repository is fully scoped try: async for _ in meals.find_upcoming_meals_by_date_range_scoped(conn, date_from, to, hid): # if function exists, break immediately to use it break use_scoped = True except AttributeError: use_scoped = False result: List[meals.Meal] = [] if use_scoped: async for meal in meals.find_upcoming_meals_by_date_range_scoped(conn, date_from, to, hid): result.append(meal) else: # Temporary path: direct query with household_id filter async with conn.execute( f""" SELECT {','.join(meals.Meal.KEYS)} FROM Meal WHERE suggested_date >= ? AND suggested_date <= ? AND consumed_date IS NULL AND deleted_date IS NULL AND household_id = ? """, (date_from, to, hid), ) as cursor: async for row in cursor: result.append(meals.Meal(**{k: v for k, v in zip(meals.Meal.KEYS, row)})) if not result: return result # Load relateds similar to v1 await meals.bulk_load_participants(conn, result) for meal in result: await meals.load_recipes(conn, meal) await meals.load_extra_ingredients(conn, meal) return result