fix(review): address code review findings before merge

- update_prep_task: move whitelist guard above filter so invalid column
  check runs on raw kwargs (was dead code — set(filtered) - allowed is
  always empty); fixes latent SQL injection path for future callers
- main.py: move register_kiwi_programs() into lifespan context manager
  so it runs once at startup, not at module import time
- MealPlanView.vue: remove debug console.log stubs from onSlotClick and
  onAddMealType (follow-up issue handlers, not ready for production)
This commit is contained in:
pyr0ball 2026-04-12 14:16:24 -07:00
parent e52c406d0a
commit 19c0664637
3 changed files with 4 additions and 7 deletions

View file

@ -1114,10 +1114,10 @@ class Store:
def update_prep_task(self, task_id: int, **kwargs: object) -> dict | None:
allowed = {"duration_minutes", "sequence_order", "notes", "equipment"}
updates = {k: v for k, v in kwargs.items() if k in allowed and v is not None}
invalid = set(updates) - allowed
invalid = set(kwargs) - allowed # check raw kwargs BEFORE filtering
if invalid:
raise ValueError(f"Unexpected column(s) in update_prep_task: {invalid}")
updates = {k: v for k, v in kwargs.items() if v is not None}
if not updates:
return self._fetch_one("SELECT * FROM prep_tasks WHERE id = ?", (task_id,))
set_clause = ", ".join(f"{k} = ?" for k in updates)

View file

@ -11,8 +11,6 @@ from app.api.routes import api_router
from app.core.config import settings
from app.services.meal_plan.affiliates import register_kiwi_programs
register_kiwi_programs()
logger = logging.getLogger(__name__)
@ -20,6 +18,7 @@ logger = logging.getLogger(__name__)
async def lifespan(app: FastAPI):
logger.info("Starting Kiwi API...")
settings.ensure_dirs()
register_kiwi_programs()
# Start LLM background task scheduler
from app.tasks.scheduler import get_scheduler

View file

@ -110,14 +110,12 @@ async function onSelectPlan(planId: number) {
if (planId) await store.setActivePlan(planId)
}
function onSlotClick({ dayOfWeek, mealType }: { dayOfWeek: number; mealType: string }) {
function onSlotClick(_: { dayOfWeek: number; mealType: string }) {
// Recipe picker integration filed as follow-up
console.log('[MealPlan] slot-click', { dayOfWeek, mealType })
}
function onAddMealType() {
// Add meal type picker Paid gate enforced by backend
console.log('[MealPlan] add-meal-type')
}
</script>