Something went wrong. Try again.
An event companion and onboarding experience for the ATmosphere (alpha) atmo.quest
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354// Package api implements the JSON API layer at /api/v1/ for the mobile app.//// All handlers return JSON and accept Bearer token auth (or session cookie).// This package mirrors the same business logic as the HTML handlers but exposes// it through a structured JSON contract.package api
import ( "database/sql" "encoding/json" "log/slog" "net/http"
"atmoquest/features/auth" "atmoquest/internal/apitoken" "atmoquest/internal/connection" "atmoquest/internal/push")
// Handlers holds the shared dependencies for all API endpoints.type Handlers struct { DB *sql.DB Auth *auth.Handlers ConnQueue *connection.Queue Tokens *apitoken.Generator Push *push.Sender}
// NewHandlers wires the API feature.func NewHandlers(conn *sql.DB, authH *auth.Handlers, connQueue *connection.Queue, tokens *apitoken.Generator, pusher *push.Sender) *Handlers { return &Handlers{DB: conn, Auth: authH, ConnQueue: connQueue, Tokens: tokens, Push: pusher}}
// --- JSON helpers -----------------------------------------------------------
// writeJSON encodes v as JSON with the given status code.func writeJSON(w http.ResponseWriter, status int, v any) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(v); err != nil { slog.Warn("api: encode response", "err", err) }}
// writeError writes a JSON error response.func writeError(w http.ResponseWriter, status int, msg string) { writeJSON(w, status, map[string]string{"error": msg})}
// decodeBody reads a JSON request body, capped at 64 KB.func decodeBody(r *http.Request, v any) error { return json.NewDecoder(http.MaxBytesReader(nil, r.Body, 64*1024)).Decode(v)}