83 lines
2.6 KiB
Python
83 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
import datetime
|
|
from typing import List, Optional
|
|
|
|
import aiosqlite
|
|
from fastapi import APIRouter, Depends, Query, Request, Response
|
|
|
|
import meals
|
|
from common import ProblemDetails
|
|
from api.deps import error_response
|
|
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
|
|
|
|
|
|
@router.get(
|
|
"/{meal_id}",
|
|
operation_id="getMealV2",
|
|
summary="Get a meal by id (scoped)",
|
|
response_model=meals.Meal,
|
|
responses={404: {"model": ProblemDetails}},
|
|
)
|
|
async def get_meal_scoped(
|
|
meal_id: int,
|
|
request: Request,
|
|
household=Depends(get_household_from_slug),
|
|
conn: aiosqlite.Connection = Depends(get_db),
|
|
) -> meals.Meal | Response:
|
|
hid = household["id"]
|
|
meal = await meals.find_meal_by_id_scoped(conn, meal_id, hid)
|
|
if not meal:
|
|
return error_response(request, 404, "Meal not found")
|
|
return meal
|