package api import ( "context" "errors" "net/http" "time" "go.uber.org/zap" "predictor-refactored/internal/api/async" "predictor-refactored/internal/datasets" "predictor-refactored/internal/elevation" "predictor-refactored/internal/engine" "predictor-refactored/internal/metrics" "predictor-refactored/internal/windviz" apirest "predictor-refactored/pkg/rest" ) // Handler implements the ogen-generated apirest.Handler interface for every // operation in the OpenAPI spec. Operation methods are grouped by concern // across prediction.go, datasets.go, and wind.go. type Handler struct { mgr *datasets.Manager elev *elevation.Dataset async *async.Manager metrics metrics.Sink cache *windviz.Cache started time.Time log *zap.Logger } var _ apirest.Handler = (*Handler)(nil) // terrain returns the elevation dataset as an engine.TerrainProvider, or an // untyped nil interface when no elevation dataset is loaded. Returning the // concrete nil *elevation.Dataset directly would produce a non-nil interface // wrapping a nil pointer, which then panics on first use — so the nil check // must happen here, on the concrete type. func (h *Handler) terrain() engine.TerrainProvider { if h.elev == nil { return nil } return h.elev } // NewError converts an error returned by a handler into the spec's default // error response. Handlers return *apirest.DefaultErrorStatusCode (via the // apiError helper) to control the status code; anything else is a 500. func (h *Handler) NewError(_ context.Context, err error) *apirest.DefaultErrorStatusCode { var coded *apirest.DefaultErrorStatusCode if errors.As(err, &coded) { return coded } h.log.Error("unhandled handler error", zap.Error(err)) return apiError(http.StatusInternalServerError, err.Error()) } // apiError builds a coded error response carrying an HTTP status. func apiError(status int, description string) *apirest.DefaultErrorStatusCode { return &apirest.DefaultErrorStatusCode{ StatusCode: status, Response: apirest.Error{ Error: apirest.ErrorError{ Type: http.StatusText(status), Description: description, }, }, } }