go-bananas/internal/httpapi/preferences.go

76 lines
2.6 KiB
Go
Raw Normal View History

2026-10-07 15:11:35 +02:00
package httpapi
import (
"net/http"
"github.com/urpi/go-bananas/internal/domain"
"github.com/urpi/go-bananas/internal/store"
)
// PreferenceHandlers serves the caller's own interface preferences.
//
// A preference belongs to the account rather than to a browser, so it is stored
// against the identity subject and travels with the person to another device. It
// is deliberately not part of the session token: the token is issued by the
// identity provider and this service does not control its claims, so a choice made
// here has to be read back from this API.
type PreferenceHandlers struct {
store *store.Store
log Logger
}
// NewPreferenceHandlers builds the preference handler set.
func NewPreferenceHandlers(st *store.Store, log Logger) *PreferenceHandlers {
return &PreferenceHandlers{store: st, log: log}
}
// Get returns the caller's preferences, or the empty preference when they have
// chosen nothing yet.
func (h *PreferenceHandlers) Get(w http.ResponseWriter, r *http.Request) {
identity := mustIdentity(r.Context())
prefs, err := h.store.Preferences(r.Context(), identity.Subject)
if err != nil {
h.log.Error("read preferences", "subject", identity.Subject, "error", err)
writeProblem(w, r, err)
return
}
writeJSON(w, r, http.StatusOK, prefs)
}
// Update records the caller's preferences and echoes back what was stored, so the
// client renders the server's decision rather than its own input.
//
// An empty selectedTheme clears the choice. Clearing through the same endpoint
// rather than a second route keeps the write surface to one path, which matters
// because this endpoint is the only thing that writes the row.
func (h *PreferenceHandlers) Update(w http.ResponseWriter, r *http.Request) {
identity := mustIdentity(r.Context())
var request domain.UserPreferences
if err := decodeJSON(r, &request); err != nil {
writeProblem(w, r, err)
return
}
stored, err := h.store.SetPreferences(r.Context(), identity.Subject, request)
if err != nil {
h.log.Warn("update preferences", "subject", identity.Subject, "error", err)
writeProblem(w, r, err)
return
}
writeJSON(w, r, http.StatusOK, stored)
}
// Reset forgets the caller's preferences and returns them to their defaults.
func (h *PreferenceHandlers) Reset(w http.ResponseWriter, r *http.Request) {
identity := mustIdentity(r.Context())
if _, err := h.store.ClearPreferences(r.Context(), identity.Subject); err != nil {
h.log.Error("clear preferences", "subject", identity.Subject, "error", err)
writeProblem(w, r, err)
return
}
writeJSON(w, r, http.StatusOK, domain.UserPreferences{})
}