Commit Graph

12 Commits

Author SHA1 Message Date
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
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
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
b230a03fdd fix: Phase 0b - fix blood_pressure and top_goal_name bugs
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 14s
Final bug fixes:
1. blood_pressure_log query - changed 'date' column to 'measured_at' (correct column for TIMESTAMP)
2. top_goal_name KeyError - added 'name' to SELECT in get_active_goals()
3. top_goal_name fallback - use goal_type if name is NULL

Changes:
- scores.py: Fixed blood_pressure_log query to use measured_at instead of date
- goal_utils.py: Added 'name' column to get_active_goals() SELECT
- placeholder_resolver.py: Added fallback to goal_type if name is None

These were the last 2 errors showing in logs. All major calculation bugs should now be fixed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 09:32:04 +01:00
dd3a4111fc fix: Phase 0b - fix remaining calculation errors
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
Fixes applied:
1. WHERE clause column names (total_sleep_min → duration_minutes, resting_heart_rate → resting_hr)
2. COUNT() column names (avg_heart_rate → hr_avg, quality_label → rpe)
3. Type errors (Decimal * float) - convert to float before multiplication
4. rest_days table (type column removed in migration 010, now uses rest_config JSONB)
5. c_thigh_l → c_thigh (no separate left/right columns)
6. focus_area_definitions queries (focus_area_id → key, label_de → name_de)

Missing functions implemented:
- goal_utils.get_active_goals() - queries goals table for active goals
- goal_utils.get_goal_by_id() - gets single goal
- calculations.scores.calculate_category_progress() - maps categories to score functions

Changes:
- activity_metrics.py: Fixed Decimal/float type errors, rest_config JSONB, data quality query
- recovery_metrics.py: Fixed all WHERE clause column names
- body_metrics.py: Fixed c_thigh column reference
- scores.py: Fixed focus_area queries, added calculate_category_progress()
- goal_utils.py: Added get_active_goals(), get_goal_by_id()

All calculation functions should now work with correct schema.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 08:39:31 +01:00
e4a2b63a48 fix: vitals baseline parameter sync + goal utils transaction rollback
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
Bug 1 Fix (Ruhepuls):
- Completely rewrote vitals_baseline POST endpoint
- Clear separation: param_values array contains ALL values (pid, date, ...)
- Synchronized insert_cols, insert_placeholders, and param_values
- Added debug logging
- Simplified UPDATE logic (EXCLUDED.col instead of COALESCE)

Bug 2 Fix (Custom Goal Type Transaction Error):
- Added transaction rollback in goal_utils._fetch_by_aggregation_method()
- When SQL query fails (e.g., invalid column name), rollback transaction
- Prevents 'InFailedSqlTransaction' errors on subsequent queries
- Enhanced error logging (shows filter conditions, SQL, params)
- Returns None gracefully so goal creation can continue

User Action Required for Bug 2:
- Edit goal type 'Trainingshäufigkeit Krafttraining'
- Change filter from {"training_type": "strength"}
  to {"training_category": "strength"}
- activity_log has training_category, NOT training_type column
2026-03-27 22:09:52 +01:00
ca4f722b47 fix: goal_utils - support different date column names
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 13s
Fixed: column 'date' does not exist in blood_pressure_log

blood_pressure_log uses 'measured_at' instead of 'date'.
Added DATE_COLUMN_MAP for table-specific date columns:
- blood_pressure_log → measured_at
- fitness_tests → test_date
- all others → date

Replaced all hardcoded 'date' with dynamic date_col variable.

Fixes error: [ERROR] Failed to fetch value from blood_pressure_log.systolic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 12:42:56 +01:00
4a11d20c4d feat: Goal System v2.0 - Focus Areas with weighted priorities
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
BREAKING: Replaces single 'primary goal' with weighted multi-goal system

Migration 027:
- New table: focus_areas (6 dimensions with percentages)
- Constraint: Sum must equal 100%
- Auto-migration: goal_mode → focus_areas for existing users
- Unique constraint: One active focus_areas per profile

Backend:
- get_focus_weights() V2: Reads from focus_areas table
- Fallback: Uses goal_mode if focus_areas not set
- New endpoints: GET/PUT /api/goals/focus-areas
- Validation: Sum=100, range 0-100

API:
- getFocusAreas() - Get current weights
- updateFocusAreas(data) - Update weights (upsert)

Focus dimensions:
1. weight_loss_pct   (Fettabbau)
2. muscle_gain_pct   (Muskelaufbau)
3. strength_pct      (Kraftsteigerung)
4. endurance_pct     (Ausdauer)
5. flexibility_pct   (Beweglichkeit)
6. health_pct        (Allgemeine Gesundheit)

Benefits:
- Multiple goals with custom priorities
- More flexible than single primary goal
- KI can use weighted scores
- Ready for Phase 0b placeholder integration

UI: Coming in next commit (slider interface)
2026-03-27 08:38:03 +01:00
2303c04123 feat: filtered goal types - count specific training types
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
NEW FEATURE: Filter conditions for goal types
Enables counting/aggregating specific subsets of data.

Example use case: Count only strength training sessions per week
- Create goal type with filter: {"training_type": "strength"}
- count_7d now counts only strength training, not all activities

Implementation:
- Migration 026: filter_conditions JSONB column
- Backend: Dynamic WHERE clause building from JSON filters
- Supports single value: {"training_type": "strength"}
- Supports multiple values: {"training_type": ["strength", "hiit"]}
- Works with all 8 aggregation methods (count, avg, sum, min, max)
- Frontend: JSON textarea with example + validation
- Pydantic models: filter_conditions field added

Technical details:
- SQL injection safe (parameterized queries)
- Graceful degradation (invalid JSON ignored with warning)
- Backward compatible (NULL filters = no filtering)

Answers user question: 'Kann ich Trainingstypen wie Krafttraining separat zählen?'
Answer: YES! 🎯
2026-03-27 08:14:22 +01:00
1f4ee5021e fix: robust error handling in goal value fetcher
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 13s
Prevents crashes when:
- Goal types have NULL source_table/column (lean_mass, inactive placeholders)
- Old goals reference inactive goal types
- SQL queries fail for any reason

Changes:
- Guard clause checks table/column before SQL
- try-catch wraps all aggregation queries
- Returns None gracefully instead of crashing endpoint
- Logs warnings for debugging

Fixes: Goals page not loading due to /api/goals/list crash
2026-03-27 07:55:19 +01:00
65ee5f898f feat: Phase 1.5 - Flexible Goal System (DB-Registry) Part 1/2
All checks were successful
Deploy Development / deploy (push) Successful in 43s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 13s
KRITISCHE ARCHITEKTUR-ÄNDERUNG vor Phase 0b:
Ermöglicht dynamische Goal Types ohne Code-Änderungen.

Backend:
- Migration 024: goal_type_definitions Tabelle
  → 8 existierende Typen als Seed-Data migriert
  → Flexible Schema: source_table, aggregation_method, calculation_formula
  → System vs. Custom Types (is_system flag)
- goal_utils.py: Universal Value Fetcher
  → get_current_value_for_goal() ersetzt hardcoded if/elif chain
  → Unterstützt: latest, avg_7d, avg_30d, sum_30d, count_7d, etc.
  → Komplexe Formeln (lean_mass) via calculation_formula JSON
- goals.py: CRUD API für Goal Type Definitions
  → GET /goals/goal-types (public)
  → POST/PUT/DELETE /goals/goal-types (admin-only)
  → Schutz für System-Types (nicht löschbar)
- goals.py: _get_current_value_for_goal_type() delegiert zu Universal Fetcher

Frontend:
- api.js: 4 neue Funktionen (listGoalTypeDefinitions, create, update, delete)

Dokumentation:
- TODO_GOAL_SYSTEM.md: Phase 1.5 hinzugefügt, Roadmap aktualisiert

Part 2/2 (nächster Commit):
- Frontend: Dynamic Goal Types Dropdown
- Admin UI: Goal Type Management Page
- Testing

Warum JETZT (vor Phase 0b)?
- Phase 0b Platzhalter (120+) nutzen Goals für Score-Berechnungen
- Flexible Goals → automatisch in Platzhaltern verfügbar
- Später umbauen = Doppelarbeit (alle Platzhalter anpassen)

Zukünftige Custom Goals möglich:
- 🧘 Meditation (min/Tag)
- 📅 Trainingshäufigkeit (x/Woche)
- 📊 Planabweichung (%)
- 🎯 Ritual-Adherence (%)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 06:45:05 +01:00
87464ff138 fix: Phase 1 - Goal System Quick Fixes + Abstraction Layer
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
Behebt 4 kritische Bugs in Phase 0a und schafft Basis für Phase 0b
ohne spätere Doppelarbeit.

Backend:
- NEW: goal_utils.py mit get_focus_weights() Abstraction Layer
  → V1: Mappt goal_mode zu Gewichten
  → V2 (später): Liest aus focus_areas Tabelle
  → Phase 0b Platzhalter (120+) müssen NICHT umgeschrieben werden
- FIX: Primary goal toggle in goals.py (is_primary im GoalUpdate Model)
  → Beim Update auf primary werden andere Goals korrekt auf false gesetzt
- FIX: lean_mass current_value Berechnung implementiert
  → weight - (weight * body_fat_pct / 100)
- FIX: VO2Max Spaltenname vo2_max (statt vo2max)
  → Internal Server Error behoben

CLAUDE.md:
- Version Update: Phase 1 Fixes (27.03.2026)

Keine Doppelarbeit:
- Alle zukünftigen Phase 0b Platzhalter nutzen get_focus_weights()
- v2.0 Redesign = nur eine Funktion ändern, nicht 120+ Platzhalter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 06:13:47 +01:00