Replace per-kind reclassify with a single global reclassify that respects manual and Race locks
Manual assignments are the user's definitive word and Race assignments come from a hard Garmin fact (eventType.typeKey), not a retunable rule -- neither is ever touched by reclassify again, and Race can no longer be set by hand via the review queue. Adds an Activities page so this locked/unlocked status is visible per workout, since Review Queue only ever showed unresolved items.
This commit is contained in:
51
backend/internal/api/reclassify.go
Normal file
51
backend/internal/api/reclassify.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"smartrun/backend/internal/store"
|
||||
)
|
||||
|
||||
// handleReclassifyAll re-runs the rule engine for every activity except
|
||||
// those that are locked:
|
||||
// - a manual assignment is the user's definitive word and is never
|
||||
// overwritten by the rule engine again;
|
||||
// - an activity already assigned to Race is locked too, since that
|
||||
// classification comes from a hard Garmin fact (eventType.typeKey ==
|
||||
// "race"), not a rule the user might retune -- there's nothing to
|
||||
// re-derive.
|
||||
//
|
||||
// It's a synchronous, bounded operation (unlike sync), so it runs inline
|
||||
// rather than in the background.
|
||||
func (s *Server) handleReclassifyAll(w http.ResponseWriter, r *http.Request) {
|
||||
raceKind, hasRaceKind, err := s.DB.GetWorkoutKindByName(r.Context(), "Race")
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
assignments, err := s.DB.AllCurrentAssignments(r.Context())
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var activityIDs []int64
|
||||
for _, a := range assignments {
|
||||
if a.AssignmentSource == store.AssignmentSourceManual {
|
||||
continue
|
||||
}
|
||||
if hasRaceKind && a.WorkoutKindID != nil && *a.WorkoutKindID == raceKind.ID {
|
||||
continue
|
||||
}
|
||||
activityIDs = append(activityIDs, a.ActivityID)
|
||||
}
|
||||
|
||||
for _, activityID := range activityIDs {
|
||||
if err := s.Sync.ClassifyActivity(r.Context(), activityID); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]int{"reclassified": len(activityIDs)})
|
||||
}
|
||||
Reference in New Issue
Block a user