Files
Horchposten/handlers/player_stats.go
2026-03-08 14:44:50 +00:00

85 lines
2.2 KiB
Go

package handlers
import (
"database/sql"
"net/http"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
"github.com/tas/horchposten/models"
)
// PlayerStats handles GET /api/analytics/player/:client_id/
func PlayerStats(db *sql.DB) echo.HandlerFunc {
return func(c echo.Context) error {
clientID := c.Param("client_id")
if _, err := uuid.Parse(clientID); err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"error": "invalid client_id format"})
}
// Look up player.
var playerID int64
var totalSessions int
var firstSeen string
err := db.QueryRow(
"SELECT id, total_sessions, first_seen FROM players WHERE client_id = ?",
clientID,
).Scan(&playerID, &totalSessions, &firstSeen)
if err == sql.ErrNoRows {
return c.JSON(http.StatusNotFound, echo.Map{"error": "player not found"})
} else if err != nil {
return c.JSON(http.StatusInternalServerError, echo.Map{"error": "database error"})
}
// Get high score.
var highScore *int
var hs int
err = db.QueryRow(
"SELECT score FROM high_scores WHERE player_id = ?", playerID,
).Scan(&hs)
if err == nil {
highScore = &hs
}
// Get last 50 sessions.
rows, err := db.Query(
`SELECT id, score, level_reached, lives_used, duration_seconds,
end_reason, started_at, ended_at
FROM game_sessions
WHERE player_id = ?
ORDER BY ended_at DESC
LIMIT 50`,
playerID,
)
if err != nil {
return c.JSON(http.StatusInternalServerError, echo.Map{"error": "database error"})
}
defer rows.Close()
sessions := make([]models.SessionSummary, 0)
for rows.Next() {
var s models.SessionSummary
var startedAt, endedAt string
if err := rows.Scan(
&s.SessionID, &s.Score, &s.LevelReached, &s.LivesUsed,
&s.DurationSeconds, &s.EndReason, &startedAt, &endedAt,
); err != nil {
return c.JSON(http.StatusInternalServerError, echo.Map{"error": "scan error"})
}
s.StartedAt = parseTime(startedAt)
s.EndedAt = parseTime(endedAt)
sessions = append(sessions, s)
}
resp := models.PlayerStatsResponse{
ClientID: clientID,
TotalSessions: totalSessions,
FirstSeen: parseTime(firstSeen),
HighScore: highScore,
Sessions: sessions,
}
return c.JSON(http.StatusOK, resp)
}
}