package api import ( "encoding/json" "net/http" "github.com/go-chi/chi/v5" "github.com/jackc/pgx/v5/pgtype" "git.fabledsword.com/bvandeusen/minstrel/internal/apierror" "git.fabledsword.com/bvandeusen/minstrel/internal/auth" "git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq" ) // requireUser returns the authenticated user from request context. On // missing context, writes a 401 envelope and returns ok=false; the // caller MUST return immediately on ok=false. Defensive belt against // middleware bypass — handlers using this don't need a separate check. func requireUser(w http.ResponseWriter, r *http.Request) (dbq.User, bool) { user, ok := auth.UserFromContext(r.Context()) if !ok { writeErr(w, apierror.Unauthorized("auth_required", "")) return dbq.User{}, false } return user, true } // requireURLUUID parses the chi URL parameter named key as a UUID. On // invalid input, writes a 400 envelope and returns ok=false; the caller // MUST return immediately on ok=false. func requireURLUUID(w http.ResponseWriter, r *http.Request, key string) (pgtype.UUID, bool) { id, ok := parseUUID(chi.URLParam(r, key)) if !ok { writeErr(w, apierror.BadRequest("invalid_id", "")) return id, false } return id, true } // decodeBody decodes the request body as JSON into out. On decode // failure, writes a 400 envelope and returns false; the caller MUST // return immediately on false. Out parameter pattern (rather than // returning T) keeps the type explicit at the call site. func decodeBody[T any](w http.ResponseWriter, r *http.Request, out *T) bool { if err := json.NewDecoder(r.Body).Decode(out); err != nil { writeErr(w, apierror.BadRequest("invalid_body", "")) return false } return true }