Public Access
248 lines
7.7 KiB
Markdown
248 lines
7.7 KiB
Markdown
# 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**: Phase 1 complete. Phase 2 (Database & Models) next.
|
|
|
|
Infrastructure skeleton is committed:
|
|
- docker-compose.yml with 4 services (backend, frontend, db, nginx)
|
|
- FastAPI backend with placeholder API routes
|
|
- React frontend with Vite + Tailwind + placeholder pages
|
|
- nginx reverse proxy config
|
|
- SQLAlchemy models created (not yet connected to real endpoints)
|
|
|
|
---
|
|
|
|
## 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) | **Complete** |
|
|
| 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: Phase 2 - Database & Models
|
|
|
|
1. Set up Alembic for migrations
|
|
2. Create actual database tables from SQLAlchemy models
|
|
3. Add seed data (basic ingredients, sample recipes)
|
|
4. Create Pydantic schemas for API validation
|
|
5. Implement real API endpoints (not just placeholders)
|
|
|
|
### After Phase 2 Complete
|
|
|
|
- Verify migrations: `docker-compose exec backend alembic upgrade head`
|
|
- Test database connectivity: `curl localhost:8000/health/db`
|
|
- Test API endpoints with real data
|
|
|
|
### Current Git State
|
|
|
|
```bash
|
|
git log --oneline
|
|
1328ec3 feat: add Phase 1 infrastructure skeleton
|
|
0c5b0aa docs: add complete project documentation
|
|
```
|
|
|
|
Phase 1 skeleton complete and committed. Phase 2 (Database) is next.
|
|
|
|
---
|
|
|
|
## 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 (Phase 1 complete, Phase 2 next)
|