From 682c0f76b85950ad0889e11750dc84e0f00d2807 Mon Sep 17 00:00:00 2001 From: Tom Flux Date: Tue, 23 Jun 2026 20:16:23 +0100 Subject: move to uv --- requirements.md | 260 -------------------------------------------------------- 1 file changed, 260 deletions(-) delete mode 100644 requirements.md (limited to 'requirements.md') diff --git a/requirements.md b/requirements.md deleted file mode 100644 index 6c71a97..0000000 --- a/requirements.md +++ /dev/null @@ -1,260 +0,0 @@ -# Food App — Requirements (pivot to web-first) - -> Written 2026-06-22, after reviewing `research.md` and interviewing Tom. -> This supersedes the Caine-centric design. Pairs with `research.md` (current -> state) — this doc is the *target*. - -## The pivot, in one line - -Caine (the Matrix LLM assistant) was never really used — it cost too much per -call. **The web UI becomes the primary interface.** An LLM can come back later -as an MCP server riding on the existing claude.ai subscription (no per-call -cost), but that's a later phase, not now. - -## The one constraint that wins - -**Ease of use beats everything.** This is a single-user personal app, low -stakes. When a requirement trades correctness, completeness, or robustness for -less friction, friction wins. Specifically: fewer fields, fewer taps, fewer -decisions, nothing that nags, and updating the pantry should feel like nothing. - -**Mobile-first, not mobile-also.** The pantry is used standing in the kitchen -or at the shop, on a phone — that's the primary device, and it's fiddly today. -Design for a one-handed phone screen first; desktop is the afterthought. -Concretely: big tap targets (state changes and add are thumb-sized, not -table-cell links), no tiny number inputs or cramped rows, single-column -layouts, no horizontal scroll, controls reachable in the lower half of the -screen. If something works on the phone it'll be fine on desktop; the reverse -is what's been failing. - -Everything below is judged against that. - ---- - -## Priorities (Tom, 2026-06-22 — current call) - -In value order: - -1. **Pantry: make it a bit nicer in the web UI.** Not a ground-up rebuild — - incremental polish (the In/Low/Out state + fast add from §2), enough that - keeping it accurate isn't a slog. It needs to be *reasonably* accurate - precisely because of #3. -2. **Add some auth** (§1) — login once, long session. -3. **MCP server with claude.ai — the highest-value piece.** The whole point: - stop hand-reciting "here's what's in my pantry" every time. Claude reads the - pantry directly in cooking mode. Almost certainly also the *lowest-friction - update path* — say "I used the last of the noodles" and Claude writes it - back — which is the real answer to the pantry-is-tedious problem. - -Everything else in this doc (web what-can-i-cook, shopping rethink, web -cook-logging, fixed recipes, §4.1 substitutions) is **deferred** — nice, not -now. Detailed below for when we get there. - -**The synergy that justifies the order:** #3 is *why* #1 only needs to be "a -bit nicer" rather than perfect. If Claude can both read and update the pantry -conversationally, the web UI becomes the glanceable / manual fallback, not the -primary data-entry surface. So don't over-invest in pantry UI — invest in -making the data MCP can serve trustworthy and easy to nudge. - ---- - -## 1. Auth — log in once, then forget it - -Decision: **a simple login page + a very long-lived session** (≈1 year cookie). -Log in once per device; never get prompted again on that device. - -- Standard Django session auth (`login_required`) on all `/app/` views — no - HMAC, no signed requests, no per-request secret. (The HMAC idea was heavier - than needed for one user.) -- Set `SESSION_COOKIE_AGE` long (~1 year) and `SESSION_EXPIRE_AT_BROWSER_CLOSE - = False` so the session survives restarts. -- One user account is enough. `/api/` keeps its existing token auth for the - future MCP client. -- This also lets us drop the `@csrf_exempt` hacks — a logged-in session has a - real CSRF token, so HTMX POSTs can be protected normally. - -Security is explicitly *not* the top priority, but this gives a real baseline -(no more wide-open `/app/`) at near-zero friction. - -## 2. Pantry — the redesign (this is the heart of it) - -Today the pantry is "all just frustrating": adding is slow, quantities drift -out of date the moment you cook, expiry dates are fiddly to set and chase, and -it's a separate chore that's easy to forget. The fix is to **stop tracking the -pantry like a spreadsheet and track it like a fridge you glance into.** - -### 2.1 Track presence, not precise amounts - -Replace exact decimal quantities as the primary signal with a simple state: - -> **In stock · Running low · Out** - -- One tap to change state (e.g. cycle In → Low → Out, or three buttons). -- Quantity becomes *optional metadata* (a free note like "½ bag", "3 left"), - never required, never the thing the app reasons about. -- This kills the "quantities drift after cooking" problem outright — you don't - maintain a number, you flip a flag when you notice. - -> **Open decision:** some items genuinely want a rough count (eggs, noodle -> nests). Proposal: keep the optional quantity note for those, but the matcher -> and shopping logic only ever look at the In/Low/Out state. Confirm before -> building. - -### 2.2 Fast add - -- A single search box: type → autocomplete against known ingredients (and - aliases) → tap to add. Defaults its unit/location from the `Ingredient` - record, state defaults to "In stock". Zero further fields needed. -- If the name isn't known, add it inline in the same flow (it auto-creates the - ingredient, like the API already does). -- **Quick-add chips** for staples and recently-used items — one tap, no typing. -- On mobile this is the make-or-break screen: the search box and chips sit near - the bottom (thumb reach), adding an item is one tap, and the In/Low/Out - control on each row is a proper button, not a fiddly inline link. The current - table-of-tiny-actions layout is exactly what's being replaced. - -### 2.3 Expiry stops nagging - -- Expiry dates become fully optional and de-emphasised. No required date entry. -- Instead of chasing exact dates, a lightweight **"use soon"** flag you can tap - on an item (and an optional date if you actually care for something specific). -- Keep the existing freezer rule (frozen = no expiry). Defrosting (freezer → - fridge) can set a soft "use soon" instead of computing a hard date. - -### 2.4 Updating the pantry as a by-product, not a chore - -The biggest win against "I forget to update it": make other actions update the -pantry for you, so the standalone chore mostly disappears. - -- **Logging a cook** optionally flips the ingredients it used toward Low/Out - (replaces the brittle decimal-deduction logic). -- **Checking off a shopping item** marks that ingredient back to "In stock" in - the pantry — closing the buy → restock loop automatically. - -## 3. Recipes & "what can I cook" — keep it, but make it one implementation - -Decision: **keep meta-recipes and the what-can-i-cook matcher** — it's the part -Tom actually wants. But: - -- There are currently **two separate matchers** (`views.what_can_i_cook` JSON - and `views_htmx.recipes_page` HTML) that have already drifted. Collapse to - **one shared function**; both the page and any API/MCP call use it. (This is - also the "two implementations hanging around" Tom flagged.) -- The matcher moves to **presence-based**: a required slot is satisfied if any - of its options is In (or Low) — no quantity comparison. Simpler, and matches - the new pantry model. -- Servings is currently hardcoded to 2 in the web page; with a presence-based - matcher, servings stops mattering for "can I cook this", so we can just drop - the servings input from that view. -- Fixed `Recipe`s: keep the model, but **de-scope the URL import for now** — it - never links ingredients (see `research.md` §7), so imported recipes are - half-broken. Cooking ideas live in claude.ai cooking mode anyway. Don't - invest here until the MCP phase, if ever. - -## 4. Shopping list — rethink the flow - -Tom was explicitly unhappy with the current flow. Requirements: - -- Generation stays smart (staples that are Out, "use soon" items, gaps for - required recipe slots) but should be **additive and forgiving** — generating - again shouldn't wipe manual additions or duplicate. -- Checking an item off should (a) cross it out and (b) restock it in the pantry - (see §2.4). -- Needs a clear "done shopping" action that tidies the list. -- Keep it dead simple — a phone checkbox list, grouped by aisle/section. - -### 4.1 "Can't find it at the shop" — substitutions (important to Tom) - -A recurring real pain: Tom goes to the shop to buy something and it's not -there, and then he's stuck. He wants help *in the moment* knowing what else -works. - -- **Partial fix available now, no LLM needed:** the meta-recipe slot model - *is* a substitution table — a protein slot already lists pork mince OR - chicken, etc. So a shopping-list item that came from a recipe slot can show - "alternatives that fit the same slot" inline. If you can't find pork mince, - the list shows the other proteins that recipe accepts. -- **Richer substitutions need the LLM/MCP (Phase 2):** general swaps the app - has no data for ("no fresh basil → dried is fine", "no crème fraîche → use - yoghurt") require world knowledge. That's a claude.ai-via-MCP job: it reads - the shopping item + recipe context and suggests a real-world substitute. -- So: ship slot-based alternatives in the web UI now; treat "smart, open-ended - substitution at the shop" as a headline use case for the MCP phase. - -## 5. Cook log — make it usable from the web - -- Add a **web UI way to log a cook** (currently API/admin only): pick a - meta-recipe, tap the slot choices you used, optional rating + note, save. -- `log-cook` must accept and store `rating` (the model field exists; the - endpoint ignores it today). -- Route cook-logging through model validation so the "exactly one recipe link" - rule is actually enforced (today's `log_cook` bypasses `clean()`). - -## 6. Cleanup / housekeeping (do first) - -- **Run `/simplify` first**, before feature work, to clear the obvious cruft - (duplicate matcher, dead `filterset_fields`/`search_fields` with no - django-filter installed, the freezer-first deduction bug if deduction - survives the redesign). -- Production baseline: `DEBUG = False`, real `SECRET_KEY` from env. Low - priority but cheap. - -## 7. Later — MCP (Phase 2, optional) - -Once the web UI is solid, wrap the existing API in an **MCP server** so -claude.ai "cooking mode" can read the pantry and (maybe) log cooks. This is the -integration Tom actually wanted from Caine, without the per-call cost. Explicit -non-goal for now — listed so the API stays MCP-friendly in the meantime. - -Two things this phase unlocks (and why it's worth keeping the API clean): - -- **Cooking blocks still work.** MCP only *feeds data into* the claude.ai - conversation — it gives Claude tools to read the pantry. It does not change - how claude.ai renders cooking mode. So Claude pulling ingredients from the - food app and Claude producing its nice formatted cooking blocks are - independent: you get the blocks *and* they're grounded in your actual pantry. -- **Smart shop-floor substitutions** (see §4.1) — the open-ended "this isn't on - the shelf, what else works?" question is the main thing MCP buys over the - built-in slot alternatives. - ---- - -## Build order (current) - -1. `/simplify` pass (running) — behavior-preserving cleanup of the existing - code so the next steps build on something tidy. -2. **Pantry polish** — In/Low/Out state + fast add in the web UI (§2). Scoped - to "a bit nicer", not the full redesign. -3. **Auth** — login page + ~1-year session, drop `@csrf_exempt` (§1). Fold the - cheap production baseline (DEBUG off, real SECRET_KEY) in here since we're - touching settings anyway. -4. **MCP server** — the goal. Expose pantry **read and update** to claude.ai - cooking mode, so Claude can both see what's in stock and write changes back. - Reuses the existing `/api/` + token auth. - -Deferred until after the above (still wanted, just not now): web -what-can-i-cook, §4.1 slot-based substitutions, shopping flow rethink, web -cook-logging. - -## Open decisions to confirm before building - -- **Quantity**: drop exact decimals entirely in favour of In/Low/Out + an - optional free-text note? (§2.1) — recommended yes. -- **Fixed recipes**: park the URL-import feature rather than fix it? (§3) — - recommended yes. -- Anything here that's actually *more* friction than today — call it out. - ---- - -## Original notes (Tom, preserved) - -+ interface: never really ended up using caine due to cost issues. was a nice idea though. -+ if we went down the route of llms again, maybe a mcp. could claude.ai connect with it -+ current food flow is using claude.ai and its "cooking mode", issue is that it doesnt integrate with my pantry -+ pantry was tedious to update, not sure the best approach here. might just have to tough it out -+ webui interface was generally clunky -+ security not the highest prio but would be good to have some basic auth -+ lets run the /simplify skill firstly -+ tagging recipes never really worked, feels like theres two implementations of it hanging around -+ auth just scares me, i want the least friction way of doing this. a hmac secret or something might be nice for fe <> be and a simple log in page would be good. although i really dont want to have to log in every time -+ pantry: it's all just frustrating at the moment (adding slow, quantities drift, expiry fiddly, easy to forget) -- cgit v1.2.3