• Townie
    AI
  • Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
connnolly

connnolly

cardamom

Unlisted
Like
2
cardamom
Home
Code
13
.claude
1
.cursor
1
backend
4
frontend
3
shared
2
.vtignore
CLAUDE.md
README.md
claude-fixes.md
deno.json
meal-planning-implementation-plan.md
test-normalization-cache.ts
todo.md
Branches
2
Pull requests
Remixes
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
meal-planning-implementation-plan.md
Code
/
meal-planning-implementation-plan.md
Search
9/13/2025
Viewing readonly version of ft-calendar branch: v71
View latest version
meal-planning-implementation-plan.md

Meal Planning Implementation - Status Report

🎯 Overview

IMPLEMENTED: Dual-view meal planning system with scrollable daily list (default) and monthly calendar view. Users can plan meals by assigning recipes to specific days and meal types, then generate shopping lists from selected days.

✅ COMPLETED FEATURES

1. ✅ Database Schema & Migration

  • meal_plans_v2 table created with:
    • id (INTEGER PRIMARY KEY)
    • recipe_id (INTEGER FK to recipes_v1)
    • date (DATE)
    • meal_type (TEXT: 'breakfast-lunch', 'dinner')
    • notes (TEXT)
    • created_at (DATETIME)
    • updated_at (DATETIME)
    • UPDATED: Simplified to 2 meal types, allows multiple recipes per meal type
  • Smart Data Migration: Automatically migrates from v1 to v2, combines breakfast/lunch, skips snacks
  • Proper Constraints: Database-level validation for meal types

2. ✅ Backend API Implementation

Complete REST API in /backend/routes/meal-plans.ts:

  • ✅ GET /api/meal-plans - Get meal plans for date range
    • Query params: startDate, endDate
    • Returns meal plans with LEFT JOIN for deleted recipe handling
    • Efficient date range filtering
  • ✅ POST /api/meal-plans - Create meal plan
    • Validates recipe exists before creation
    • Input validation for meal types and date formats
    • Transaction-safe atomic operations
  • ✅ DELETE /api/meal-plans/:id - Remove meal plan
  • ✅ PUT /api/meal-plans/:id - Update meal plan
    • Change date/meal type with validation
  • ✅ POST /api/meal-plans/shopping-list - Generate shopping list from calendar
    • Supports date ranges or specific date arrays
    • Filters out deleted recipes automatically
    • Reuses existing shopping list creation logic

3. ✅ Frontend Components Implementation

✅ New Components Created:

  • MealPlanCalendar.tsx - Dual-view meal planning interface

    • ✅ Default List View: Scrollable daily cards showing planned meals
    • ✅ Calendar View: Full monthly grid with day selection
    • ✅ View Switcher: Toggle between "📝 List" and "📅 Calendar"
    • ✅ Shopping List Integration: Multi-day selection for list creation
    • ✅ Mobile-responsive: Adaptive layouts for both views
  • DayMealPlan.tsx - Detailed day meal editor

    • ✅ Modal Interface: Full-screen day planning modal
    • ✅ Meal Type Sections: "Breakfast & Lunch" and "Dinner"
    • ✅ Multiple Recipes: Support for multiple recipes per meal type
    • ✅ Recipe Management: Add/remove individual recipes
    • ✅ Deleted Recipe Handling: Warning display for deleted recipes
    • ✅ Ingredient Count: Total ingredients calculation
  • MealPlanSidebar.tsx - Recipe selection interface

    • ✅ Smart Filtering: Search, tags, difficulty, prep time filters
    • ✅ Recipe Metadata: Prep time, difficulty, tags display
    • ✅ Simple Success Feedback: Auto-close on successful add
    • ✅ Error Handling: Clear error messages and validation
    • ✅ Mobile Overlay: Full-screen sidebar on mobile

✅ Modified Components:

  • App.tsx - Added 'meal-calendar' view and navigation button
  • Type System - Updated shared/types.ts with meal planning interfaces

4. ✅ User Interface Implementation

✅ List View (Default):

  • Daily Cards: Clean cards for each day with meal plans
  • Color Coding: Orange for "Breakfast & Lunch", Purple for "Dinner"
  • Today Highlighting: Blue accent for current day
  • Recipe Details: Prep time, difficulty badges, deleted recipe warnings
  • Empty States: Engaging empty state with call-to-action

✅ Calendar View:

┌─────────────────────────────────────────────────┐
│  📝 List | 📅 Calendar     [Create List]        │
├─────────────────────────────────────────────────┤
│ Sun │ Mon │ Tue │ Wed │ Thu │ Fri │ Sat │       │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤       │
│  1  │  2  │  3  │  4  │  5  │  6  │  7  │       │
│B&L:2│B&L:-│B&L:1│B&L:3│B&L:-│B&L:-│B&L:1│       │
│ D:3 │ D:1 │ D:2 │ D:- │ D:2 │ D:1 │ D:2 │       │
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤       │
│  8  │  9  │ ... │                         │       │
└─────┴─────┴─────┴─────────────────────────┘

Legend: B&L=Breakfast & Lunch, D=Dinner

✅ Mobile Responsiveness:

  • Responsive Grids: CSS Grid adapts to screen size
  • Touch-Friendly: 44px minimum touch targets
  • Modal Interfaces: Full-screen modals for editing
  • Stackable Views: List view naturally stacks on mobile

🎯 IMPLEMENTATION PHASES

✅ Phase 1: Database & Backend (COMPLETED)

  1. ✅ Database Migration: Created meal_plans_v2 with smart v1→v2 migration
  2. ✅ Database Queries: All CRUD operations with transaction safety
  3. ✅ API Routes: Complete REST API with validation and error handling
  4. ✅ Backend Integration: Added to main app routes

✅ Phase 2: Calendar Components (COMPLETED)

  1. ✅ MealPlanCalendar: Dual-view interface with list/calendar toggle
  2. ✅ Day Navigation: Month navigation and day selection
  3. ✅ Meal Display: Recipe counts and meal type indicators
  4. ✅ Responsive Design: Mobile-first CSS Grid layouts

✅ Phase 3: Recipe Assignment (COMPLETED)

  1. ✅ MealPlanSidebar: Advanced recipe selection with filtering
  2. ✅ Success Feedback: Auto-close sidebar on successful add
  3. ✅ DayMealPlan: Detailed day editing with meal type sections
  4. ✅ Multiple Recipes: Full support for multiple recipes per meal type

✅ Phase 4: Shopping List Integration (COMPLETED)

  1. ✅ Selection Mode: Multi-day selection in both list and calendar views
  2. ✅ Shopping List Generation: Direct integration with existing system
  3. ✅ Transaction Safety: Atomic operations with deleted recipe filtering
  4. ✅ User Experience: Seamless flow from planning to shopping

✅ Phase 5: Mobile & Polish (COMPLETED)

  1. ✅ Mobile Optimization: Touch-friendly interactions and responsive design
  2. ✅ User Feedback: Simplified success indication and error handling
  3. ✅ Data Integrity: Comprehensive deleted recipe handling
  4. ✅ Performance: Efficient data loading for both view types

🚀 WHAT'S NEXT (Future Enhancements)

The core meal planning system is COMPLETE and fully functional. Potential future enhancements:

Types to Add (shared/types.ts)

export interface MealPlan { id?: number; recipeId: number; recipe?: Recipe | null; // Populated on fetch, null if recipe was deleted date: string; // YYYY-MM-DD mealType: 'breakfast' | 'lunch' | 'dinner' | 'snack'; notes?: string; createdAt?: string; updatedAt?: string; } export interface CalendarDay { date: string; meals: { breakfast: MealPlan[]; // Array to support multiple recipes lunch: MealPlan[]; dinner: MealPlan[]; snack: MealPlan[]; }; isSelected?: boolean; totalRecipeCount: number; } export interface MealPlanDateRange { startDate: string; endDate: string; }

Navigation Flow

  1. Main nav: Add "Meal Calendar" option
  2. From Calendar: "Create Shopping List" → Select days → Generate list
  3. From Shopping List Creator: Tab for "From Calendar" vs "From Recipes"
  4. Quick actions: "Plan this recipe" button on recipe view

Mobile-First Considerations

  • Touch targets: Minimum 44x44px for all interactive elements
  • Swipe navigation: Between months and weeks
  • Responsive grid: Days stack on small screens
  • Progressive disclosure: Expand/collapse meal details
  • Offline support: Cache meal plans locally
  • Performance: Lazy load recipes, virtualize long lists

Transaction Safety & Data Integrity

Transaction Patterns

All multi-table operations will use Val Town's sqlite.batch() method:

// Example: Creating meal plan with validation const queries = [ // Verify recipe exists { sql: 'SELECT id FROM recipes_v1 WHERE id = ?', args: [recipeId] }, // Insert meal plan if recipe exists { sql: 'INSERT INTO meal_plans_v1 (recipe_id, date, meal_type) VALUES (?, ?, ?)', args: [recipeId, date, mealType] } ]; const results = await sqlite.batch(queries); if (!results[0].rows.length) { throw new Error('Recipe not found'); }

Handling Deleted Recipes

  • Meal Plan Queries: Use LEFT JOIN to include orphaned meal plans:
    SELECT mp.*, r.* FROM meal_plans_v1 mp LEFT JOIN recipes_v1 r ON mp.recipe_id = r.id WHERE mp.date BETWEEN ? AND ?
  • Frontend Display: Show placeholder for deleted recipes with option to remove
  • Shopping List Generation: Filter out null recipes before ingredient aggregation
  • Cascade Behavior: Keep meal plans when recipes are deleted (no CASCADE DELETE)

Benefits

  • Visual meal planning interface
  • Support for meal prep (multiple recipes per meal)
  • Efficient shopping for multiple days
  • Flexibility for varying meal sizes/occasions
  • Mobile-friendly for grocery shopping
  • Data integrity maintained even when recipes are deleted
  • Atomic operations ensure consistent state
FeaturesVersion controlCode intelligenceCLI
Use cases
TeamsAI agentsSlackGTM
ExploreDocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.