diff --git a/api/deps.py b/api/deps.py index 83c55e5..c17ab0f 100644 --- a/api/deps.py +++ b/api/deps.py @@ -3,11 +3,10 @@ from __future__ import annotations from typing import AsyncGenerator, Optional import aiosqlite -from fastapi import Cookie, Depends, HTTPException, Request +from fastapi import Depends, HTTPException, Request from fastapi.responses import JSONResponse import db -import persons from common import ProblemDetails from settings import settings from users.models import User @@ -45,34 +44,6 @@ async def get_db() -> AsyncGenerator[aiosqlite.Connection, None]: await sql_db.close() -async def cookie_person( - user_id: int = Cookie(..., alias="user_id"), - conn: aiosqlite.Connection = Depends(get_db), -) -> persons.Person: - """Return the authenticated user from the user_id cookie or raise 401. - - When the cookie is missing, FastAPI will raise 422 (validation error). - """ - person = await persons.get_by_id(conn, user_id) - if not person: - raise HTTPException(status_code=401, detail="Unauthorized") - return person - - -async def cookie_person_optional( - user_id: Optional[int] = Cookie(default=None, alias="user_id"), - conn: aiosqlite.Connection = Depends(get_db), -) -> Optional[persons.Person]: - """Return the authenticated user if cookie present; otherwise None. - - Use for endpoints that want to return 401 for missing auth themselves. - """ - if user_id is None: - return None - person = await persons.get_by_id(conn, user_id) - return person - - def error_response(request: Optional[Request], status_code: int, message: str) -> JSONResponse: body = ProblemDetails( title=message, diff --git a/backend-spec.md b/backend-spec.md index ded8816..100054c 100644 --- a/backend-spec.md +++ b/backend-spec.md @@ -149,7 +149,7 @@ Refactor the backend from a single-tenant architecture to a robust, multi-tenant - `POST /api/v1/auth/logout`: clears refresh cookie. After logout, subsequent `POST /api/v1/auth/refresh` returns 401. Notes: -- `get_current_user` (JWT) is used by protected endpoints (households, shopping purchase, etc.). Legacy `cookie_person` remains only for historical v1 module references and will be removed with full v2 completion. +- `get_current_user` (JWT) is used by protected endpoints (households, shopping purchase, etc.). Legacy cookie-based helpers have been removed from the app surface. - RFC7807 error semantics and the existing OpenAPI augmentation are preserved. The special-case 401 mapping for POST shopping is obsolete under JWT. ### 3.2. Household & Tenancy API (current) @@ -296,7 +296,7 @@ Remaining work (prioritized cleanup to final state): 1. Remove the `persons/` package and all code references across domains (recipes, meals, shopping). Replace `Person` with `users`/HouseholdMember everywhere: - Code hotspots today: `recipes/models.py` (imports Person), `recipes/repository.py` (FKs, hide_recipe signature), `meals/models.py` (participants as List[Person]), `api/shopping_models.py` and `shopping/models.py` (ShoppingList.purchased_by typed as Person), and `shopping/repository.py` (FKs to Person). - Replace internal usages with `user_id`/`MemberRef` where outward, and update repository DDL to stop referencing `Person`. - - Remove `api.deps.cookie_person` once no tests or code depend on it. + - Removed `api.deps.cookie_person` and `cookie_person_optional`; v1 tests referencing them remain skipped and will be deleted or ported. - Ensure no API module performs direct SQL; all persistence must flow through repositories (enforced during cleanup). 2. Recipes outward schema: DONE for `createdById`/`createdBy` and `hiddenById`/`hiddenBy` (MemberRef on delete). If/when we expose hide actor on other flows, keep MemberRef. 3. Shopping outward DTOs: DONE — `ShoppingListOut.purchasedBy` is a MemberRef; mapping added. Ensure clients shift to `displayName`. diff --git a/recipes/__init__.py b/recipes/__init__.py index 9a59703..517de5c 100644 --- a/recipes/__init__.py +++ b/recipes/__init__.py @@ -17,7 +17,6 @@ from recipes.repository import ( get_all as get_all, get_all_paged as get_all_paged, get_all_paged_scoped as get_all_paged_scoped, - hide_recipe as hide_recipe, insert_recipe as insert_recipe, insert_recipe_scoped as insert_recipe_scoped, load_recipe_ingredients as load_recipe_ingredients, diff --git a/recipes/repository.py b/recipes/repository.py index 807d139..90825d5 100644 --- a/recipes/repository.py +++ b/recipes/repository.py @@ -74,17 +74,6 @@ async def insert_recipe_scoped(conn, recipe: Recipe, household_id: int): recipe.id = cursor.lastrowid -async def hide_recipe(conn, recipe_id: int, person): - await conn.execute( - """ - UPDATE Recipe - SET date_hidden = ?, hidden_by_id = ? - WHERE id = ? - """, - (datetime.datetime.now().astimezone().isoformat(), person.id, recipe_id), - ) - - async def hide_recipe_scoped(conn, recipe_id: int, household_id: int) -> bool: """Soft-delete a recipe by household for v2.