# Meal Planner - Orientation Guide This document is the **first stop** for any agent resuming work on this project after context compaction. Read it before doing anything else. --- ## Project Overview **MealPlanner** is a self-hosted meal planning system for a family of 4 (2 adults, 2 children) that integrates with Lucky California grocery store to source ingredients from weekly sales, sends meal proposals via email, generates shopping lists, and learns from feedback. ### Key Problem Being Solved The family has been using meal kit services (Blue Apron → EveryPlate → HungryRoot → Sunbasket) which suffer from: - 3x ingredient markup in cost - Repetitive meals and sauces - Forcing app login to manage meal selection - No home pantry integration ### Current Status **Phase**: Documentation complete. Implementation NOT started. All planning documents are written and committed. The next step is Phase 1: Infrastructure & Foundation (setting up Docker, PostgreSQL, FastAPI skeleton, React frontend). --- ## Key Files | File | Purpose | |------|---------| | `docs/SPEC.md` | Full project specification (goals, constraints, user stories) | | `docs/ARCHITECTURE.md` | System architecture, component descriptions, data flow | | `docs/database-schema.md` | PostgreSQL schema with all tables, indexes, relationships | | `docs/implementation-plan.md` | 12-phase implementation plan with verification commands | | `docs/RUNNING.md` | Deployment guide, troubleshooting, environment setup | | `README.md` | Project overview and quick start | | `meal-planner-plan.md` | Original planning file (may be superseded) | --- ## Architecture Summary ``` User (email) ──► SendGrid ───────────────────────────────┐ User (web) ───► React UI ──► nginx ──► FastAPI ──────────┼──► PostgreSQL │ │ └──► Lucky California scraper ──┘ ``` ### Services (Docker Compose) - **backend**: FastAPI Python app (port 8000) - **frontend**: React + Tailwind (port 3000, served via nginx) - **db**: PostgreSQL 15 (port 5432) - **nginx**: Reverse proxy with SSL (ports 80/443) ### Tech Stack - Backend: Python 3.11, FastAPI, SQLAlchemy, Alembic - Frontend: React 18, TypeScript, Tailwind CSS, React Query - Database: PostgreSQL 15 - Scraping: Playwright, BeautifulSoup - Email: SendGrid - Hosting: Docker Compose, nginx --- ## Family Profile - **Household**: 2 adults, 2 children - **Dietary**: One adult + one child like mushrooms; other adult + one child do NOT - **Goals**: Calorie, budget, and health conscious; tasty but not expensive - **No allergies** ### Approval Workflow 1. System generates 7-day meal plan (Sunday) 2. Email sent to both adults with meals, images, Approve/Deny links 3. One denial → meal swapped with alternative 4. No denials (or silence) → meal auto-approved 5. After all approvals → shopping list generated --- ## Database Schema Highlights ### Core Tables - `family_profile` - Household configuration - `recipe` - All recipes with ingredients (JSONB), instructions, image URLs - `ingredient` - Master ingredient list with aisle, price, season - `meal_plan` - Weekly plan (7 days) - `meal_plan_item` - Individual meal with approval_token, status - `home_pantry` - Family's on-hand ingredients - `feedback` - Ratings, denial reasons, never-suggest flags - `grocery_item` - Scraped Lucky California items with sale prices - `scrape_log` / `email_log` - Operation history ### Key Relationships - `family_profile` 1:N `meal_plan` - `family_profile` 1:N `home_pantry` - `recipe` N:N `ingredient` (via `recipe_ingredient` junction table) - `meal_plan` 1:N `meal_plan_item` - `meal_plan_item` 1:1 `feedback` --- ## Implementation Phases | Phase | Description | Status | |-------|-------------|--------| | 1 | Infrastructure (Docker, PostgreSQL, FastAPI, React, nginx) | **Not Started** | | 2 | Database & Models (SQLAlchemy models, Alembic migrations) | Not Started | | 3 | API Endpoints (CRUD, meal plans, shopping list, feedback) | Not Started | | 4 | Lucky California Scraper (weekly ad, Playwright) | Not Started | | 5 | Recipe Engine (CRUD, tagging, search) | Not Started | | 6 | Meal Planner Engine (generation algorithm, substitutions) | Not Started | | 7 | SendGrid Email Integration | Not Started | | 8 | Web UI - Core (Dashboard, Meal Detail, Approval, Pantry) | Not Started | | 9 | Web UI - Feedback (Feedback Portal, Learning) | Not Started | | 10 | Shopping List & Print | Not Started | | 11 | Image Strategy (scraped + AI fallback) | Not Started | | 12 | Polish & Future (variety analysis, budget tracking) | Not Started | --- ## Environment Variables Required ```bash # Database DATABASE_URL=postgresql://mealplanner:password@db:5432/mealplanner POSTGRES_PASSWORD=secure_password # SendGrid SENDGRID_API_KEY=SG.xxx # Family FAMILY_EMAIL_1=user@example.com FAMILY_EMAIL_2=spouse@example.com # Scraping LUCKY_CA_URL=https://www.luckyncal.com # AI Images (optional) AI_IMAGE_ENABLED=false ``` --- ## Next Steps ### IMMEDIATE: Start Phase 1 1. Create `docker-compose.yml` with all 4 services 2. Create backend directory structure and FastAPI skeleton 3. Create frontend with Vite + React + TypeScript + Tailwind 4. Set up nginx reverse proxy config 5. Create `.env.example` file ### After Phase 1 Complete - Verify all services start: `docker-compose up -d && docker-compose ps` - Test health endpoint: `curl localhost:8000/health` - Test frontend builds: `cd frontend && npm run build` ### Current Git State ```bash git log --oneline # (empty - no commits yet) ``` All documentation is written but NOT YET COMMITTED. Commit with: ```bash git add docs/ README.md meal-planner-plan.md git commit -m "docs: add complete project documentation - SPEC.md: project specification and goals - ARCHITECTURE.md: system design and component descriptions - database-schema.md: PostgreSQL schema with all tables - implementation-plan.md: 12-phase implementation guide - RUNNING.md: deployment and troubleshooting guide - README.md: project overview Family profile: 2 adults, 2 children. Mushroom avoidance for 3/4. Approval workflow: email proposals, one denial swaps meal. Tech stack: FastAPI, PostgreSQL, React, Playwright, SendGrid." ``` --- ## Important Conventions ### Code Style - Python: Black formatter, isort for imports - TypeScript: Prettier, ESLint - No comments unless explaining non-obvious logic ### Git Commits - Conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`, `test:` - One logical change per commit where possible ### API Design - RESTful endpoints with proper HTTP methods and status codes - Pydantic schemas for request/response validation - JWT-free for MVP (simple token-based auth for email approval links) ### Database - Always use UUIDs for primary keys - Timestamps with timezone (TIMESTAMPTZ) - Soft deletes preferred over hard deletes where applicable ### Testing - Write unit tests for services (pytest) - Integration tests for API endpoints - Frontend: component tests with React Testing Library --- ## Common Tasks ### Run full stack ```bash docker-compose up -d ``` ### Create database migration ```bash docker-compose exec backend alembic revision --autogenerate -m "description" ``` ### Trigger scrape manually ```bash curl -X POST http://localhost:8000/api/admin/scrape \ -H "Content-Type: application/json" \ -d '{"source": "lucky_california", "type": "weekly_ad"}' ``` ### View all logs ```bash docker-compose logs -f ``` --- ## Known Issues / Open Questions 1. **Lucky California scraping**: May need adjustment if website structure changes. Has fallback to manual input. 2. **AI image generation**: Config flag to enable/disable. Disabled by default. 3. **WhatsApp integration**: Planned for future via Twilio. Out of scope for MVP. --- ## Contact / Context - **Primary user**: Peter (tech-savvy, hosts the system) - **Wife**: Non-technical, will use web UI and email - **Children**: 2, eating habits vary (one OK with mushrooms) Last updated: 2026-05-04 (after documentation completion)