package handlers import ( "log/slog" "net/http" "qbank/internal/auth" "qbank/internal/db" "qbank/internal/models" ) type HistoryHandler struct { auth *auth.Manager repo *db.Repo render *Renderer } func NewHistoryHandler(a *auth.Manager, repo *db.Repo, r *Renderer) *HistoryHandler { return &HistoryHandler{auth: a, repo: repo, render: r} } // TestHistoryItem pairs a test with its correct-answer count. type TestHistoryItem struct { *models.Test NCorrect int } func (h *HistoryHandler) Handle(w http.ResponseWriter, r *http.Request) { user := auth.UserFromCtx(r.Context()) tests, err := h.repo.ListTestsForUser(user.ID) if err != nil { slog.Error("list tests for history", "err", err) HTTPError(w, http.StatusInternalServerError) return } correctCounts, err := h.repo.GetCorrectCountsForUser(user.ID) if err != nil { slog.Error("get correct counts", "err", err) HTTPError(w, http.StatusInternalServerError) return } items := make([]TestHistoryItem, 0, len(tests)) for _, t := range tests { if !t.CompletedAt.Valid { continue // skip in-progress tests } items = append(items, TestHistoryItem{ Test: t, NCorrect: correctCounts[t.ID], }) } totalCorrect, totalAnswered, err := h.repo.GetAggregateStats(user.ID) if err != nil { slog.Error("get aggregate stats", "err", err) HTTPError(w, http.StatusInternalServerError) return } weakSpots, err := h.repo.GetWeakSpots(user.ID) if err != nil { slog.Error("get weak spots", "err", err) HTTPError(w, http.StatusInternalServerError) return } data := BaseData(h.auth, r) data["Items"] = items data["TotalCorrect"] = totalCorrect data["TotalAnswered"] = totalAnswered data["WeakSpots"] = weakSpots h.render.Render(w, http.StatusOK, "history", data) }