Files
clawd d81e403f01 Phase 06 Tier 1: Complete Backend Implementation - Recovery Tracking & Swap System
COMPLETED TASKS:
 06-01: Workout Swap System
   - Added swapped_from_id to workout_logs
   - Created workout_swaps table for history
   - POST /api/workouts/:id/swap endpoint
   - GET /api/workouts/available endpoint
   - Reversible swaps with audit trail

 06-02: Muscle Group Recovery Tracking
   - Created muscle_group_recovery table
   - Implemented calculateRecoveryScore() function
   - GET /api/recovery/muscle-groups endpoint
   - GET /api/recovery/most-recovered endpoint
   - Auto-tracking on workout log completion

 06-03: Smart Workout Recommendations
   - GET /api/recommendations/smart-workout endpoint
   - 7-day workout analysis algorithm
   - Recovery-based filtering (>30% threshold)
   - Top 3 recommendations with context
   - Context-aware reasoning messages

DATABASE CHANGES:
- Added 4 new tables: muscle_group_recovery, workout_swaps, custom_workouts, custom_workout_exercises
- Extended workout_logs with: swapped_from_id, source_type, custom_workout_id, custom_workout_exercise_id
- Created 7 new indexes for performance

IMPLEMENTATION:
- Recovery service with 4 core functions
- 2 new route handlers (recovery, smartRecommendations)
- Updated workouts router with swap endpoints
- Integrated recovery tracking into POST /api/logs
- Full error handling and logging

TESTING:
- Test file created: /backend/test/phase-06-tests.js
- Ready for E2E and staging validation

STATUS: Ready for frontend integration and production review
Branch: feature/06-phase-06
2026-03-06 20:54:03 +01:00

66 lines
4.5 KiB
JSON

{
"protein_sources": [
{ "name": "Kycklingbröst", "serving": "100g", "kcal": 165, "protein": 31, "fat": 3.6, "carbs": 0 },
{ "name": "Laxfilé", "serving": "100g", "kcal": 208, "protein": 20, "fat": 13, "carbs": 0 },
{ "name": "Ägg (1 st)", "serving": "60g", "kcal": 90, "protein": 7, "fat": 6, "carbs": 0.5 },
{ "name": "Kvarg (naturell)", "serving": "100g", "kcal": 63, "protein": 11, "fat": 0.2, "carbs": 4 },
{ "name": "Grekisk yoghurt", "serving": "100g", "kcal": 97, "protein": 9, "fat": 5, "carbs": 3 },
{ "name": "Cottage cheese", "serving": "100g", "kcal": 98, "protein": 11, "fat": 4.3, "carbs": 3.4 },
{ "name": "Nötfärs (10%)", "serving": "100g", "kcal": 176, "protein": 20, "fat": 10, "carbs": 0 },
{ "name": "Tonfisk (konserv)", "serving": "100g", "kcal": 116, "protein": 26, "fat": 1, "carbs": 0 },
{ "name": "Räkor", "serving": "100g", "kcal": 85, "protein": 18, "fat": 1, "carbs": 0 },
{ "name": "Tofu", "serving": "100g", "kcal": 76, "protein": 8, "fat": 4.8, "carbs": 1.9 },
{ "name": "Tempeh", "serving": "100g", "kcal": 192, "protein": 19, "fat": 11, "carbs": 8 },
{ "name": "Proteinpulver (whey)", "serving": "30g", "kcal": 120, "protein": 24, "fat": 1.5, "carbs": 3 }
],
"carb_sources": [
{ "name": "Ris (kokt)", "serving": "100g", "kcal": 130, "protein": 2.7, "fat": 0.3, "carbs": 28 },
{ "name": "Pasta (kokt)", "serving": "100g", "kcal": 131, "protein": 5, "fat": 1.1, "carbs": 25 },
{ "name": "Potatis (kokt)", "serving": "100g", "kcal": 77, "protein": 2, "fat": 0.1, "carbs": 17 },
{ "name": "Sötpotatis", "serving": "100g", "kcal": 86, "protein": 1.6, "fat": 0.1, "carbs": 20 },
{ "name": "Havregryn", "serving": "100g", "kcal": 379, "protein": 13, "fat": 7, "carbs": 66 },
{ "name": "Bröd (fullkorn)", "serving": "1 skiva", "kcal": 80, "protein": 3, "fat": 1, "carbs": 15 },
{ "name": "Banan", "serving": "1 st (120g)", "kcal": 105, "protein": 1.3, "fat": 0.4, "carbs": 27 },
{ "name": "Äpple", "serving": "1 st (150g)", "kcal": 78, "protein": 0.4, "fat": 0.2, "carbs": 21 },
{ "name": "Quinoa (kokt)", "serving": "100g", "kcal": 120, "protein": 4.4, "fat": 1.9, "carbs": 21 }
],
"fat_sources": [
{ "name": "Olivolja", "serving": "1 msk", "kcal": 119, "protein": 0, "fat": 13.5, "carbs": 0 },
{ "name": "Avokado", "serving": "100g", "kcal": 160, "protein": 2, "fat": 15, "carbs": 9 },
{ "name": "Mandlar", "serving": "30g", "kcal": 173, "protein": 6, "fat": 15, "carbs": 6 },
{ "name": "Jordnötssmör", "serving": "1 msk", "kcal": 94, "protein": 4, "fat": 8, "carbs": 3 },
{ "name": "Smör", "serving": "10g", "kcal": 72, "protein": 0, "fat": 8, "carbs": 0 },
{ "name": "Ost (vällagrad)", "serving": "30g", "kcal": 120, "protein": 8, "fat": 10, "carbs": 0 }
],
"vegetables": [
{ "name": "Broccoli", "serving": "100g", "kcal": 34, "protein": 2.8, "fat": 0.4, "carbs": 7 },
{ "name": "Spenat", "serving": "100g", "kcal": 23, "protein": 2.9, "fat": 0.4, "carbs": 3.6 },
{ "name": "Paprika", "serving": "100g", "kcal": 31, "protein": 1, "fat": 0.3, "carbs": 6 },
{ "name": "Tomat", "serving": "100g", "kcal": 18, "protein": 0.9, "fat": 0.2, "carbs": 3.9 },
{ "name": "Gurka", "serving": "100g", "kcal": 15, "protein": 0.7, "fat": 0.1, "carbs": 3.6 },
{ "name": "Morötter", "serving": "100g", "kcal": 41, "protein": 0.9, "fat": 0.2, "carbs": 10 }
],
"meal_templates": {
"bulk_day": {
"description": "~2800 kcal, 180g protein",
"meals": [
{ "name": "Frukost", "example": "Havregryn 80g + mjölk + banan + whey", "kcal": 550 },
{ "name": "Lunch", "example": "Kyckling 150g + ris 200g + grönsaker + olivolja", "kcal": 700 },
{ "name": "Mellanmål", "example": "Kvarg 300g + jordnötssmör + frukt", "kcal": 450 },
{ "name": "Middag", "example": "Lax 150g + potatis 250g + grönsaker", "kcal": 650 },
{ "name": "Kvällsmål", "example": "Ägg 3st + bröd 2 skivor + ost", "kcal": 450 }
]
},
"cut_day": {
"description": "~1800 kcal, 160g protein",
"meals": [
{ "name": "Frukost", "example": "Ägg 3st + grönsaker + 1 brödskiva", "kcal": 350 },
{ "name": "Lunch", "example": "Kyckling 150g + ris 100g + mycket grönsaker", "kcal": 450 },
{ "name": "Mellanmål", "example": "Kvarg 250g + bär", "kcal": 200 },
{ "name": "Middag", "example": "Torsk 200g + potatis 150g + grönsaker", "kcal": 400 },
{ "name": "Kvällsmål", "example": "Cottage cheese 200g + gurka", "kcal": 200 }
]
}
}
}