summaryrefslogtreecommitdiff
path: root/requirements.md
diff options
context:
space:
mode:
Diffstat (limited to 'requirements.md')
-rw-r--r--requirements.md260
1 files changed, 0 insertions, 260 deletions
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)