diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 4edf65a..f80c5e7 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -2,13 +2,22 @@ You are taking over a project in mid-flight. Read `docs/ORIENTATION.md` first for the high-level. This file is the deep dive: what's real, what's stubbed, where the bodies are buried, and what to do next. -**Date of handoff: 2026-05-14. Last commits before handoff:** +**Date of handoff: 2026-06-03. Last commits before handoff:** ``` -[pending] feat: Phase 8 Feedback UI + API endpoints -[pending] fix: RecipeIngredient schema qty→quantity model_validator +427d8ac docs(review): add handoff document for UI audit work +e90a9d6 feat(ui): close 3 P2 audit findings + a11y sweep (Sprint 3) +f5fb755 fix(migration): simplify aisle migration + add persistent backup script +ccc70aa feat(ui): close 6 P1 audit findings + 1 bonus mobile fix (Sprint 2) +36038bb docs(review): mark Sprint 1 P0 fixes addressed in commit f3e4a44 +f3e4a44 fix(ui): close 5 P0 audit findings (ingredients, cost, routing, mobile slots) b522760 fix: cast qty/unit to str before html.escape in vote email shopping preview ``` +**Focused UI/UX audit handoff** (Sprints 1, 2, 3 — 14 findings closed across 3 commits): +see `Review/handoff-ui-audit.md`. That doc is the right starting point for +anyone continuing the UI/UX work; the present file remains the project-wide +overview (backend, infra, family data, admin API, prior phases). + --- ## TL;DR @@ -287,9 +296,101 @@ backend/app/schemas/__init__.py — RecipeIngredient model_validator q Trust the tests. Trust the live runs. Don't trust prose claims that something is "complete" without running the verification gate yourself. **Current open proposals:** -- None — feedback-driven recipe discovery implemented and verified. +- `docs/proposals/2026-05-23-feedback-driven-recipe-discovery.md` — pending user approval. No code yet (per the 2026-05-23 section below). -**Last updated: 2026-05-24** — Feedback-driven recipe discovery (Phases A–D) complete. +**Last updated: 2026-06-03** — UI/UX audit & fix cycle (Sprints 1, 2, 3) complete. 14 findings closed, code committed (`f3e4a44`, `ccc70aa`, `f5fb755`, `e90a9d6`), build green. Sprint 1 deployed; Sprints 2 and 3 awaiting deploy on the user's home server. Backend migration `0015_normalize_pantry_aisles.py` not yet run on prod (dry-run shows 21k rows would change on dev DB). Full UI-audit handoff at `Review/handoff-ui-audit.md`. + +--- + +## New session: 2026-06-03 + +### UI/UX audit & fix — 3 sprints, 14 findings closed + +A full Nielsen-10-heuristics audit of the live deployment at `http://100.108.208.56:8082/` was performed using Playwright (NixOS-compatible Chromium at `/run/current-system/sw/bin/chromium --no-sandbox`; original screenshots in `/tmp/opencode/mp-review/screenshots/`). 14 findings (5 P0, 6 P1, 3 P2) plus 3 a11y items were addressed in three sprints, each ending in `npm run build` green. + +**Audit & plan documents (all kept in sync, all in `Review/`):** +- `Review/ui-nielsen-audit.md` — the audit itself, with status blocks per sprint at the top +- `fix-ui-audit.md` — the implementation plan, with per-task implementation notes +- `Review/sprint2-verification.md` — Sprint 2 deploy + smoke-check checklist (includes the **backend migration** step) +- `Review/sprint3-verification.md` — Sprint 3 deploy + smoke-check checklist (frontend only) +- `Review/handoff-ui-audit.md` — focused handoff for a fresh agent continuing UI-audit work + +**Commits on `main` (ahead of `origin/main` by 9 prior WIP commits plus these 6):** + +| Commit | Sprint | What | +|---|---|---| +| `f3e4a44` | 1 | 5 P0 blockers: recipe/meal ingredient field names, `$N/A` cost, `/recommended` 404, mobile empty slots | +| `36038bb` | 1 (docs) | Mark Sprint 1 P0 fixes in audit doc | +| `ccc70aa` | 2 | 6 P1s + S3.3: meal-card title clamp, MealDetail hero + SEO strip, pantry aisle select, shopping-list aisle map, mobile pantry scroll hint, recipes filters w/ Apply/Reset/active-count, mobile shopping-list 3-col grid | +| `f5fb755` | 2 (fix) | Migration 0015 simplification + persistent backup script (`persist_aisle_backup.sql`) + corrected container-based deploy commands | +| `e90a9d6` | 3 | 3 P2s + a11y: undo-toast (Dashboard refills slot; Pantry fully reversible), mobile nav nowrap, aria-current, `
`, Badge `aria-label`/`icon` props | +| `427d8ac` | (docs) | Review/handoff-ui-audit.md | + +**Critical Sprint 2 deploy note:** the user must run on the deployment host *after* `git pull`: + +```bash +# 1. Persistent backup BEFORE the migration (recommended) +docker compose exec -T db psql -U mealplanner -d mealplanner \ + -f /dev/stdin < backend/scripts/persist_aisle_backup.sql + +# 2. Dry-run preview (no writes) +docker compose exec -T db psql -U mealplanner -d mealplanner \ + -f /dev/stdin < backend/scripts/dry_run_aisle_migration.sql + +# 3. Apply the migration +docker compose exec backend alembic upgrade head + +# 4. Frontend rebuild + restart +docker compose -f docker-compose.yml up -d --build frontend +``` + +The dev DB dry-run on this host shows 10,657 ingredient rows + 10,539 grocery_item rows = **21,196 rows** would change. The deployment-host DB will differ — operator judgment required. The `persist_aisle_backup.sql` creates two permanent `public.*_aisle_backup_0015` tables the operator can `DROP` after confidence is established. + +**Sprint 3 deploy is frontend-only:** +```bash +git pull +docker compose -f docker-compose.yml up -d --build frontend +``` + +### Deployment-host vs dev-host (Tailscale gotcha) + +This repo lives on a dev host (Tailscale `100.108.146.47`). The user's home server (Tailscale `100.108.224.12`) serves the live app at `100.108.208.56:8082`. The user's workflow is **commit locally, `git pull` on the deployment host, rebuild there**. Don't `docker compose up` on the local dev host expecting it to update the live site — it won't. + +### Repo quirk: `.gitignore` blocks `frontend/src/lib/` + +Pre-existing bug: `.gitignore` line 17 is `lib/` (the Python ignore), and it catches `frontend/src/lib/`. New files there need `git add -f` (the `toast.tsx` rename in Sprint 3 was force-added). The `lib/` ignore should arguably be `^lib/$` or `/lib/`, but that's a separate cleanup. + +### Files added by this session + +``` +Review/handoff-ui-audit.md # Focused UI-audit handoff +Review/sprint2-verification.md # Deploy + smoke-check for Sprint 2 +Review/sprint3-verification.md # Deploy + smoke-check for Sprint 3 +Review/ui-nielsen-audit.md # (rewritten) Audit with status blocks per sprint +fix-ui-audit.md # The plan, with per-task implementation notes +frontend/src/pages/NotFound.tsx # 404 catch-all (B4) +backend/alembic/versions/0015_normalize_pantry_aisles.py # Sprint 2 migration +backend/scripts/dry_run_aisle_migration.sql # Read-only preview +backend/scripts/persist_aisle_backup.sql # Persistent backup +``` + +### Files modified by this session + +``` +frontend/src/App.tsx # Routes, nav, aria +frontend/src/api/index.ts # (pre-existing WIP, not mine) +frontend/src/components/ui/Badge.tsx # icon + aria-label props +frontend/src/components/ui/EmptyState.tsx # optional to prop +frontend/src/lib/toast.ts → toast.tsx # renamed for JSX; showToast.undo() +frontend/src/lib/utils.ts # cleanDescription() (B7) +frontend/src/pages/Dashboard.tsx # B5, B6, B12 +frontend/src/pages/MealDetail.tsx # B2, B3, B7 +frontend/src/pages/Pantry.tsx # B8, B10, B12 +frontend/src/pages/RecipeDetail.tsx # B1 +frontend/src/pages/Recipes.tsx # B11 +frontend/src/pages/ShoppingList.tsx # B9, S3.3 +frontend/src/types/index.ts # PANTRY_AISLES, RecipeIngredient extensions +``` ---