From c11dd152ba9e28063b41dda3864f4decd01223b9 Mon Sep 17 00:00:00 2001 From: Christophe Vila Date: Fri, 17 Jul 2026 19:13:24 +0200 Subject: [PATCH] feat: classification reads max HR from the profile instead of static config Co-Authored-By: Claude Sonnet 5 --- backend/internal/sync/service.go | 12 +++++++++--- backend/internal/sync/service_test.go | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/internal/sync/service.go b/backend/internal/sync/service.go index 7807f0b..0d4b453 100644 --- a/backend/internal/sync/service.go +++ b/backend/internal/sync/service.go @@ -35,8 +35,6 @@ type Config struct { // MinConfidence is the classify.Classify threshold below which even a // single matching kind is sent to manual review. MinConfidence float64 - // MaxHR is used only to derive avg_hr_pct_max for the rule engine. - MaxHR float64 } func (c Config) withDefaults() Config { @@ -296,8 +294,16 @@ func (s *Service) ClassifyActivity(ctx context.Context, activityID int64) error if err != nil { return fmt.Errorf("parse workout kind rules: %w", err) } + profile, err := s.db.GetProfile(ctx) + if err != nil { + return fmt.Errorf("load profile: %w", err) + } + var maxHR float64 + if profile.MaxHeartRate != nil { + maxHR = *profile.MaxHeartRate + } - ctxMetrics := buildMetricContext(activity, laps, s.cfg.MaxHR) + ctxMetrics := buildMetricContext(activity, laps, maxHR) result := classify.Classify(ctxMetrics, rules, s.cfg.MinConfidence) candidatesJSON, err := json.Marshal(result.Candidates) diff --git a/backend/internal/sync/service_test.go b/backend/internal/sync/service_test.go index 93cb9c7..9888803 100644 --- a/backend/internal/sync/service_test.go +++ b/backend/internal/sync/service_test.go @@ -87,7 +87,7 @@ func TestFillPendingDetailsAndClassify_EndToEnd(t *testing.T) { }, }, } - svc := NewService(m, db, Config{MinConfidence: 0.5, MaxHR: 190}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC))) + svc := NewService(m, db, Config{MinConfidence: 0.5}, fixedNow(time.Date(2026, 7, 11, 0, 0, 0, 0, time.UTC))) if err := svc.Backfill(ctx); err != nil { t.Fatalf("Backfill: %v", err)