package handlers import ( "fmt" "strconv" "github.com/gin-gonic/gin" "google.golang.org/grpc" ) const ( ErrMsgDataClient = "data client is required" ) // Handler is a base handler that provides common functionality for all HTTP handlers. type Handler struct { dataClient *grpc.ClientConn storageUrl string } // HandlerOption defines a functional option for configuring a Handler type HandlerOption func(*Handler) // WithDataClient sets the data client for the Handler func WithDataClient(dataClient *grpc.ClientConn) HandlerOption { return func(h *Handler) { h.dataClient = dataClient } } // WithStorageUrl sets the storage url func WithStorageUrl(storageUrl string) HandlerOption { return func(cfg *Handler) { cfg.storageUrl = storageUrl } } // NewHandler creates a new Handler with the provided options. // It requires both a datastore and an authentication service to function properly. func NewHandler(options ...HandlerOption) (*Handler, error) { handler := &Handler{} // Apply all provided options for _, option := range options { option(handler) } // Validate required dependencies if err := handler.validateDependencies(); err != nil { return nil, err } return handler, nil } // validateDependencies ensures all required dependencies are properly set func (h *Handler) validateDependencies() error { if h.dataClient == nil { return fmt.Errorf(ErrMsgDataClient) } return nil } // validateRange ensures a value is within the specified range, returning defaultValue if outside func validateRange(value, min, max, defaultValue int) int { if value < min { return defaultValue } if value > max { return max } return value } // validateMin ensures a value is at least the minimum, returning defaultValue if below func validateMin(value, min, defaultValue int) int { if value < min { return defaultValue } return value } // getPagination extracts pagination parameters from query string. // It applies validation rules to ensure parameters are within acceptable ranges. func getPagination(ctx *gin.Context, defaultPageSize, minPageSize, maxPageSize int) (pageSize, pageNumber int) { // Get page size from query string, parse to integer pageSizeStr := ctx.Query("page_size") if pageSizeStr != "" { pageSize, _ = strconv.Atoi(pageSizeStr) } else { pageSize = defaultPageSize } // Get page number from query string, parse to integer pageNumberStr := ctx.Query("page_number") if pageNumberStr != "" { pageNumber, _ = strconv.Atoi(pageNumberStr) } else { pageNumber = 1 // Default to first page } // Apply validation rules pageSize = validateRange(pageSize, minPageSize, maxPageSize, defaultPageSize) pageNumber = validateMin(pageNumber, 1, 1) return pageSize, pageNumber }