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:
@@ -83,6 +83,27 @@ func (db *DB) ReviewQueue(ctx context.Context) ([]KindAssignment, error) {
|
||||
return assignments, rows.Err()
|
||||
}
|
||||
|
||||
// AllCurrentAssignments returns the latest assignment for every activity
|
||||
// that has one, regardless of status or source -- the basis for deciding
|
||||
// which activities a global reclassify pass is allowed to touch.
|
||||
func (db *DB) AllCurrentAssignments(ctx context.Context) ([]KindAssignment, error) {
|
||||
rows, err := db.QueryContext(ctx, `SELECT `+kindAssignmentColumns+` FROM current_kind_assignment`)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("all current assignments: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
assignments := []KindAssignment{}
|
||||
for rows.Next() {
|
||||
a, err := scanKindAssignment(rows)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("scan kind assignment row: %w", err)
|
||||
}
|
||||
assignments = append(assignments, a)
|
||||
}
|
||||
return assignments, rows.Err()
|
||||
}
|
||||
|
||||
// AssignmentsForKind returns every historical assignment where the given
|
||||
// workout kind was the resolved kind (regardless of source), oldest first --
|
||||
// the basis for progression-over-time charts.
|
||||
|
||||
@@ -65,6 +65,19 @@ func (db *DB) GetWorkoutKind(ctx context.Context, id int64) (WorkoutKind, bool,
|
||||
return k, true, nil
|
||||
}
|
||||
|
||||
// GetWorkoutKindByName fetches one workout kind by its unique name.
|
||||
func (db *DB) GetWorkoutKindByName(ctx context.Context, name string) (WorkoutKind, bool, error) {
|
||||
row := db.QueryRowContext(ctx, `SELECT `+workoutKindColumns+` FROM workout_kinds WHERE name = ?`, name)
|
||||
k, err := scanWorkoutKind(row)
|
||||
if err == sql.ErrNoRows {
|
||||
return WorkoutKind{}, false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return WorkoutKind{}, false, fmt.Errorf("get workout kind %q: %w", name, err)
|
||||
}
|
||||
return k, true, nil
|
||||
}
|
||||
|
||||
// ListWorkoutKinds returns workout kinds. If activeOnly, soft-deleted
|
||||
// (is_active=0) kinds are excluded.
|
||||
func (db *DB) ListWorkoutKinds(ctx context.Context, activeOnly bool) ([]WorkoutKind, error) {
|
||||
|
||||
Reference in New Issue
Block a user