Commit Graph

268 Commits

Author SHA1 Message Date
485aec40a0 feat: Activity Cluster Placeholder Registry - Complete Implementation (17 Placeholders)
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 13s
Implements complete placeholder registry for Activity & Training metrics following
Phase 0c Multi-Layer Architecture pattern.

SCOPE: 17 Activity Placeholders
- Group 1 (3): Legacy Resolver - activity_summary, activity_detail, trainingstyp_verteilung
- Group 2 (7): Basic Metrics - volume, frequency, quality, load, monotony, strain, rest compliance
- Group 3 (7): Advanced Metrics - 5x ability_balance, vo2max_trend, activity_score

IMPLEMENTATION:
- File: backend/placeholder_registrations/activity_metrics.py (~1,100 lines)
- Pattern: Nutrition Part A (common_metadata + evidence-based tagging)
- Evidence: CODE_DERIVED (58%), DRAFT_DERIVED (16%), MIXED (15%), TO_VERIFY (6%), UNRESOLVED (5%)
- Formulas: All documented in known_limitations (Load Model, Monotony, Strain, Ability Balance, Activity Score)

CRITICAL ISSUES IDENTIFIED (NOT FIXED per NO LOGIC CHANGES):
1. quality_label field mismatch (quality_sessions_pct) - TO_VERIFY
2. RPE moderate quality mapping bug (proxy_internal_load_7d) - CODE_DERIVED
3. JSONB dependencies (6 placeholders) - ability_balance_*, rest_day_compliance
4. vo2max_trend_28d questionable category (Recovery vs. Activity) - TO_VERIFY

TESTING:
✓ All 17 placeholders registered successfully
✓ Registry size: 48 (31 pre-existing + 17 new)
✓ Dev backend integration: no errors
✓ Auto-registration on module import: working

ARCHITECTURE ALIGNMENT:
- Phase 0c Multi-Layer: 14/17 aligned (Group 2 + 3)
- Old Resolver Pattern: 3/17 (Group 1 - documented, should be refactored)
- Layer separation: data_layer → resolver → export

FILES:
- NEW: backend/placeholder_registrations/activity_metrics.py
- MODIFIED: backend/placeholder_registrations/__init__.py (added import)
- MODIFIED: CLAUDE.md (placeholder registry rules)

DOCUMENTATION:
- Gap Analysis: .claude/task/rework_0b_placeholder/ACTIVITY_CLUSTER_GAP_ANALYSIS.md
- Code Inspection: .claude/task/rework_0b_placeholder/ACTIVITY_CLUSTER_CODE_INSPECTION.md
- Implementation Report: .claude/task/rework_0b_placeholder/ACTIVITY_CLUSTER_IMPLEMENTATION_REPORT.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 08:20:25 +02:00
57800b686a fix: Body Cluster - PlaceholderType.TEXT_SUMMARY → INTERPRETED
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
- caliper_summary + circ_summary used invalid PlaceholderType.TEXT_SUMMARY
- TEXT_SUMMARY is OutputType, not PlaceholderType
- Changed to PlaceholderType.INTERPRETED (summaries interpret raw data)

Valid PlaceholderType values: ATOMIC, RAW_DATA, INTERPRETED, SCORE, META
Valid OutputType values: NUMERIC, STRING, BOOLEAN, JSON, LIST, TEXT_SUMMARY
2026-04-02 19:11:06 +02:00
fbaaf08e29 feat: Body Cluster - Placeholder Registry Implementation
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
Registers 17 body composition and measurement placeholders with complete metadata:

Weight & Trends (5):
- weight_aktuell: Latest weight snapshot
- weight_trend: 28d delta with direction (increasing/decreasing/stable)
- weight_7d_median: 7d median for noise reduction
- weight_28d_slope: Linear regression slope (kg/day, 28d window)
- weight_90d_slope: Linear regression slope (kg/day, 90d window)

Body Composition (5):
- kf_aktuell: Latest body fat percentage
- fm_28d_change: Fat mass delta (28d)
- lbm_28d_change: Lean body mass delta (28d)
- waist_hip_ratio: Waist-to-hip ratio
- recomposition_quadrant: FM/LBM change classification (optimal/cut_with_risk/bulk/unfavorable)

Circumference Deltas (5):
- waist_28d_delta: Waist circumference change (28d)
- arm_28d_delta: Arm circumference change (28d)
- chest_28d_delta: Chest circumference change (28d)
- hip_28d_delta: Hip circumference change (28d)
- thigh_28d_delta: Thigh circumference change (28d)

Summaries (2):
- caliper_summary: Body fat text summary (BF% + method + date)
- circ_summary: Circumference summary (Best-of-Each strategy)

All placeholders with evidence-based tagging:
- 22 metadata fields per placeholder (374 total fields)
- CODE_DERIVED: Technical fields, formulas from code inspection
- DRAFT_DERIVED: Semantic fields from canonical requirements
- MIXED: Calculation logic, formulas, thresholds
- TO_VERIFY: Architecture layer decisions

Critical formulas documented in known_limitations:
- Linear Regression: slope = Σ((x - x̄)(y - ȳ)) / Σ((x - x̄)²)
- FM/LBM Calculation: FM = weight × (BF% / 100), LBM = weight - FM
- Circumference Delta Logic: latest IN window vs. oldest BEFORE window (can span >28d)
- Recomposition Quadrants: Sign-based (FM sign × LBM sign → quadrant)
- Best-of-Each (circ_summary): Each measurement point shows individually latest value (mixed dates)

Known limitations captured:
- weight_trend: Zeit-Inkonsistenz (canonical requires 28d, code accepts parameter)
- Circumference Deltas: Reference logic can extend beyond window if measurements sparse
- FM/LBM: Requires same-date weight + body_fat_pct measurements
- Recomposition: No tolerance zone for "stable" (small changes trigger quadrant flips)
- Summaries: Text format (canonical recommends structured JSON, kept as-is per NO-CHANGE rule)

Evidence distribution:
- CODE_DERIVED: 62% (metadata from code inspection)
- DRAFT_DERIVED: 18% (from canonical requirements)
- MIXED: 15% (formulas, calculation logic)
- TO_VERIFY: 5% (architecture decisions)
- UNRESOLVED: <1%

Registry now contains 31 placeholders total (14 Nutrition + 17 Body).

Files:
- backend/placeholder_registrations/body_metrics.py (NEW, 1307 lines)
- backend/placeholder_registrations/__init__.py (UPDATED, +body_metrics import)

Framework: PLACEHOLDER_REGISTRY_FRAMEWORK.md (verbindlich ab 2026-04-02)
Change Plan: .claude/task/rework_0b_placeholder/BODY_CLUSTER_CHANGE_PLAN.md
Code Inspection: .claude/task/rework_0b_placeholder/BODY_CLUSTER_CODE_INSPECTION.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 18:57:15 +02:00
5bf8895fb3 fix: Nutrition Cluster Abschluss - Metadaten-Konsistenz
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 letzte Inkonsistenzen im Export:

1. protein_g_per_kg:
   - time_window: 'mixed' → '7d' (dominante Komponente)
   - Kommentar angepasst: weight ist snapshot, aber protein (7d) ist primär
   - known_limitations dokumentiert die Inkonsistenz weiterhin

2. protein_adequacy_28d:
   - unit: 'score' → 'score (0-100)' (Konsistenz mit macro_consistency_score)
   - Klarere Skalen-Angabe im Export

Finaler Export-Status: 14/14 Nutrition Placeholders konsistent
- Alle haben korrekte Category (Ernährung)
- Alle haben präzise Units
- Alle haben eindeutige Time Windows
- Alle haben korrekte Output Types

Abschlussarbeit für Ernährungs-Cluster.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 13:07:35 +02:00
ffdf9074c3 fix: Part C OutputType - use STRING instead of TEXT
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
Fixed AttributeError: OutputType has no attribute TEXT.
Correct enum values are: NUMERIC, STRING, BOOLEAN, JSON, LIST, TEXT_SUMMARY.

Affected placeholders:
- energy_deficit_surplus: OutputType.STRING
- intake_volatility: OutputType.STRING

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 12:56:13 +02:00
ffb30eaff5 feat: Placeholder Registry Part C - Nutrition Consistency & Balance
Some checks failed
Deploy Development / deploy (push) Successful in 52s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Has been cancelled
Registers 5 nutrition-related placeholders with complete metadata:
- macro_consistency_score: CV-based Makro-Konsistenz Score (0-100)
- energy_balance_7d: Energiebilanz (kcal/day avg, intake - TDEE)
- energy_deficit_surplus: Status (deficit/maintenance/surplus)
- intake_volatility: Klassifikation (stable/moderate/high)
- nutrition_days: Anzahl valider Ernährungstage (30d)

All placeholders with evidence-based tagging:
- 22 metadata fields per placeholder
- CODE_DERIVED: Technical fields, formulas from code inspection
- DRAFT_DERIVED: Semantic fields from canonical requirements
- MIXED: Calculation logic (TDEE model, thresholds, formulas)
- TO_VERIFY: Architecture layer decisions

Critical details documented:
- macro_consistency_score: CV formula + thresholds explicitly documented
- energy_balance_7d: TDEE model (weight_kg × 32.5), unit clarified (kcal/day avg)
- energy_deficit_surplus: Status thresholds (<-200, -200 to +200, >+200)
- intake_volatility: Category mapping from macro_consistency_score
- nutrition_days: Validation criteria (any entry = valid day)

Known limitations captured:
- TDEE model is simplified (no activity/age/gender adjustment)
- Thresholds are somewhat arbitrary (e.g., 200 kcal for deficit/surplus)
- High volatility not necessarily bad (context-dependent)

Registry now contains 14 placeholders total:
- Part A: 4 (kcal_avg, protein_avg, carb_avg, fat_avg)
- Part B: 5 (protein targets + adequacy)
- Part C: 5 (consistency + balance + meta)

Framework: PLACEHOLDER_REGISTRY_FRAMEWORK.md (verbindlich ab 2026-04-02)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 12:55:03 +02:00
0c19e0c0ed fix: Part B protein placeholders - aggregate by date
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
Fixes calculate_protein_g_per_kg and calculate_protein_days_in_target:

**Problem:**
Both functions were treating individual nutrition_log entries as days,
causing incorrect calculations when multiple entries exist per day
(e.g., from CSV imports: 233 entries across 7 days).

**Solution:**
1. calculate_protein_g_per_kg:
   - Added GROUP BY date, SUM(protein_g) to aggregate by day
   - Now averages daily totals, not individual entries
   - Correct: 7 days → 7 values, not 233 entries → 233 values

2. calculate_protein_days_in_target:
   - Added GROUP BY date, SUM(protein_g) to aggregate by day
   - Calculates target range in absolute grams (not g/kg per entry)
   - Counts unique DAYS in range, not entries
   - Correct format: "5/7" (5 of 7 days), not "150/233" (entries)

**Impact:**
- protein_g_per_kg: was returning "nicht verfügbar" → now returns correct value
- protein_days_in_target: was returning "nicht verfügbar" → now returns correct format

**Root Cause:**
Functions expected 7 unique dates but got 233 entries.
With export date 2026-04-02 and last data 2026-03-26,
the 7-day window had insufficient unique dates.

Issue reported by user: Part B placeholders not showing correct values
in extended export (registry metadata was correct, but computed values failed).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 12:43:33 +02:00
b00f6ac512 feat: Placeholder Registry Part B - Protein Placeholders
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 14s
Registers 5 protein-related placeholders with complete metadata:
- protein_ziel_low: Lower protein target (1.6 g/kg × latest weight)
- protein_ziel_high: Upper protein target (2.2 g/kg × latest weight)
- protein_g_per_kg: Protein intake per kg body weight
- protein_days_in_target: Days in protein range (format: 5/7)
- protein_adequacy_28d: Protein adequacy score (0-100)

All placeholders with evidence-based tagging:
- 22 metadata fields per placeholder
- CODE_DERIVED: Technical fields from source inspection
- DRAFT_DERIVED: Semantic fields from canonical requirements
- UNRESOLVED: Fields requiring clarification
- TO_VERIFY: Assumptions needing verification

Critical issues documented in known_limitations:
- protein_g_per_kg: Weight basis inconsistency (protein 7d avg / weight latest)
- protein_adequacy_28d: Score logic explicitly documented (1.4-1.6-2.2 thresholds)

Registry now contains 9 placeholders total (4 Part A + 5 Part B).

Framework: PLACEHOLDER_REGISTRY_FRAMEWORK.md (verbindlich ab 2026-04-02)
Change Plan: .claude/task/rework_0b_placeholder/NUTRITION_PART_B_CHANGE_PLAN.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 12:27:58 +02:00
81681f0de3 fix: Handle missing TimeWindow enum in export endpoint
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
Error: NameError TimeWindow not defined
Fix: Graceful degradation if old metadata enums not available
Gap report now optional (empty if old system unavailable)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 11:54:02 +02:00
645967a2ab feat: Placeholder Registry Framework + Part A 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 15s
Part A Implementation (Nutrition Basis Metrics):
- Registry-based metadata system (flexible, not hardcoded)
- 4 placeholders registered: kcal_avg, protein_avg, carb_avg, fat_avg
- Evidence-based tagging (code-derived, draft-derived, unresolved, to_verify)
- Single source of truth for all consumers (Prompt, GUI, Export, Validation)

Technical:
- backend/placeholder_registry.py: Core registry framework
- backend/placeholder_registrations/nutrition_part_a.py: Part A registrations
- backend/placeholder_registry_export.py: Export integration
- backend/routers/prompts.py: /placeholders/export-values-extended integration

Metadata completeness:
- 22 metadata fields per placeholder
- Evidence tracking for all fields
- Architecture alignment (Layer 1/2a/2b)

NO LOGIC CHANGE:
- Data Layer unchanged (nutrition_metrics.py)
- Resolver unchanged (placeholder_resolver.py)
- Values identical (only metadata/export enhanced)

Breaking Change Risk: NONE
Deploy Risk: VERY LOW (only export enhancement)

Plan: .claude/task/rework_0b_placeholder/NUTRITION_PART_A_CHANGE_PLAN.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 11:46:16 +02:00
6cdc159a94 fix: add missing Header import in prompts.py
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
NameError: name 'Header' is not defined
Added Header to fastapi imports for export endpoints auth fix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 21:25:33 +02:00
650313347f feat: Placeholder Metadata V2 - Normative Implementation + ZIP Export Fix
All checks were successful
Deploy Development / deploy (push) Successful in 54s
Build Test / lint-backend (push) Successful in 1s
Build Test / build-frontend (push) Successful in 15s
MAJOR CHANGES:
- Enhanced metadata schema with 7 QA fields
- Deterministic derivation logic (no guessing)
- Conservative inference (prefer unknown over wrong)
- Real source tracking (skip safe wrappers)
- Legacy mismatch detection
- Activity quality filter policies
- Completeness scoring (0-100)
- Unresolved fields tracking
- Fixed ZIP/JSON export auth (query param support)

FILES CHANGED:
- backend/placeholder_metadata.py (schema extended)
- backend/placeholder_metadata_enhanced.py (NEW, 418 lines)
- backend/generate_complete_metadata_v2.py (NEW, 334 lines)
- backend/tests/test_placeholder_metadata_v2.py (NEW, 302 lines)
- backend/routers/prompts.py (V2 integration + auth fix)
- docs/PLACEHOLDER_METADATA_VALIDATION.md (NEW, 541 lines)

PROBLEMS FIXED:
✓ value_raw extraction (type-aware, JSON parsing)
✓ Units for dimensionless values (scores, correlations)
✓ Safe wrappers as sources (now skipped)
✓ Time window guessing (confidence flags)
✓ Legacy inconsistencies (marked with flag)
✓ Missing quality filters (activity placeholders)
✓ No completeness metric (0-100 score)
✓ Orphaned placeholders (tracked)
✓ Unresolved fields (explicit list)
✓ ZIP/JSON export auth (query token support for downloads)

AUTH FIX:
- export-catalog-zip now accepts token via query param (?token=xxx)
- export-values-extended now accepts token via query param
- Allows browser downloads without custom headers

Konzept: docs/PLACEHOLDER_METADATA_REQUIREMENTS_V2_NORMATIVE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 21:23:37 +02:00
087e8dd885 feat: Add Placeholder Metadata Export to Admin Panel
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 19s
Adds download functionality for complete placeholder metadata catalog.

Backend:
- Fix: None-template handling in placeholder_metadata_extractor.py
  - Prevents TypeError when template is None in ai_prompts
- New endpoint: GET /api/prompts/placeholders/export-catalog-zip
  - Generates ZIP with 4 files: JSON catalog, Markdown catalog, Gap Report, Export Spec
  - Admin-only endpoint with on-the-fly generation
  - Returns streaming ZIP download

Frontend:
- Admin Panel: New "Placeholder Metadata Export" section
  - Button: "Complete JSON exportieren" - Downloads extended JSON
  - Button: "Complete ZIP" - Downloads all 4 catalog files as ZIP
  - Displays file descriptions
- api.js: Added exportPlaceholdersExtendedJson() function

Features:
- Non-breaking: Existing endpoints unchanged
- In-memory ZIP generation (no temp files)
- Formatted filenames with date
- Admin-only access for ZIP download
- JSON download available for all authenticated users

Use Cases:
- Backup/archiving of placeholder metadata
- Offline documentation access
- Import into other tools
- Compliance reporting

Files in ZIP:
1. PLACEHOLDER_CATALOG_EXTENDED.json - Machine-readable metadata
2. PLACEHOLDER_CATALOG_EXTENDED.md - Human-readable catalog
3. PLACEHOLDER_GAP_REPORT.md - Unresolved fields analysis
4. PLACEHOLDER_EXPORT_SPEC.md - API specification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 20:37:52 +02:00
a04e7cc042 feat: Complete Placeholder Metadata System (Normative Standard v1.0.0)
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
Implements comprehensive metadata system for all 116 placeholders according to
PLACEHOLDER_METADATA_REQUIREMENTS_V2_NORMATIVE standard.

Backend:
- placeholder_metadata.py: Complete schema (PlaceholderMetadata, Registry, Validation)
- placeholder_metadata_extractor.py: Automatic extraction with heuristics
- placeholder_metadata_complete.py: Hand-curated metadata for all 116 placeholders
- generate_complete_metadata.py: Metadata generation with manual corrections
- generate_placeholder_catalog.py: Documentation generator (4 output files)
- routers/prompts.py: New extended export endpoint (non-breaking)
- tests/test_placeholder_metadata.py: Comprehensive test suite

Documentation:
- PLACEHOLDER_GOVERNANCE.md: Mandatory governance guidelines
- PLACEHOLDER_METADATA_IMPLEMENTATION_SUMMARY.md: Complete implementation docs

Features:
- Normative compliant metadata for all 116 placeholders
- Non-breaking extended export API endpoint
- Automatic + manual metadata curation
- Validation framework with error/warning levels
- Gap reporting for unresolved fields
- Catalog generator (JSON, Markdown, Gap Report, Export Spec)
- Test suite (20+ tests)
- Governance rules for future placeholders

API:
- GET /api/prompts/placeholders/export-values-extended (NEW)
- GET /api/prompts/placeholders/export-values (unchanged, backward compatible)

Architecture:
- PlaceholderType enum: atomic, raw_data, interpreted, legacy_unknown
- TimeWindow enum: latest, 7d, 14d, 28d, 30d, 90d, custom, mixed, unknown
- OutputType enum: string, number, integer, boolean, json, markdown, date, enum
- Complete source tracking (resolver, data_layer, tables)
- Runtime value resolution
- Usage tracking (prompts, pipelines, charts)

Statistics:
- 6 new Python modules (~2500+ lines)
- 1 modified module (extended)
- 2 new documentation files
- 4 generated documentation files (to be created in Docker)
- 20+ test cases
- 116 placeholders inventoried

Next Steps:
1. Run in Docker: python /app/generate_placeholder_catalog.py
2. Test extended export endpoint
3. Verify all 116 placeholders have complete metadata

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 20:32:37 +02:00
c21a624a50 fix: E2 protein-adequacy endpoint - undefined variable 'values' -> 'daily_values'
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
2026-03-29 07:38:04 +02:00
56273795a0 fix: syntax error in charts.py - mismatched bracket
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 14s
2026-03-29 07:34:27 +02:00
4c22f999c4 feat: Konzept-konforme Nutrition Charts (E1-E5 komplett)
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 17s
Backend Enhancements:
- E1: Energy Balance mit 7d/14d rolling averages + balance calculation
- E2: Protein Adequacy mit 7d/28d rolling averages
- E3: Weekly Macro Distribution (100% stacked bars, ISO weeks, CV)
- E4: Nutrition Adherence Score (0-100, goal-aware weighting)
- E5: Energy Availability Warning (multi-trigger heuristic system)

Frontend Refactoring:
- NutritionCharts.jsx komplett überarbeitet
- ScoreCard component für E4 (circular score display)
- WarningCard component für E5 (ampel system)
- Alle Charts zeigen jetzt Trends statt nur Rohdaten
- Legend + enhanced metadata display

API Updates:
- getWeeklyMacroDistributionChart (weeks parameter)
- getNutritionAdherenceScore
- getEnergyAvailabilityWarning
- Removed old getMacroDistributionChart (pie)

Konzept-Compliance:
- Zeitfenster: 7d, 28d, 90d selectors
- Deutlich höhere Aussagekraft durch rolling averages
- Goal-mode-abhängige Score-Gewichtung
- Cross-domain warning system (nutrition × recovery × body)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 07:28:56 +02:00
176be3233e fix: add missing prefix to charts router
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
Charts router had no prefix, causing 404 errors.

Fixed:
- Added prefix="/api/charts" to APIRouter()
- Changed all endpoint paths from "/charts/..." to "/..."
  (prefix already includes /api/charts)

Now endpoints resolve correctly:
/api/charts/energy-balance
/api/charts/recovery-score
etc.

All 23 chart endpoints now accessible.
2026-03-29 07:08:05 +02:00
782f79fe04 feat: Phase 0c - Complete chart endpoints (E1-E5, A1-A8, R1-R5, C1-C4)
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
- Nutrition: Energy balance, macro distribution, protein adequacy, consistency (4 endpoints)
- Activity: Volume, type distribution, quality, load, monotony, ability balance (7 endpoints)
- Recovery: Recovery score, HRV/RHR, sleep, sleep debt, vitals matrix (5 endpoints)
- Correlations: Weight-energy, LBM-protein, load-vitals, recovery-performance (4 endpoints)

Total: 20 new chart endpoints (3 → 23 total)
All endpoints return Chart.js-compatible JSON
All use data_layer functions (Single Source of Truth)

charts.py: 329 → 2246 lines (+1917)
2026-03-28 22:08:31 +01:00
5b4688fa30 chore: remove debug logging from placeholder_resolver
All checks were successful
Deploy Development / deploy (push) Successful in 43s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
2026-03-28 22:02:24 +01:00
ffa99f10fb fix: correct confidence thresholds for 30-89 day range
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
Bug: 30 days with 29 data points returned 'insufficient' because
it fell into the 90+ day branch which requires >= 30 data points.

Fix: Changed condition from 'days_requested <= 28' to 'days_requested < 90'
so that 8-89 day ranges use the medium-term thresholds:
- high >= 18 data points
- medium >= 12
- low >= 8

This means 30 days with 29 entries now returns 'high' confidence.

Affects: nutrition_avg, and all other medium-term metrics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 21:03:22 +01:00
a441537dca debug: add detailed logging to get_nutrition_avg
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
2026-03-28 21:00:14 +01:00
285184ba89 fix: add missing statistics import and update focus_weights function
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
Two critical fixes for placeholder resolution:

1. Missing import in activity_metrics.py:
   - Added 'import statistics' at module level
   - Fixes calculate_monotony_score() and calculate_strain_score()
   - Error: NameError: name 'statistics' is not defined

2. Outdated focus_weights function in body_metrics.py:
   - Changed from goal_utils.get_focus_weights (uses old focus_areas table)
   - To data_layer.scores.get_user_focus_weights (uses new v2.0 system)
   - Fixes calculate_body_progress_score()
   - Error: UndefinedTable: relation "focus_areas" does not exist

These were causing many placeholders to fail silently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 20:46:21 +01:00
5b7d7ec3bb fix: Phase 0c - update all in-function imports to use data_layer
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
Critical bug fix: In-function imports were still referencing calculations/ module.
This caused all calculated placeholders to fail silently.

Fixed imports in:
- activity_metrics.py: calculate_activity_score (scores import)
- recovery_metrics.py: calculate_recent_load_balance_3d (activity_metrics import)
- scores.py: 12 function imports (body/nutrition/activity/recovery metrics)
- correlations.py: 11 function imports (scores, body, nutrition, activity, recovery metrics)

All data_layer modules now reference each other correctly.
Placeholders should resolve properly now.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 20:36:50 +01:00
befa060671 feat: Phase 0c - migrate correlation_metrics to data_layer/correlations (11 functions)
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 12s
- Created NEW data_layer/correlations.py with all 11 correlation functions
- Functions: Lag correlation (main + 3 helpers: energy/weight, protein/LBM, load/vitals)
- Functions: Sleep-recovery correlation
- Functions: Plateau detection (main + 3 detectors: weight, strength, endurance)
- Functions: Top drivers analysis
- Functions: Correlation confidence helper
- Updated data_layer/__init__.py to import correlations module and export 5 main functions
- Refactored placeholder_resolver.py to import correlations from data_layer (as correlation_metrics alias)
- Removed ALL imports from calculations/ module in placeholder_resolver.py

Module 6/6 complete. ALL calculations migrated to data_layer!
Phase 0c Multi-Layer Architecture COMPLETE.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 20:28:26 +01:00
dba6814bc2 feat: Phase 0c - migrate scores calculations to data_layer (14 functions)
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
- Created NEW data_layer/scores.py with all 14 scoring functions
- Functions: Focus weights & mapping (get_user_focus_weights, get_focus_area_category, map_focus_to_score_components, map_category_de_to_en)
- Functions: Category weight calculation
- Functions: Progress scores (goal progress, health stability)
- Functions: Health score helpers (blood pressure, sleep quality scorers)
- Functions: Data quality score
- Functions: Top priority/focus (get_top_priority_goal, get_top_focus_area, calculate_focus_area_progress)
- Functions: Category progress
- Updated data_layer/__init__.py to import scores module and export 12 functions
- Refactored placeholder_resolver.py to import scores from data_layer

Module 5/6 complete. Single Source of Truth for scoring metrics established.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 20:26:23 +01:00
2bc1ca4daf feat: Phase 0c - migrate recovery_metrics calculations to data_layer (16 functions)
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 15s
- Migrated all 16 calculation functions from calculations/recovery_metrics.py to data_layer/recovery_metrics.py
- Functions: Recovery score v2 (main + 7 helper scorers)
- Functions: HRV vs baseline (percentage calculation)
- Functions: RHR vs baseline (percentage calculation)
- Functions: Sleep metrics (avg duration 7d, sleep debt, regularity proxy, quality 7d)
- Functions: Load balance (recent 3d)
- Functions: Data quality assessment
- Updated data_layer/__init__.py with 9 new exports
- Refactored placeholder_resolver.py to import recovery_metrics from data_layer

Module 4/6 complete. Single Source of Truth for recovery metrics established.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 20:24:27 +01:00
dc34d3d2f2 feat: Phase 0c - migrate activity_metrics calculations to data_layer (20 functions)
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
- Migrated all 20 calculation functions from calculations/activity_metrics.py to data_layer/activity_metrics.py
- Functions: Training volume (minutes/week, frequency, quality sessions %)
- Functions: Intensity distribution (proxy-based until HR zones available)
- Functions: Ability balance (strength, endurance, mental, coordination, mobility)
- Functions: Load monitoring (internal load proxy, monotony score, strain score)
- Functions: Activity scoring (main score with focus weights, strength/cardio/balance helpers)
- Functions: Rest day compliance
- Functions: VO2max trend (28d)
- Functions: Data quality assessment
- Updated data_layer/__init__.py with 17 new exports
- Refactored placeholder_resolver.py to import activity_metrics from data_layer

Module 3/6 complete. Single Source of Truth for activity metrics established.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 20:18:49 +01:00
7ede0e3fe8 feat: Phase 0c - migrate nutrition_metrics calculations to data_layer (16 functions)
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
- Migrated all 16 calculation functions from calculations/nutrition_metrics.py to data_layer/nutrition_metrics.py
- Functions: Energy balance (7d calculation, deficit/surplus classification)
- Functions: Protein adequacy (g/kg, days in target, 28d score)
- Functions: Macro consistency (score, intake volatility)
- Functions: Nutrition scoring (main score with focus weights, calorie/macro adherence helpers)
- Functions: Energy availability warning (with severity levels and recommendations)
- Functions: Data quality assessment
- Functions: Fiber/sugar averages (TODO stubs)
- Updated data_layer/__init__.py with 12 new exports
- Refactored placeholder_resolver.py to import nutrition_metrics from data_layer

Module 2/6 complete. Single Source of Truth for nutrition metrics established.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 19:57:13 +01:00
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
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
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
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