Commit Graph

400 Commits

Author SHA1 Message Date
504581838c feat: Phase 0c - migrate body_metrics calculations to data_layer (20 functions)
All checks were successful
Deploy Development / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
- Migrated all 20 calculation functions from calculations/body_metrics.py to data_layer/body_metrics.py
- Functions: weight trends (7d median, 28d/90d slopes, goal projection, progress)
- Functions: body composition (FM/LBM changes)
- Functions: circumferences (waist/hip/chest/arm/thigh deltas, WHR)
- Functions: recomposition quadrant
- Functions: scoring (body progress, data quality)
- Updated data_layer/__init__.py with 20 new exports
- Refactored placeholder_resolver.py to import body_metrics from data_layer

Module 1/6 complete. Single Source of Truth for body metrics established.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 19:51:08 +01:00
26110d44b4 fix: rest_days schema - use 'focus' column instead of 'rest_type'
All checks were successful
Deploy Development / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Problem: get_rest_days_data() queried non-existent 'rest_type' column
Fix: Changed to 'focus' column with correct values (muscle_recovery, cardio_recovery, etc.)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 19:28:46 +01:00
6c23973c5d feat: Phase 0c - body_metrics.py module complete
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Data Layer:
- get_latest_weight_data() - most recent weight with date
- get_weight_trend_data() - already existed (PoC)
- get_body_composition_data() - already existed (PoC)
- get_circumference_summary_data() - already existed (PoC)

Placeholder Layer:
- get_latest_weight() - refactored to use data layer
- get_caliper_summary() - refactored to use get_body_composition_data
- get_weight_trend() - already refactored (PoC)
- get_latest_bf() - already refactored (PoC)
- get_circ_summary() - already refactored (PoC)

body_metrics.py now complete with all 4 functions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 19:17:02 +01:00
b4558b0582 feat: Phase 0c - health_metrics.py module complete
All checks were successful
Deploy Development / deploy (push) Successful in 53s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Data Layer:
- get_resting_heart_rate_data() - avg RHR with min/max trend
- get_heart_rate_variability_data() - avg HRV with min/max trend
- get_vo2_max_data() - latest VO2 Max with date

Placeholder Layer:
- get_vitals_avg_hr() - refactored to use data layer
- get_vitals_avg_hrv() - refactored to use data layer
- get_vitals_vo2_max() - refactored to use data layer

All 3 health data functions + 3 placeholder refactors complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 19:15:31 +01:00
432f7ba49f feat: Phase 0c - recovery_metrics.py module complete
All checks were successful
Deploy Development / deploy (push) Successful in 53s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
Data Layer:
- get_sleep_duration_data() - avg duration with hours/minutes breakdown
- get_sleep_quality_data() - Deep+REM percentage with phase breakdown
- get_rest_days_data() - total count + breakdown by rest type

Placeholder Layer:
- get_sleep_avg_duration() - refactored to use data layer
- get_sleep_avg_quality() - refactored to use data layer
- get_rest_days_count() - refactored to use data layer

All 3 recovery data functions + 3 placeholder refactors complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 19:13:59 +01:00
6b2ad9fa1c feat: Phase 0c - activity_metrics.py module complete
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 16s
Data Layer:
- get_activity_summary_data() - count, duration, calories, frequency
- get_activity_detail_data() - detailed activity log with all fields
- get_training_type_distribution_data() - category distribution with percentages

Placeholder Layer:
- get_activity_summary() - refactored to use data layer
- get_activity_detail() - refactored to use data layer
- get_trainingstyp_verteilung() - refactored to use data layer

All 3 activity data functions + 3 placeholder refactors complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 19:11:45 +01:00
e1d7670971 feat: Phase 0c - nutrition_metrics.py module complete
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Data Layer:
- get_nutrition_average_data() - all macros in one call
- get_nutrition_days_data() - coverage tracking
- get_protein_targets_data() - 1.6g/kg and 2.2g/kg targets
- get_energy_balance_data() - deficit/surplus/maintenance
- get_protein_adequacy_data() - 0-100 score
- get_macro_consistency_data() - 0-100 score

Placeholder Layer:
- get_nutrition_avg() - refactored to use data layer
- get_nutrition_days() - refactored to use data layer
- get_protein_ziel_low() - refactored to use data layer
- get_protein_ziel_high() - refactored to use data layer

All 6 nutrition data functions + 4 placeholder refactors complete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 18:45:24 +01:00
c79cc9eafb feat: Phase 0c - Multi-Layer Data Architecture (Proof of Concept)
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
- Add data_layer/ module structure with utils.py + body_metrics.py
- Migrate 3 functions: weight_trend, body_composition, circumference_summary
- Refactor placeholders to use data layer
- Add charts router with 3 Chart.js endpoints
- Tests: Syntax , Confidence logic 

Phase 0c PoC (3 functions): Foundation for 40+ remaining functions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 18:26:22 +01:00
255d1d61c5 docs: cleanup debug logs + document goal system enhancements
All checks were successful
Deploy Development / deploy (push) Successful in 53s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
- Removed all debug print statements from placeholder_resolver.py
- Removed debug print statements from goals.py (list_goals, update_goal)
- Updated CLAUDE.md with Phase 0a completion details:
  * Auto-population of start_date/start_value from historical data
  * Time-based tracking (behind schedule = time-deviated)
  * Hybrid goal display (with/without target_date)
  * Timeline visualization in goal lists
  * 7 bug fixes documented
- Created memory file for future sessions (feedback_goal_system.md)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 17:32:13 +01:00
dd395180a3 feat: hybrid goal tracking - with/without target_date
All checks were successful
Deploy Development / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
Implements requested hybrid approach:

WITH target_date:
  - Time-based deviation (actual vs. expected progress)
  - Format: 'Zielgewicht (41%, +7% voraus)'

WITHOUT target_date:
  - Simple progress percentage
  - Format: 'Ruhepuls (100% erreicht)' or 'VO2max (0% erreicht)'

Sorting:
  behind_schedule:
    1. Goals with negative deviation (behind timeline)
    2. Goals without date with progress < 50%

  on_track:
    1. Goals with positive deviation (ahead of timeline)
    2. Goals without date with progress >= 50%

Kept debug logging for new hybrid logic validation.
2026-03-28 17:22:18 +01:00
0e89850df8 fix: add start_date and created_at to get_active_goals query
All checks were successful
Deploy Development / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
ROOT CAUSE: get_active_goals() SELECT was missing start_date and created_at
IMPACT: Time-based deviation calculation failed silently for all goals

Now returns:
- start_date: Required for accurate time-based progress calculation
- created_at: Fallback when start_date is not set

This fixes:
- Zielgewicht (weight) should now show +7% ahead
- Körperfett should show time deviation
- All goals with target_date now have time-based tracking
2026-03-28 17:18:53 +01:00
eb8b503faa debug: log all continue statements in goal deviation calculation
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
- Log when using created_at as fallback for start_date
- Log when skipping due to missing created_at
- Log when skipping due to invalid date range (total_days <= 0)

This will reveal exactly why Körperfett and Zielgewicht are not added.
2026-03-28 15:09:41 +01:00
294b3b2ece debug: extensive logging for behind_schedule/on_track calculation
All checks were successful
Deploy Development / deploy (push) Successful in 54s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
- Log each goal processing (name, values, dates)
- Log skip reasons (missing values, no target_date)
- Log exceptions during calculation
- Log successful additions with calculated values

This will reveal why Weight goal (+7% ahead) is not showing up.
2026-03-28 15:07:31 +01:00
8e67175ed2 fix: behind_schedule now uses time-based deviation, not just lowest progress
All checks were successful
Deploy Development / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
OLD: Showed 3 goals with lowest progress %
NEW: Calculates expected progress based on elapsed time vs. total time
     Shows goals with largest negative deviation (behind schedule)

Example Weight Goal:
- Total time: 98 days (22.02 - 31.05)
- Elapsed: 34 days (35%)
- Actual progress: 41%
- Deviation: +7% (AHEAD, not behind)

Also updated on_track to show goals with positive deviation (ahead of schedule).

Note: Linear progress is a simplification. Real-world progress curves vary
by goal type (weight loss, muscle gain, VO2max, etc). Future: AI-based
projection models for more realistic expectations.
2026-03-28 14:58:50 +01:00
d7aa0eb3af feat: show target_date in goal list next to target value
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
- Start value already showed start_date in parentheses
- Now target value also shows target_date in parentheses
- Consistent UX: both dates visible at their respective values
2026-03-28 14:50:34 +01:00
cb72f342f9 fix: add missing start_date and reached_date to grouped goals query
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Root cause: listGoalsGrouped() SELECT was missing g.start_date and g.reached_date
Result: Frontend used grouped goals for editing, so start_date was undefined

This is why target_date worked (it was in SELECT) but start_date didn't.
2026-03-28 14:48:41 +01:00
623f34c184 debug: extensive frontend logging for goal dates
All checks were successful
Deploy Development / deploy (push) Successful in 54s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 14:46:06 +01:00
b7e7817392 debug: show ALL goals with dates, not just first
Some checks failed
Build Test / lint-backend (push) Waiting to run
Build Test / build-frontend (push) Waiting to run
Deploy Development / deploy (push) Has been cancelled
2026-03-28 14:45:36 +01:00
068a8e7a88 debug: show goals after serialization
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 14:41:33 +01:00
97defaf704 fix: serialize date objects to ISO format for JSON
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 14s
- Added serialize_dates() helper to convert date objects to strings
- Applied to list_goals and get_goals_grouped endpoints
- Fixes issue where start_date was saved but not visible in frontend
- Python datetime.date objects need explicit .isoformat() conversion

Root cause: FastAPI doesn't auto-serialize all date types consistently
2026-03-28 14:36:45 +01:00
370f0d46c7 debug: extensive logging for start_date persistence
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
- Log UPDATE SQL and parameters
- Verify saved values after UPDATE
- Show date types in list_goals response
- Track down why start_date not visible in UI
2026-03-28 14:33:16 +01:00
c90e30806b fix: save start_date to database in update_goal
All checks were successful
Deploy Development / deploy (push) Successful in 53s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
- Rewrote update logic to determine final_start_date/start_value first
- Then append to updates/params arrays (ensures alignment)
- Fixes bug where only start_value was saved but not start_date

User feedback: start_value correctly calculated but start_date not persisted
2026-03-28 14:28:52 +01:00
ab29a85903 debug: Add console logging to trace start_date loading
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 13:55:29 +01:00
3604ebc781 fix: Load actual start_date in edit form + improve timeline display
All checks were successful
Deploy Development / deploy (push) Successful in 48s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
**Problem 1:** Edit form showed today's date instead of stored start_date
- Cause: Fallback logic `goal.start_date || today` always defaulted to today
- Fix: Load actual date or empty string (no fallback)
- Input field: Remove fallback from value binding

**Problem 2:** Timeline only showed target_date, not start_date
- Added dedicated timeline display below values
- Shows: "📅 15.01.26 → 31.05.26"
- Only appears if at least one date exists
- Start date with calendar icon, target date bold

**Result:**
- Editing goals now preserves the start_date ✓
- Timeline clearly shows start → target dates ✓
- No more accidental overwrites with today's date ✓

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 13:50:47 +01:00
e479627f0f feat: Auto-adjust start_date to first available measurement
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
**User Feedback:** "Macht es nicht Sinn, den nächsten verfügbaren Wert
am oder nach dem Startdatum automatisch zu ermitteln und auch das
Startdatum dann automatisch auf den Wert zu setzen?"

**New Logic:**
1. User sets start_date: 2026-01-01
2. System finds FIRST measurement >= 2026-01-01 (e.g., 2026-01-15: 88 kg)
3. System auto-adjusts:
   - start_date → 2026-01-15
   - start_value → 88 kg
4. User sees: "Start: 88 kg (15.01.26)" ✓

**Benefits:**
- User doesn't need to know exact date of first measurement
- More user-friendly UX
- Automatically finds closest available data

**Implementation:**
- Changed query from "BETWEEN date ±7 days" to "WHERE date >= target_date"
- Returns dict with {'value': float, 'date': date}
- Both create_goal() and update_goal() now adjust start_date automatically

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 13:41:35 +01:00
169dbba092 debug: Add comprehensive logging to trace historical value lookup
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 13:27:16 +01:00
42cc583b9b debug: Add logging to update_goal to trace start_date issue
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 13:24:29 +01:00
7ffa8f039b fix: PostgreSQL date subtraction in historical value query
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
**Error:**
function pg_catalog.extract(unknown, integer) does not exist
HINT: No function matches the given name and argument types.

**Problem:**
In PostgreSQL, date - date returns INTEGER (days), not INTERVAL.
EXTRACT(EPOCH FROM integer) fails because EPOCH expects timestamp/interval.

**Solution:**
Changed from:
  ORDER BY ABS(EXTRACT(EPOCH FROM (date - '2026-01-01')))

To:
  ORDER BY ABS(date - '2026-01-01'::date)

This directly uses the day difference (integer) for sorting,
which is exactly what we need to find the closest date.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 13:22:05 +01:00
1c7b5e0653 fix: Include start_date in goal edit form and API call
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
**Bug:** start_date was not being loaded into edit form or sent in update request

**Fixed:**
1. handleEditGoal() - Added start_date to formData when editing
2. handleSaveGoal() - Added start_date to API payload for both create and update

Now when editing a goal:
- start_date field is populated with existing value
- Changing start_date triggers backend to recalculate start_value
- Update request includes start_date

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 13:19:10 +01:00
327319115d feat: Frontend - Startdatum field in goal form
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Added start_date field to goal creation/editing form:

1. New "Startdatum" input field before "Zieldatum"
   - Defaults to today
   - Hint: "Startwert wird automatisch aus historischen Daten ermittelt"

2. Display start_date in goals list
   - Shows next to start_value: "85 kg (01.01.26)"
   - Compact format for better readability

3. Updated formData state
   - Added start_date with today as default
   - API calls automatically include it

User can now:
- Set historical start date (e.g., 3 months ago)
- Backend auto-populates start_value from that date
- See exact start date and value for each goal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 13:15:56 +01:00
efde158dd4 feat: Auto-populate goal start_value from historical data
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
**Problem:** Goals created today had start_value = current_value,
showing 0% progress even after months of tracking.

**Solution:**
1. Added start_date and start_value to GoalCreate/GoalUpdate models
2. New function _get_historical_value_for_goal_type():
   - Queries source table for value on specific date
   - ±7 day window for closest match
   - Works with all goal types via goal_type_definitions
3. create_goal() logic:
   - If start_date < today → auto-populate from historical data
   - If start_date = today → use current value
   - User can override start_value manually
4. update_goal() logic:
   - Changing start_date recalculates start_value
   - Can manually override start_value

**Example:**
- Goal created today with start_date = 3 months ago
- System finds weight on that date (88 kg)
- Current weight: 85.2 kg, Target: 82 kg
- Progress: (85.2 - 88) / (82 - 88) = 47% ✓

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 13:14:33 +01:00
a6701bf7b2 fix: Include start_value in get_active_goals query
All checks were successful
Deploy Development / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Goal progress placeholders were filtering out all goals because
start_value was missing from the SELECT statement.

Added start_value to both:
- get_active_goals() - for placeholder formatters
- get_goal_by_id() - for consistency

This will fix:
- active_goals_md progress column (was all "-")
- top_3_goals_behind_schedule (was "keine Ziele")
- top_3_goals_on_track (was "keine Ziele")

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 13:02:43 +01:00
befc310958 fix: focus_areas column name + goal progress calculation
All checks were successful
Deploy Development / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Fixed 2 critical placeholder issues:

1. focus_areas_weighted_json was empty:
   - Query used 'area_key' but column is 'key' in focus_area_definitions
   - Changed to SELECT key, not area_key

2. Goal progress placeholders showed "nicht verfügbar":
   - progress_pct in goals table is NULL (not auto-calculated)
   - Added manual calculation in all 3 formatter functions:
     * _format_goals_as_markdown() - shows % in table
     * _format_goals_behind() - finds lowest progress
     * _format_goals_on_track() - finds >= 50% progress

All placeholders should now return proper values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 12:43:54 +01:00
112226938d fix: Convert goal values to float before progress calculation
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
TypeError: unsupported operand type(s) for -: 'decimal.Decimal' and 'float'

PostgreSQL NUMERIC columns return Decimal objects. Must convert
current_value, target_value, start_value to float before passing
to calculate_goal_progress_pct().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 12:39:26 +01:00
8da577fe58 fix: Phase 0b - body_progress_score + placeholder formatting
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Fixed remaining placeholder calculation issues:

1. body_progress_score returning 0:
   - When start_value is NULL, query oldest weight from last 90 days
   - Prevents progress = 0% when start equals current

2. focus_areas_weighted_json empty:
   - Changed from goal_utils.get_focus_weights_v2() to scores.get_user_focus_weights()
   - Now uses same function as focus_area_weights_json

3. Implemented 5 TODO markdown formatting functions:
   - _format_goals_as_markdown() - table with progress bars
   - _format_focus_areas_as_markdown() - weighted list
   - _format_top_focus_areas() - top N by weight
   - _format_goals_behind() - lowest progress goals
   - _format_goals_on_track() - goals >= 50% progress

All placeholders should now return proper values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 12:34:24 +01:00
b09a7b200a fix: Phase 0b - implement active_goals and focus_areas JSON placeholders
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Root cause: Two TODO stubs always returned '[]'

Implemented:
- active_goals_json: Calls get_active_goals() from goal_utils
- focus_areas_weighted_json: Builds weighted list with names/categories

Result:
- active_goals_json now shows actual goals
- body_progress_score should calculate correctly
- top_3_goals placeholders will work

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 12:19:37 +01:00
05d15264c8 fix: Phase 0b - complete Decimal/float conversion in nutrition_metrics
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Previous commit only converted weight values, but missed:
- avg_intake (calories from DB)
- avg_protein (protein_g from DB)
- protein_per_kg calculations in loops

All DB numeric values now converted to float BEFORE arithmetic.

Fixed locations:
- Line 44: avg_intake conversion
- Line 126: avg_protein conversion
- Line 175: protein_per_kg in loop
- Line 213: protein_values list comprehension

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 11:32:07 +01:00
78437b649f fix: Phase 0b - PostgreSQL Decimal type handling
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
TypeError: unsupported operand type(s) for *: 'decimal.Decimal' and 'float'
TypeError: unsupported operand type(s) for -: 'float' and 'decimal.Decimal'

PostgreSQL NUMERIC/DECIMAL columns return decimal.Decimal objects,
not float. These cannot be mixed in arithmetic operations.

Fixed 3 locations:
- Line 62: float(weight_row['weight']) * 32.5
- Line 153: float(weight_row['weight']) for protein_per_kg
- Line 202: float(weight_row['avg_weight']) for adequacy calc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 11:23:40 +01:00
6f20915d73 fix: Phase 0b - body_progress_score uses correct column name
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
Bug: Filtered goals by g.get('type_key') but goals table has 'goal_type' column.
Result: weight_goals was always empty → _score_weight_trend returned None.

Fix: Changed 'type_key' → 'goal_type' (matches goals table schema).

Verified: Migration 022 defines goal_type column, not type_key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 11:16:29 +01:00
202c36fad7 fix: Phase 0b - replace non-existent get_goals_by_type import
All checks were successful
Deploy Development / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
ImportError: cannot import name 'get_goals_by_type' from 'goal_utils'

Changes:
- body_metrics.py: Use get_active_goals() + filter by type_key
- nutrition_metrics.py: Remove unused import (dead code)

Result: Score functions no longer crash on import error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 11:04:28 +01:00
cc76ae677b fix: Phase 0b - score functions use English focus area keys
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
Root cause: All 3 score functions returned None because they queried
German focus area keys that don't exist in database (migration 031
uses English keys).

Changes:
- body_progress_score: körpergewicht/körperfett/muskelmasse
  → weight_loss/muscle_gain/body_recomposition
- nutrition_score: ernährung_basis/proteinzufuhr/kalorienbilanz
  → protein_intake/calorie_balance/macro_consistency/meal_timing/hydration
- activity_score: kraftaufbau/cardio/bewegungsumfang/trainingsqualität
  → strength/aerobic_endurance/flexibility/rhythm/coordination (grouped)

Result: Scores now calculate correctly with existing focus area weights.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 10:59:37 +01:00
63bd103b2c feat: Phase 0b - add avg_per_week_30d to frontend dropdown
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 10:50:51 +01:00
14c4ea13d9 feat: Phase 0b - add avg_per_week_30d aggregation method
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
- Calculates average count per week over 30 days
- Use case: Training frequency per week (smoothed)
- Formula: (count in 30 days) / 4.285 weeks
- Documentation: .claude/docs/technical/AGGREGATION_METHODS.md
2026-03-28 10:45:36 +01:00
9fa6c5dea7 feat: Phase 0b - add nutrition focus areas to score mapping
All checks were successful
Deploy Development / deploy (push) Successful in 48s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 10:20:46 +01:00
949301a91d feat: Phase 0b - add nutrition focus area category (migration 033) 2026-03-28 10:20:08 +01:00
43e6c3e7f4 fix: Phase 0b - map German to English category names
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
2026-03-28 10:13:10 +01:00
e3e635d9f5 fix: Phase 0b - remove orphaned German mapping entries
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 10:10:18 +01:00
289b132b8f fix: Phase 0b - map_focus_to_score_components English keys
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 09:53:59 +01:00
919eae6053 fix: Phase 0b - sleep dict access in health_stability_score regularity
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 15s
2026-03-28 09:42:54 +01:00
91bafc6af1 fix: Phase 0b - activity duration column in health_stability_score
All checks were successful
Deploy Development / deploy (push) Successful in 51s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 13s
2026-03-28 09:40:07 +01:00