Public Access
All §1 consensus blockers and §2 high-risk gaps resolved: Schema fixes: - Remove RecipeIngredient join table, use JSONB for ingredients - Add family_member table for per-voter approval tracking - Add all ENUMs for status fields (no loose VARCHAR) - Add CHECK constraints (household_size, rating 1-5, day_of_week) - Add name_lower for case-insensitive ingredient matching - Add grocery_item → ingredient FK - Fix day_of_week to ISO-8601 (1=Monday, 7=Sunday) - Remove calorie_target (nutrition is non-goal) Approval flow redesign: - Email link → confirmation page (GET), not auto-approve - Actual vote is POST from confirmation page - Per-voter tokens (single-use, 72h TTL) - Record which member voted Auth model: - VPN-only for admin endpoints - Session-based for family web UI Docker hardening: - Remove direct port exposure for backend/frontend - nginx is sole entrypoint - Add docker-compose.dev.yml for local dev Skeleton fixes: - Add missing Pantry.tsx page - Add missing index.html (Vite entrypoint) - Add package-lock.json - Fix SQLAlchemy 2 text() for raw SQL - Remove create_all from startup (use migrations) - Configure Alembic properly Docs updates: - Update Lucky URL to luckysupermarkets.com - Add WCAG 2.1 AA accessibility target - Update family profile with correct mushroom preferences - Add external dependencies list to SPEC Verification: - docker compose config: PASS - docker compose build backend: PASS - docker compose build frontend: PASS - backend import: PASS - alembic context: PASS
6.5 KiB
6.5 KiB
Running the Meal Planner
Prerequisites
- Docker and Docker Compose
- Git
- SendGrid account (for email)
- Lucky California store access (for scraping)
Environment Setup
1. Clone Repository
git clone <repository-url>
cd MealPlanner
2. Create Environment File
cp .env.example .env
Edit .env with your values:
# Database
POSTGRES_PASSWORD=your_secure_password
# SendGrid
SENDGRID_API_KEY=SG.your_sendgrid_api_key
# Family Emails
FAMILY_EMAIL_1=you@example.com
FAMILY_EMAIL_2=spouse@example.com
# Lucky California (for scraping)
LUCKY_CA_URL=https://luckysupermarkets.com
# AI Images (optional)
AI_IMAGE_ENABLED=false
AI_IMAGE_PROVIDER=openai
AI_IMAGE_API_KEY=sk-your-key
3. Create SSL Certificates (for remote access)
mkdir -p nginx/ssl
# Option 1: Let's Encrypt with Certbot
certbot certonly --nginx -d your-domain.com
# Option 2: Self-signed for local testing
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout nginx/ssl/key.pem -out nginx/ssl/cert.pem
Starting Services
Local Development
# Start all services
docker-compose up -d
# View logs
docker-compose logs -f backend
docker-compose logs -f frontend
# Stop all services
docker-compose down
Production Deployment
# Start with production settings
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Check service status
docker-compose ps
# View resource usage
docker stats
Accessing the Application
Local Access
- Web UI: http://localhost:3000
- API: http://localhost:8000
- API Docs: http://localhost:8000/docs
Remote Access (with reverse proxy)
Configure your domain and SSL in nginx/nginx.conf, then access via:
- Web UI: https://your-domain.com
- API: https://your-domain.com/api
Database Management
Initial Migration
# Run migrations
docker-compose exec backend alembic upgrade head
# Check current migration
docker-compose exec backend alembic current
# Create new migration after model changes
docker-compose exec backend alembic revision --autogenerate -m "Description"
Backup Database
# Backup to file
docker-compose exec db pg_dump -U mealplanner mealplanner > backup_$(date +%Y%m%d).sql
# Restore from backup
cat backup_20240101.sql | docker-compose exec -T db psql -U mealplanner mealplanner
Reset Database
# Danger: Drops and recreates all data
docker-compose down -v
docker-compose up -d
docker-compose exec backend alembic upgrade head
Scraping
Manual Scrape Trigger
# Scrape Lucky California weekly ad
curl -X POST http://localhost:8000/api/admin/scrape \
-H "Content-Type: application/json" \
-d '{"source": "lucky_california", "type": "weekly_ad"}'
Check Scrape Logs
# View recent scrape operations
curl http://localhost:8000/api/admin/logs?limit=10
Scheduling
Scrape runs automatically:
- Weekly: Sunday at 8 PM (before meal planning)
- Daily: 6 AM (price updates)
Email Testing
Test Email Send
# Send test email
curl -X POST http://localhost:8000/api/admin/test-email \
-H "Content-Type: application/json" \
-d '{"to": "test@example.com", "template": "meal_proposal"}'
View Email Logs
curl http://localhost:8000/api/admin/email-logs
Troubleshooting
Backend Won't Start
# Check logs
docker-compose logs backend
# Common issues:
# - Database not ready: wait for db to be healthy
# - Port conflict: check if port 8000 is in use
# - Missing env vars: verify .env file exists and is valid
Frontend Build Fails
# Check for Node version issues
node --version # Should be 18+
# Clear cache and rebuild
docker-compose exec frontend npm cache clean --force
docker-compose exec frontend rm -rf node_modules package-lock.json
docker-compose exec frontend npm install
Database Connection Errors
# Verify database is running
docker-compose ps db
# Test connection from backend
docker-compose exec backend python -c "from app.database import engine; print(engine.url)"
# Check credentials
docker-compose exec backend python -c "from app.database import SessionLocal; print('OK')"
Scraping Failures
# Check Lucky California is accessible
curl -I https://luckysupermarkets.com
# Verify Playwright browser installed
docker-compose exec backend python -c "from playwright.sync_api import sync_playwright; print('OK')"
# Manual retry
docker-compose exec backend python -c "from app.scraper.lucky_ca import LuckyCaliforniaScraper; s = LuckyCaliforniaScraper(); s.scrape_weekly_ad()"
Email Not Sending
# Verify SendGrid API key
docker-compose exec backend python -c "import sendgrid; print('SendGrid imported')"
# Check SendGrid dashboard for failures
# Ensure sender email is verified in SendGrid
Development
Backend Development
# Enter backend container
docker-compose exec backend bash
# Run tests
pytest
# Run with hot reload
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
Frontend Development
# Enter frontend container
docker-compose exec frontend sh
# Run dev server with hot reload
npm run dev
Database Migrations
# Create migration
alembic revision --autogenerate -m "add_new_table"
# Upgrade
alembic upgrade head
# Downgrade
alembic downgrade -1
# Show migration history
alembic history
Health Checks
# Check backend health
curl http://localhost:8000/health
# Check database connectivity
curl http://localhost:8000/health/db
# Check all services
docker-compose ps
Logs
View All Logs
docker-compose logs -f
View Specific Service
docker-compose logs -f backend
docker-compose logs -f frontend
docker-compose logs -f db
Configure Log Level
In backend/app/config.py:
LOG_LEVEL=DEBUG # DEBUG, INFO, WARNING, ERROR
Security Notes
- Change default passwords in
.env - Use strong SSL certificates for production
- Consider VPN for remote database access
- Regularly update Docker images
- Review nginx access logs for suspicious activity
Updating
# Pull latest code
git pull
# Rebuild images
docker-compose build
# Run migrations
docker-compose exec backend alembic upgrade head
# Restart services
docker-compose up -d
Stopping Completely
docker-compose down # Stop containers
docker-compose down -v # Stop and remove volumes (DELETES DATA)
docker-compose down --rmi all # Stop and remove images