fix: update seedsample for the fixed workout taxonomy and profile-based max HR

Update workout kinds by fixed name (via ListWorkoutKinds/UpdateWorkoutKind)
instead of creating new ones, since the taxonomy migration now seeds
Easy Run/Tempo/Interval by unique name. Set profile.MaxHeartRate so
avg_hr_pct_max is computed during classification, and drop the removed
appsync.Config.MaxHR field.
This commit is contained in:
2026-07-17 19:29:02 +02:00
parent 17ebe3c665
commit 91b901ba60

View File

@@ -29,39 +29,49 @@ func main() {
}
defer db.Close()
// Easy and Tempo's pace/HR ranges deliberately overlap a little (330-340
// sec/km, 0.70-0.85 HR%max) so a run that lands in that overlap zone
// demonstrates the ambiguous-multi-match review path, not just a gap
// between disjoint ranges.
easyID, err := db.CreateWorkoutKind(ctx, store.WorkoutKind{
Name: "Easy", Description: "Easy conversational runs", Color: "#22c55e",
// Set a max heart rate on the profile so avg_hr_pct_max is computed
// during classification below (it's nil/unset by default).
profile, err := db.GetProfile(ctx)
must(err)
maxHR := 190.0
profile.MaxHeartRate = &maxHR
must(db.UpdateProfile(ctx, profile))
// Easy Run and Tempo's pace/HR ranges deliberately overlap a little
// (330-340 sec/km, 0.70-0.85 HR%max) so a run that lands in that overlap
// zone demonstrates the ambiguous-multi-match review path, not just a
// gap between disjoint ranges. The taxonomy migration already seeded
// these rows (by fixed name) -- update their rules in place rather than
// creating new ones, since names are unique.
easyID := mustFindKindID(ctx, db, "Easy Run")
must(db.UpdateWorkoutKind(ctx, store.WorkoutKind{
ID: easyID, Name: "Easy Run", Description: "Easy conversational runs", Color: "#22c55e",
RuleJSON: `{"match":"all","conditions":[
{"metric":"avg_pace_sec_per_km","op":"between","value":[330,420]},
{"metric":"avg_hr_pct_max","op":"<=","value":0.85}
]}`,
IsActive: true,
})
must(err)
}))
tempoID, err := db.CreateWorkoutKind(ctx, store.WorkoutKind{
Name: "Tempo", Description: "Comfortably hard sustained effort", Color: "#f59e0b",
tempoID := mustFindKindID(ctx, db, "Tempo")
must(db.UpdateWorkoutKind(ctx, store.WorkoutKind{
ID: tempoID, Name: "Tempo", Description: "Comfortably hard sustained effort", Color: "#f59e0b",
RuleJSON: `{"match":"all","conditions":[
{"metric":"avg_pace_sec_per_km","op":"between","value":[300,340]},
{"metric":"avg_hr_pct_max","op":">=","value":0.70}
]}`,
IsActive: true,
})
must(err)
}))
_, err = db.CreateWorkoutKind(ctx, store.WorkoutKind{
Name: "Interval", Description: "Structured work/rest intervals", Color: "#ef4444",
intervalID := mustFindKindID(ctx, db, "Interval")
must(db.UpdateWorkoutKind(ctx, store.WorkoutKind{
ID: intervalID, Name: "Interval", Description: "Structured work/rest intervals", Color: "#ef4444",
RuleJSON: `{"match":"all","conditions":[{"metric":"lap_interval_pattern","op":"==","value":true}]}`,
IsActive: true,
})
must(err)
}))
m := &mock.Client{}
svc := appsync.NewService(m, db, appsync.Config{MinConfidence: 0.6, MaxHR: 190}, nil)
svc := appsync.NewService(m, db, appsync.Config{MinConfidence: 0.6}, nil)
today := time.Now()
activityIDs := []int64{}
@@ -219,3 +229,15 @@ func must(err error) {
log.Fatal(err)
}
}
func mustFindKindID(ctx context.Context, db *store.DB, name string) int64 {
kinds, err := db.ListWorkoutKinds(ctx, false)
must(err)
for _, k := range kinds {
if k.Name == name {
return k.ID
}
}
log.Fatalf("seedsample: no workout kind named %q found (did migration 0004 run?)", name)
return 0
}