package user import ( "encoding/json" "log/slog" "net/http" "github.com/food-ai/backend/internal/infra/middleware" ) const maxRequestBodySize = 1 << 20 // 1 MB type Handler struct { service *Service } func NewHandler(service *Service) *Handler { return &Handler{service: service} } func (h *Handler) Get(w http.ResponseWriter, r *http.Request) { userID := middleware.UserIDFromCtx(r.Context()) if userID == "" { writeErrorJSON(w, r, http.StatusUnauthorized, "unauthorized") return } u, err := h.service.GetProfile(r.Context(), userID) if err != nil { writeErrorJSON(w, r, http.StatusNotFound, "user not found") return } writeJSON(w, http.StatusOK, u) } func (h *Handler) Update(w http.ResponseWriter, r *http.Request) { userID := middleware.UserIDFromCtx(r.Context()) if userID == "" { writeErrorJSON(w, r, http.StatusUnauthorized, "unauthorized") return } r.Body = http.MaxBytesReader(w, r.Body, maxRequestBodySize) var req UpdateProfileRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeErrorJSON(w, r, http.StatusBadRequest, "invalid request body") return } u, err := h.service.UpdateProfile(r.Context(), userID, req) if err != nil { writeErrorJSON(w, r, http.StatusBadRequest, err.Error()) return } writeJSON(w, http.StatusOK, u) } type errorResponse struct { Error string `json:"error"` RequestID string `json:"request_id,omitempty"` } func writeErrorJSON(w http.ResponseWriter, r *http.Request, status int, msg string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) if encodeErr := json.NewEncoder(w).Encode(errorResponse{ Error: msg, RequestID: middleware.RequestIDFromCtx(r.Context()), }); encodeErr != nil { slog.ErrorContext(r.Context(), "failed to write error response", "err", encodeErr) } } func writeJSON(w http.ResponseWriter, status int, v interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) if err := json.NewEncoder(w).Encode(v); err != nil { slog.Error("failed to write JSON response", "err", err) } }