package api import ( "encoding/json" "geniusrun/backend/internal/store" ) // activityResponse adds back ActivityName/ActivityType as fields decoded // from RawJSON. They're no longer stored as their own columns (Phase 2 of // the 2026-07 duplication cleanup -- see store.Activity's doc comment): // Garmin's raw JSON is the only place they live now, decoded fresh for each // API response instead of kept as a redundant copy in the database. type activityResponse struct { store.Activity ActivityName string `json:"ActivityName"` ActivityType string `json:"ActivityType"` } func toActivityResponse(a store.Activity) activityResponse { name, typeKey := decodeActivityDisplayFields(a.RawJSON) return activityResponse{Activity: a, ActivityName: name, ActivityType: typeKey} } type rawActivityDisplayFields struct { ActivityName string `json:"activityName"` ActivityType struct { TypeKey string `json:"typeKey"` } `json:"activityType"` } func decodeActivityDisplayFields(rawJSON string) (name, typeKey string) { var f rawActivityDisplayFields _ = json.Unmarshal([]byte(rawJSON), &f) // best-effort -- zero values are fine if rawJSON is empty/malformed return f.ActivityName, f.ActivityType.TypeKey } // lapResponse adds back DurationSeconds/AvgHR as fields decoded from // RawJSON, same rationale as activityResponse -- the frontend chart still // needs them (x-axis timing, dashed average-HR line) even though nothing on // the backend does. type lapResponse struct { store.Lap DurationSeconds float64 `json:"DurationSeconds"` AvgHR *float64 `json:"AvgHR"` } func toLapResponse(l store.Lap) lapResponse { duration, avgHR := decodeLapDisplayFields(l.RawJSON) return lapResponse{Lap: l, DurationSeconds: duration, AvgHR: avgHR} } func toLapResponses(laps []store.Lap) []lapResponse { out := make([]lapResponse, len(laps)) for i, l := range laps { out[i] = toLapResponse(l) } return out } type rawLapDisplayFields struct { Duration float64 `json:"duration"` AverageHR float64 `json:"averageHR"` } func decodeLapDisplayFields(rawJSON string) (durationSeconds float64, avgHR *float64) { var f rawLapDisplayFields _ = json.Unmarshal([]byte(rawJSON), &f) durationSeconds = f.Duration if f.AverageHR > 0 { v := f.AverageHR avgHR = &v } return }