Files
qbank/internal/handlers/history.go
T
Jānis Kacēns 2477130dd9 Phase 8: history
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 16:50:55 +03:00

77 lines
1.7 KiB
Go

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)
}