grocery-bot

Log | Files | Refs | README

CLAUDE.md (3382B)


      1 # CLAUDE.md — Recipe & Grocery Telegram Bot
      2 
      3 ## Project Purpose
      4 
      5 A self-hosted Telegram bot for tracking recipes, managing a weekly staples
      6 list, and generating grocery lists. Runs as a long-polling service in an
      7 LXC/VM on Proxmox, alongside the rest of the homelab stack.
      8 
      9 ## Dietary Constraints
     10 
     11 - **Ketogenic**: recipes/ingredients should be tagged `keto` automatically
     12   based on carb content where determinable, but always allow manual override.
     13 
     14 Nut-free tracking was considered and deliberately dropped (2026-07-02):
     15 single-user household, user doesn't eat nuts, so nut-containing recipes are
     16 very unlikely to enter the system in the first place. Not worth the schema/
     17 logic complexity for this tool.
     18 
     19 ## Tech Stack
     20 
     21 - Python 3.11+
     22 - `python-telegram-bot` (async, v22+) — long polling, no public webhook needed.
     23   v20.x is broken on Python 3.14 (AttributeError building `Updater`,
     24   confirmed 2026-07-03) — pin to v22+ if the system Python is 3.14.
     25 - SQLite via `sqlite3` stdlib or `sqlmodel` if an ORM is wanted — keep it
     26   simple, this doesn't need SQLAlchemy's full weight
     27 - `systemd` service file for deployment (same conventions for logging and
     28   restarts as the rest of the homelab stack)
     29 
     30 ## Data Model
     31 
     32 - `recipes(id, name, servings, instructions, source, is_keto)`
     33 - `ingredients(id, recipe_id, name, quantity, unit, category)`
     34 - `staples(id, name, default_quantity, unit, category)`
     35 - `grocery_list_items(id, name, quantity, unit, category, source)`
     36   - `source` is one of `staple`, `recipe`, `freeform` — keep provenance so
     37     items can be intelligently merged/deduped and so `/clearlist` behavior
     38     is predictable
     39 
     40 ## Bot Commands (initial scope)
     41 
     42 - `/addrecipe` — conversational flow OR paste structured text/URL to parse
     43 - `/recipes [tag]` — list/filter recipes
     44 - `/staples` — show current staples list
     45 - `/staples add <item>` / `/staples remove <item>`
     46 - `/grocerylist [recipe1, recipe2, ...]` — staples + named recipes merged
     47   into one list, quantities summed for matching items
     48 - `/add <item>` — freeform one-off add to the current grocery list
     49 - `/clearlist` — reset the working grocery list
     50 - `/random [tag]` — random recipe suggestion, optionally filtered
     51 
     52 ## Merge Logic Rules
     53 
     54 - Same-name ingredients across recipes/staples/freeform sum their quantities
     55   when units match; if units don't match, keep as separate line items rather
     56   than guessing a conversion.
     57 - Category (produce, dairy, pantry, etc.) is used for grouping the final list
     58   output, not for merge logic.
     59 
     60 ## Code Style / Conventions
     61 
     62 - Match the conventions already used in Jake's other homelab projects:
     63   small, readable functions over cleverness; explicit error handling.
     64 - No unnecessary abstraction layers — this is a personal tool, not a
     65   library. Prefer a flat file structure (`bot.py`, `db.py`, `models.py`,
     66   `parsing.py`) over deep package nesting.
     67 - Config (Telegram bot token, DB path) via environment variables or a
     68   `.env` file — never hardcoded, never committed.
     69 
     70 ## Out of Scope (for now)
     71 
     72 - Web UI — SQLite backend should make this easy to bolt on later if wanted
     73 - Multi-user support — this is a single-household tool
     74 - Nutrition/macro calculation beyond keto tagging
     75 
     76 ## Testing
     77 
     78 - Unit tests for merge logic (the trickiest part) using `pytest`
     79 - Manual testing against a test Telegram bot token before pointing at the
     80   real one