106 lines
3.5 KiB
Markdown
106 lines
3.5 KiB
Markdown
# Food — Meal Planning System
|
|
|
|
A custom Django app for pantry tracking, meta-recipes, and meal planning. Built for Tom, operated primarily through Caine (OpenClaw AI assistant) via Matrix chat, with Django admin as the web UI.
|
|
|
|
## Architecture
|
|
|
|
- **Django 5.2** (latest LTS) with SQLite backend
|
|
- **Django REST Framework** for API (Phase 2)
|
|
- **HTMX** frontend planned (Phase 4)
|
|
- **App name:** `kitchen`
|
|
|
|
### Core Concept: Meta-Recipes
|
|
|
|
Instead of rigid recipes, the system uses **templates with swappable slots**:
|
|
|
|
```
|
|
"Stir Fry" = protein (chicken OR pork) + carb (noodles OR rice) + veg (any combo) + sauce
|
|
```
|
|
|
|
This matches how Tom actually cooks — same method, different ingredients depending on what's in the pantry.
|
|
|
|
## Models
|
|
|
|
| Model | Purpose |
|
|
|-------|---------|
|
|
| `Tag` | Flexible ingredient tags (protein, carb, veg, etc.) |
|
|
| `Ingredient` | Master ingredient list with aliases and shelf life |
|
|
| `PantryItem` | Current kitchen inventory with location and expiry |
|
|
| `MetaRecipe` | Cooking template with swappable slots |
|
|
| `Slot` | A category in a meta-recipe (protein, carb, veg) |
|
|
| `SlotOption` | An ingredient that can fill a slot, with qty/serving |
|
|
| `MetaRecipeBase` | Always-needed ingredients (onion, garlic, oil) |
|
|
| `Recipe` | Traditional fixed-ingredient recipe |
|
|
| `RecipeIngredient` | Ingredient in a fixed recipe |
|
|
| `CookLog` | What was cooked and when |
|
|
| `ShoppingListItem` | Shopping list with reasons and checkboxes |
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
cd /var/lib/food
|
|
source venv/bin/activate
|
|
|
|
# Run migrations
|
|
python manage.py migrate
|
|
|
|
# Seed initial data (ingredients, pantry, meta-recipes)
|
|
python manage.py seed
|
|
|
|
# Create superuser (if not already done)
|
|
python manage.py createsuperuser
|
|
|
|
# Run dev server
|
|
python manage.py runserver 0.0.0.0:8042
|
|
```
|
|
|
|
Admin UI at: `http://localhost:8042/admin/`
|
|
|
|
## Credentials
|
|
|
|
- **Admin user:** `tom`
|
|
- **Admin password:** `Kitch3n!2026`
|
|
|
|
## File Structure
|
|
|
|
```
|
|
/var/lib/food/
|
|
├── food_project/ # Django project config
|
|
│ ├── settings.py
|
|
│ ├── urls.py
|
|
│ └── wsgi.py
|
|
├── kitchen/ # Main app
|
|
│ ├── models.py # All models
|
|
│ ├── admin.py # Admin config with inlines
|
|
│ ├── management/
|
|
│ │ └── commands/
|
|
│ │ └── seed.py # Initial data seeder
|
|
│ └── migrations/
|
|
├── venv/ # Python virtual environment (gitignored)
|
|
├── db.sqlite3 # SQLite database (gitignored)
|
|
├── manage.py
|
|
└── README.md
|
|
```
|
|
|
|
## Pantry Business Rules
|
|
|
|
- **Freezer items** → no expiry date (frozen = indefinite)
|
|
- **Fridge items** → expiry date set from ingredient's `shelf_life_days` if available
|
|
- **Staples** (onions, frozen chips, salt, etc.) → auto-flag for restocking when quantity = 0
|
|
- **Onions** are a permanent staple — always restock
|
|
- **Chicken skin** → remove before cooking (noted in slot option notes)
|
|
- **Tom prefers pork to chicken** — pork mince over loins
|
|
|
|
## Implementation Phases
|
|
|
|
- [x] **Phase 1:** Django project + models + admin + seed data
|
|
- [ ] **Phase 2:** DRF API + Caine integration + "what can I cook?" logic
|
|
- [ ] **Phase 3:** Recipe import (URL scraping + cookbook extraction)
|
|
- [ ] **Phase 4:** HTMX frontend (pantry view, recipe browser, shopping list)
|
|
- [ ] **Phase 5:** Systemd service + nginx reverse proxy + production hardening
|
|
|
|
## Design Doc
|
|
|
|
Full design document with meta-recipe concept, model rationale, and implementation plan:
|
|
`Obsidian Vault/Tom Net/Meal Planning System.md`
|