# MealPlan — Product Specification (Interview Reference)

Use this to answer candidate questions during the interview. Let them ask first — don't volunteer everything. How many and which questions they ask is a signal.

---

## 1. Overview

**Concept:** Weekly meal planner for families. Plan meals, auto-generate shopping lists, track nutrition, get AI meal suggestions.

**Users:** Family household (2–6 members). Each member has individual profile (age, weight, dietary restrictions, allergies, preferences). One account per household, multiple profiles.

**Platform:** Responsive web app. Primary UX target: mobile-first (meal planning happens on phone in kitchen/grocery store). Desktop usable.

---

## 2. Personas

### Primary: The Household Manager
- Late 20s–40s, one or two working parents
- Plans meals weekly (Sunday evening). Grocery shop once or twice per week.
- Wants: speed, reuse past weeks, minimize food waste, family approval
- Pain: "What's for dinner" repeated daily, forgotten ingredients, impulse takeout

### Secondary: The Cook
- Anyone who executes dinner. May be different person than planner.
- Uses app in the kitchen (phone or tablet).
- Wants: step-by-step recipe, timers, substitutions if missing ingredient
- Pain: recipe linked to meal easily, but cooking flow is outside scope for v1

### Tertiary: Kids / Picky Eaters
- Don't use the app. Their preferences are represented as tags/dietary flags per profile.

---

## 3. Core Features (v1)

### 3.1 Meal Grid

- 7-day view, Mon–Sun. Week starts Monday (configurable in future).
- 3 meal slots per day: Breakfast, Lunch, Dinner. Future: Snack, Dessert.
- Each slot: assigned recipe OR empty state ("+"). Cannot assign multiple recipes to one slot.
- Grid is read by multiple family members simultaneously. Edit is single-writer per slot (lock approach — see conflict section).
- Week navigation: previous week, next week, "jump to current week."
- Copy week: duplicate entire week's meals (or single-day) to a future week. Copied slots are "draft" — user can modify before confirming.

### 3.2 Recipes

- Recipe: name, description, serving size, prep time, cook time, total time, difficulty (easy/medium/hard), cuisine type, tags (user-defined)
- Ingredients: list of (ingredient_name, quantity, unit, optional_note). No nested ingredients.
- Instructions: ordered list of steps. Each step is free text with optional cooking timer (in minutes).
- Photo: 0–3 photos per recipe (plating, step, ingredient group).
- Source: user-created, AI-generated, or imported from public recipe API (edamam / spoonacular). AI recipes are marked with `source: "ai"` and flagged for user confirmation before saving.
- Users can mark favorites, rate (1–5 stars), write private notes.
- Recipe count expected per household: 20–200 (v1), up to 2000 (power user in v2).

### 3.3 Shopping List

- Aggregation of ingredients across all assigned meals in selected date range (default: current Mon–Sun).
- Deduplication rules:
  - Same ingredient, same unit → sum quantities: "garlic, 2 cloves" + "garlic, 1 clove" = "garlic, 3 cloves"
  - Same ingredient, different unit → convert to canonical: "garlic, 1 head" + "garlic, 2 cloves" → depends on recipe context — hard problem
  - Near-duplicates → synonym map: "spring onion" / "scallion" / "green onion" → unified name
- Auto-categorize: Produce, Meat & Seafood, Dairy, Pantry, Frozen, Spices, Other. Rules are per-ingredient mapping in recipe DB.
- Manual override: user can add/edit/delete items, mark as owned, adjust quantity.
- Seen by: all family members in real-time. Checkbox syncs across devices.
- Export: plain text list, share via messaging. Future: grocery delivery API integration.

### 3.4 Nutrition Tracking

- Per-meal calories, protein, carbs, fat shown on meal card.
- Per-day and per-week totals shown in nutrition panel.
- Source: recipe ingredient → nutrition DB query. If ingredient not matched → show "N/A" with warning icon.
- Daily target: set per profile. Default based on WHO guidelines for age/sex/weight.
- Weekly average vs target: simple bar comparison.
- Scope: v1 is informational only — no weight logging, no meal diary beyond planned meals.

### 3.5 AI Meal Assistant

- Chat interface, natural language. No strict command format.
- Scope: suggest meals given constraints (leftovers, dietary, time), answer nutrition questions, explain recipe substitutions.
- Not a general-purpose chatbot. Topic-scoped: meals, nutrition, ingredients only.
- Prompt engineering: system prompt includes user's dietary preferences, age, household size, recent meals, current inventory.
- Fallback: "I can't answer that" — not a search engine.
- First message is proactive if inventory has unused ingredients (see mockup). Otherwise passive.

### 3.6 AI Feature — What's in My Fridge

- User takes photo of fridge contents (phone camera in app, no gallery import in v1).
- System returns detected items with confidence (≥70% shown as "detected", <70% shown with confidence badge).
- User confirms detected items, adjusts quantity, adds missing items manually.
- System suggests recipes where ingredient coverage ≥50%. Ranked by match percentage × user preference × prep time.
- Suggestion card: recipe name, prep time, missing ingredients highlighted ("You need: soy sauce"), "Add to meal plan" button (autofills next available slot).
- Fallback — no photo available: manual text input "I have chicken, broccoli, rice."
- Privacy: photos not stored after processing. User can opt-in to store for future detection training.

---

## 4. Data Model (Core Entities)

```
Household
  id, name, created_at, timezone, meal_week_start (monday/sunday)

Profile (1 per family member)
  id, household_id, name, dietary_restrictions[], allergies[],
  daily_calorie_target, is_default, avatar_url

Recipe
  id, household_id, name, source (user/ai/imported), serving_size,
  prep_time_min, cook_time_min, difficulty, cuisine_type,
  tags[], rating, notes, photos[], created_at, updated_at
  ingredients: [{name, quantity, unit, note}]
  steps: [{order, text, timer_min?}]

MealSlot
  id, household_id, recipe_id?, date, meal_type (breakfast/lunch/dinner),
  servings_override (default: recipe serving size), created_by,
  created_at, updated_at, status (active/draft/tentative)

ShoppingListItem
  id, household_id, name, quantity, unit, category,
  is_checked, checked_by, checked_at,
  source_meal_slot_ids[], is_manual (true if user added directly)

Inventory
  id, household_id, ingredient_name, quantity, unit,
  added_at, expiry_date, source (manual/photo/from_shopping_list)

ChatMessage
  id, household_id, role (user/assistant), content,
  suggested_recipe_ids[], created_at

NutritionSnapshot (eventual consistency cache, recomputed on meal change)
  id, household_id, profile_id, date, meal_type?,
  total_cal, total_protein, total_carbs, total_fat
```

---

## 5. Non-Functional / Constraints

### 5.1 Performance
- Meal grid loads in <1s for one week (21 slots → compute from cached recipe + nutrition data).
- Shopping list recompute: <2s for full week, 10+ meals, 50+ ingredient lines.
- AI Assistant response: initial chunk in <2s, full response in <8s. Stream to UI.
- "What's in My Fridge" photo → suggestions: <10s total.

### 5.2 Offline
- Meal grid must be editable without network. Changes sync when online.
- Recipe browsing must work offline if recipe was viewed recently.
- Shopping list checkbox must work offline.
- AI features: chat, photo → unavailable offline. Show graceful degredation.
- Recipe create/edit: offline queue, sync with conflict detection.

### 5.3 Real-time
- Two family members viewing same week should see same state without manual refresh.
- Shopping list check hits sync in <3s to other devices.

### 5.4 Scale
- 10,000 households expected year 1, 100,000 year 2.
- Each household: 100 recipes avg, 52 weeks × 21 slots/year.
- AI features hit external LLM API (no on-device model).

---

## 6. Open Ambiguities (Deliberate for Interview)

The following are NOT specified — strong candidates will notice and ask:

- **Multi-user editing:** How conflict resolution works when two users edit same meal slot simultaneously. (Intent: last-write-wins with notification? Pessimistic lock? CRDT?)
- **Search:** How recipes are searched (full-text? semantic? tags-only?) — not defined.
- **Authentication:** Social login? Email/password? SSO? Not specified — assume basic auth for now, but the omission is noticeable.
- **Data export:** Can user export their recipes / meal history? Not in v1 spec.
- **Meal history:** How far back data is retained. Forever? Rolling 6 months? Not specified.
- **Recipe scaling:** When a meal is planned for 4 people but recipe serves 2 — how ingredient quantities scale. Linear? Fractional eggs handled how? Not specified.
- **Push notifications:** Reminders to plan meals, shop, or start cooking? Not in v1 but obvious gap.
- **Third-party recipe import format:** URL paste → scrape (structured data, HTML parse, or failure)? Not designed.
- **Accessibility:** WCAG target level? Not stated.
- **Inventory decay:** Fridge items implicitly expire — how does system know when they're gone? Manual removal only? Recurring purchase → auto-decrement? Not specified.

---

## 7. Interview Guidance for Interviewer

| Candidate behavior | Signal |
|---|---|
| Asks "who is the user" before designing | Strong — they establish persona first |
| Notices offline requirements are vague and probes | Strong — real-world awareness |
| Asks about conflict resolution unprompted | Strong — understands multi-user systems |
| Accepts AI latency as normal without asking about UX | Weak — misses the interaction pain point |
| Never questions data model decisions | Neutral — may be implementing, not designing |
| Asks about authentication, data privacy, or RBAC | Positive signal — considers security as part of design |
| Notices "meal week starts Monday" and asks about configuration | Attention to detail + internationalization awareness |
| Asks how the shopping list handles "1 onion" across 3 recipes | Strong — thinking about real-world data problems |

Use the open ambiguities section (6) to evaluate: does the candidate surface these naturally, or do they assume perfect information?
