// Package httpresponse provides standard HTTP response types and helpers. // // This package implements an envelope pattern for consistent API responses: // // { // "data": {...}, // Present on success // "error": {...}, // Present on error // "meta": { // "request_id": "...", // "trace_id": "...", // "timestamp": "..." // } // } // // Usage: // // func GetUser(w http.ResponseWriter, r *http.Request) { // user, err := svc.Get(ctx, id) // if err != nil { // httpresponse.NotFound(w, r, "user not found") // return // } // httpresponse.OK(w, r, user) // } package httpresponse import ( "net/http" "time" "git.threesix.ai/jordan/sp4-debug-1770477266/pkg/httpcontext" ) // Response is the standard envelope for all API responses. type Response struct { Data any `json:"data,omitempty"` Error *Error `json:"error,omitempty"` Meta Meta `json:"meta"` } // Error represents an API error in the response envelope. type Error struct { Code string `json:"code"` Message string `json:"message"` Details any `json:"details,omitempty"` } // Meta contains response metadata. type Meta struct { RequestID string `json:"request_id,omitempty"` TraceID string `json:"trace_id,omitempty"` Timestamp string `json:"timestamp"` } // newMeta creates a Meta with current timestamp, request ID, and trace ID from context. func newMeta(r *http.Request) Meta { requestID, _ := httpcontext.GetRequestID(r.Context()) traceID, _ := httpcontext.GetTraceID(r.Context()) return Meta{ RequestID: requestID, TraceID: traceID, Timestamp: time.Now().UTC().Format(time.RFC3339), } } // Error codes for machine-readable error classification. const ( CodeBadRequest = "BAD_REQUEST" CodeUnauthorized = "UNAUTHORIZED" CodeForbidden = "FORBIDDEN" CodeNotFound = "NOT_FOUND" CodeConflict = "CONFLICT" CodeInternal = "INTERNAL_ERROR" CodeValidation = "VALIDATION_ERROR" )