104 lines
5.2 KiB
Markdown
104 lines
5.2 KiB
Markdown
# Phase 8 — Meal Planning & Waste Reduction
|
|
|
|
**Goal**: Enable weekly meal planning with automatic nutrition tracking vs targets. The core feature is a **suggestion engine** that recommends recipes prioritizing ingredients already in the pantry (especially those expiring soon), reducing food waste while maintaining nutritional balance.
|
|
|
|
**Depends on**: Phase 5 (products), Phase 6 (recipes), Phase 7 (pantry)
|
|
|
|
---
|
|
|
|
## Implementation Workflow (Vertical Slice)
|
|
|
|
Following the project's standard workflow, Phase 8 will be implemented in the following order:
|
|
|
|
### 8.1 — Shared Layer: Types & Validation
|
|
- **Types**: Define `MealPlan` and `NutritionTarget` in `packages/shared/src/types/`.
|
|
- **Enums**: Define `MealType` and `MealPlanStatus` in `packages/shared/src/enums/`.
|
|
- **Validation**: Create Zod schemas in `packages/shared/src/validation/`:
|
|
- `CreateMealPlanSchema`: Ensures 7 days, valid `weekStartDate`.
|
|
- `UpdateMealPlanSchema`: Supports granular updates (add/move/remove meal).
|
|
- `NutritionTargetSchema`: Validates daily macros and calorie goals.
|
|
- **Unit Tests**: Test Zod schemas for all edge cases (e.g., negative calories, overlapping weeks).
|
|
|
|
### 8.2 — Database Layer: Repositories
|
|
- **MealPlanRepository**:
|
|
- `findByHousehold(householdId, weekStartDate)`: Unique constraint per household per week.
|
|
- `findCurrent(householdId)`: Returns the plan for the current calendar week.
|
|
- `updateMeal(id, dayIndex, mealId, data)`: Granular update for a specific meal slot.
|
|
- **NutritionTargetRepository**:
|
|
- `findByUser(userId, householdId)`: Get active targets for a specific user.
|
|
- `upsert(userId, householdId, data)`: Update or create targets.
|
|
- **Integration Tests**: Verify MongoDB unique indexes and household scoping.
|
|
|
|
### 8.3 — Service Layer: Suggestion Engine & Planning
|
|
- **MealPlanService**:
|
|
- Manage CRUD operations and status transitions (Draft -> Active).
|
|
- Compute `dailyNutritionTotal` dynamically using the `NutritionCalculatorService` from Phase 6.
|
|
- **NutritionTargetService**:
|
|
- Manage user-specific nutritional goals and presets (Maintenance, Loss, Gain).
|
|
- **SuggestionEngineService** (Core Algorithm):
|
|
- **Scoring Algorithm**:
|
|
- `IngredientCoverage` (40%): Matches recipe ingredients vs current pantry items.
|
|
- `FreshnessUrgency` (30%): Bonus for using items with `urgency: urgent` or `expiringSoon`.
|
|
- `NutritionBalance` (20%): Complements existing meals in the day vs user targets.
|
|
- `Variety` (10%): Penalizes recipes used in the last 14 days.
|
|
- Uses `RecipesService` to fetch catalog and `PantryService` to fetch current inventory.
|
|
- **ShoppingGapService**:
|
|
- Analyze meal plans vs pantry to identify missing ingredients for Phase 9 integration.
|
|
- **Unit Tests**: Test scoring weights and ingredient matching logic (100% coverage required).
|
|
|
|
### 8.4 — Route Layer: API Endpoints
|
|
- **MealPlanRoutes**:
|
|
- `GET /api/v1/households/:householdId/meal-plans`: List plans.
|
|
- `GET /api/v1/households/:householdId/meal-plans/current`: Get current week.
|
|
- `POST /api/v1/households/:householdId/meal-plans`: Create plan.
|
|
- `PATCH /api/v1/households/:householdId/meal-plans/:id`: Update structure.
|
|
- `GET /api/v1/households/:householdId/meal-plans/suggestions`: Get algorithmic suggestions.
|
|
- **NutritionTargetRoutes**:
|
|
- `GET /api/v1/households/:householdId/nutrition-targets`: Get user targets.
|
|
- `POST /api/v1/households/:householdId/nutrition-targets`: Set targets.
|
|
- **Integration Tests**: Verify all endpoints return correctly shaped responses (using `toProductResponse` style mappers).
|
|
|
|
### 8.5 — Web Layer: API Client & Components
|
|
- **API Client**: Implement `meal-plans.ts` and `nutrition-targets.ts` in `packages/web/src/services/`.
|
|
- **Hooks**: Create `useMealPlan` and `useSuggestions` hooks for state management.
|
|
- **Components**:
|
|
- `CalendarGrid`: Weekly view using CSS Grid and drag-and-drop.
|
|
- `NutritionProgress`: Daily progress bars vs targets.
|
|
- `SuggestionPanel`: Sidebar showing ranked recipes with "reasoning" tooltips.
|
|
- `ShoppingGapView`: Breakdown of missing items.
|
|
- **Component Tests**: Use React Testing Library to verify drag-and-drop and progress bar calculations.
|
|
|
|
### 8.6 — Verification Gate
|
|
- `npm run build`
|
|
- `npm run test:cov` (100% API/Shared, 90% Web thresholds)
|
|
- `npm run lint`
|
|
|
|
---
|
|
|
|
## Technical Details
|
|
|
|
### Scoring Algorithm Constants
|
|
```typescript
|
|
const WEIGHTS = {
|
|
COVERAGE: 0.4, // Do I have the items?
|
|
URGENCY: 0.3, // Should I use these items now?
|
|
NUTRITION: 0.2, // Does it fit my macros?
|
|
VARIETY: 0.1 // Have I eaten this too much?
|
|
};
|
|
```
|
|
|
|
### Integration Points
|
|
- **PantryService**: Fetch items where `status` is `sealed` or `opened`.
|
|
- **RecipesService**: Fetch recipes and their computed nutrition/ingredients.
|
|
- **NutritionCalculator**: Reuse for summing daily plan totals.
|
|
|
|
---
|
|
|
|
## Acceptance Criteria
|
|
- [ ] Weekly meal plans can be created and managed via a calendar UI.
|
|
- [ ] Drag-and-drop allows moving recipes between days and meal types.
|
|
- [ ] The suggestion engine prioritizes recipes using urgent pantry items.
|
|
- [ ] Daily nutrition bars reflect progress against user-defined macro targets.
|
|
- [ ] Shopping gap analysis identifies missing ingredients for the planned week.
|
|
- [ ] Full unit and integration test coverage as per project standards.
|
|
- [ ] Build, Lint, and Coverage checks all pass.
|