Add leaderboard for all tracks and track calendar

This commit is contained in:
2026-07-15 11:53:35 +04:00
parent 4a894a4399
commit a56841237d
20 changed files with 1394 additions and 25 deletions
@@ -118,3 +118,66 @@ func leaderboardEntryToWire(e races.LeaderboardEntry) transport.LeaderboardEntry
Rank: e.Rank,
}
}
// calendarLeaderboardHandler godoc
// @Summary Track Calendar Leaderboards
// @Description Returns the list of scheduled tracks with their status (finished/active/planned), top 3 drivers, and current driver position, sorted by calendar start date.
// @Tags leaderboard
// @Produce json
// @Param year query int false "Year. Defaults to current year."
// @Param X-Driver-Id header string false "Current driver ID. Defaults to driver-seed-001 (mock Alice)."
// @Success 200 {object} transport.TrackCalendarLeaderboardResponse "Calendar leaderboards list"
// @Failure 400 {object} map[string]interface{} "Invalid input"
// @Failure 500 {object} map[string]interface{} "Internal server error"
// @Router /api/leaderboard/tracks [get]
func calendarLeaderboardHandler(svc *races.Service) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
yearVal := r.URL.Query().Get("year")
var year int
if yearVal != "" {
var err error
year, err = strconv.Atoi(yearVal)
if err != nil {
writeError(w, http.StatusBadRequest, "invalid_input", "invalid year")
return
}
}
driverID := r.Header.Get("X-Driver-Id")
if driverID == "" {
driverID = "driver-seed-001" // mock current driver
}
res, err := svc.GetCalendarLeaderboard(r.Context(), year, driverID)
if err != nil {
writeError(w, http.StatusInternalServerError, "internal", err.Error())
return
}
items := make([]transport.TrackCalendarLeaderboard, 0, len(res))
for _, item := range res {
podium := make([]transport.LeaderboardEntry, 0, len(item.Podium))
for _, entry := range item.Podium {
podium = append(podium, leaderboardEntryToWire(entry))
}
var curDriver *transport.LeaderboardEntry
if item.CurrentDriver != nil {
wire := leaderboardEntryToWire(*item.CurrentDriver)
curDriver = &wire
}
items = append(items, transport.TrackCalendarLeaderboard{
TrackID: item.TrackID,
TrackName: item.TrackName,
StartAt: item.StartAt,
EndAt: item.EndAt,
Status: item.Status,
Podium: podium,
CurrentDriver: curDriver,
})
}
writeJSON(w, http.StatusOK, transport.TrackCalendarLeaderboardResponse{Items: items})
}
}