Sprint 7: US-07 Macronutrient Information — Technical Decisions
Overview
Sprint 7 (User Story #36 / US-07) adds personalized macronutrient target display to the LocalFoodAI interface. It is split into two focused tasks: backend data exposure (#37) and responsive UI cards (#38).
Task #37: Backend Data Exposure
What we chose
- New table:
user_profiles (in localfood.db) instead of a separate user_macro_targets table.
- Reasoning: Avoids data duplication. The same table will be extended in a later sprint to hold full profile data (age, weight, BMR inputs). Starting with macro targets here means we have one clean place for all user personalization data.
- Default values hardcoded in the schema:
- Calories: 2000 kcal
- Protein: 150 g
- Carbs: 200 g
- Fat: 65 g
- Reasoning: These are generic safe baseline values (based on general dietary guidelines). Real personalized targets will be calculated later via BMR/TDEE logic.
- Auto-insertion on first fetch: The
get_user_profile() function automatically inserts a default row if the user has no profile yet. This prevents API errors and means users always see valid values immediately on first login.
- Read-only endpoint:
GET /api/macros/targets — no POST endpoint at this stage. All data modification will be addressed when the full profile management feature is implemented.
Task #38: Responsive Nutrient Breakdown Cards
What we chose
- Placement: The dashboard is placed directly below the food search bar, above the chat, so it is always visible without scrolling.
- Design system: Glassmorphism cards using
backdrop-filter: blur, rgba backgrounds, and subtle borders — matching the existing chat interface design.
- Color coding per macro:
| Macro | Color |
|-------|-------|
| Calories | Yellow
#facc15 |
| Protein | Red #ef4444 |
| Carbs | Blue #3b82f6 |
| Fat | Green #22c55e |
- Reasoning: Color-coded cards make it immediately clear which value is which at a glance, without needing to read the label closely.
- Responsive layout: Cards use
flex-wrap and reduce in size on screens narrower than 768px (mobile-friendly).
- Visibility lifecycle: The dashboard is
display: none by default and is only shown (display: flex) after a successful GET /api/macros/targets call at login. On logout, it is hidden again, so another user's data is never exposed.