Meal request requires user

This commit is contained in:
jableader 2025-11-02 17:51:02 +11:00
parent b7a737ddaa
commit 83388b2925
3 changed files with 8 additions and 97 deletions

View file

@ -167,6 +167,7 @@ async def request_meal_scoped(
r: MealIdWrapper,
request: Request,
household=Depends(get_household_from_slug),
user=Depends(get_current_user),
conn: aiosqlite.Connection = Depends(get_db),
):
hid = household["id"]
@ -177,7 +178,7 @@ async def request_meal_scoped(
return error_response(request, 404, "Meal not found")
try:
item = await shopping.request_meal_scoped(conn, meal, hid)
item = await shopping.request_meal_scoped(conn, meal, hid, user.id)
except ValueError as e:
return error_response(request, 400, str(e))
return _to_meal_item(item)

View file

@ -280,24 +280,25 @@ async def request(
async def request_meal_scoped(
conn, meal: Any, household_id: int, person_id: Optional[int] = None
conn, meal: Any, household_id: int, person_id: int
) -> ShoppingListItem:
if meal is None or getattr(meal, "id", -1) < 0:
raise ValueError("Meal must have a valid id")
if await is_requested_scoped(conn, meal.id, household_id):
raise ValueError("Meal is already requested")
# Use 0 for outward personId to satisfy schema without binding to v1 persons
pid = person_id if person_id is not None else 0
# Require a valid person id
if person_id is None or person_id < 0:
raise ValueError("Meal request must have a valid person id")
item = ShoppingListItem(ingredient_id=None, person_id=pid, meal_id=meal.id)
item = ShoppingListItem(ingredient_id=None, person_id=person_id, meal_id=meal.id)
async with conn.execute(
"""
INSERT INTO ShoppingListItem (ingredient_id, person_id, meal_id, created_date, household_id)
VALUES (?, ?, ?, ?, ?)
""",
(None, pid, meal.id, item.created_date.isoformat(), household_id),
(None, person_id, meal.id, item.created_date.isoformat(), household_id),
) as cursor:
item.id = cursor.lastrowid

View file

@ -1,91 +0,0 @@
import asyncio
import aiosqlite
import db
from tests.test_data import create_test_data
from scripts.migration_to_households import run_migration
async def table_has_column(conn: aiosqlite.Connection, table: str, col: str) -> bool:
async with conn.execute(f"PRAGMA table_info({table});") as c:
async for row in c:
if row[1] == col:
return True
return False
def test_migration_adds_tables_and_columns_and_ports_data(tmp_path):
async def _run():
db_path = tmp_path / "test.sqlite"
conn = await db.connect(str(db_path))
# Bootstrap v1 schema
await db.create(conn)
await conn.commit()
# Seed some v1 data (persons, products, recipes, meals)
await create_test_data(conn)
await conn.commit()
# Run migration
await run_migration(conn)
# Verify new tables exist
for tbl in [
"User",
"LocalCredentials",
"OAuthCredentials",
"Household",
"HouseholdMember",
"HouseholdInvitation",
]:
async with conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name=?;", (tbl,)
) as c:
assert await c.fetchone() is not None, f"Missing table {tbl}"
# Verify household_id column exists on tenant tables
tenant_tables = [
"Recipe",
"Ingredient",
"Meal",
"MealParticipant",
"MealRecipe",
"ShoppingList",
"ShoppingListItem",
]
for tbl in tenant_tables:
assert await table_has_column(conn, tbl, "household_id"), f"{tbl} lacks household_id"
# Default household exists
async with conn.execute(
"SELECT id, slug FROM Household WHERE slug='default' LIMIT 1;"
) as c:
row = await c.fetchone()
assert row is not None
# Persons were ported to Users and memberships created (if legacy Person table exists)
try:
async with conn.execute("SELECT COUNT(1) FROM Person;") as c:
row = await c.fetchone()
assert row is not None
person_count = int(row[0])
except Exception:
person_count = 0
async with conn.execute("SELECT COUNT(1) FROM User;") as c:
row = await c.fetchone()
assert row is not None
user_count = int(row[0])
if person_count > 0:
assert user_count == person_count
async with conn.execute("SELECT COUNT(1) FROM HouseholdMember;") as c:
row = await c.fetchone()
assert row is not None
member_count = int(row[0])
if person_count > 0:
assert member_count == person_count
await conn.close()
asyncio.run(_run())