| package features |
|
|
| import ( |
| "context" |
| "fmt" |
| "net/http" |
|
|
| api "github.com/openmeterio/openmeter/api/v3" |
| "github.com/openmeterio/openmeter/api/v3/apierrors" |
| "github.com/openmeterio/openmeter/api/v3/request" |
| "github.com/openmeterio/openmeter/openmeter/meter" |
| "github.com/openmeterio/openmeter/openmeter/productcatalog/feature" |
| "github.com/openmeterio/openmeter/pkg/framework/commonhttp" |
| "github.com/openmeterio/openmeter/pkg/framework/transport/httptransport" |
| "github.com/openmeterio/openmeter/pkg/models" |
| ) |
|
|
| type ( |
| CreateFeatureRequest = feature.CreateFeatureInputs |
| CreateFeatureResponse = api.Feature |
| CreateFeatureHandler httptransport.Handler[CreateFeatureRequest, CreateFeatureResponse] |
| ) |
|
|
| func (h *handler) CreateFeature() CreateFeatureHandler { |
| return httptransport.NewHandler( |
| func(ctx context.Context, r *http.Request) (CreateFeatureRequest, error) { |
| body := api.CreateFeatureRequest{} |
| if err := request.ParseBody(r, &body); err != nil { |
| return CreateFeatureRequest{}, err |
| } |
|
|
| ns, err := h.resolveNamespace(ctx) |
| if err != nil { |
| return CreateFeatureRequest{}, err |
| } |
|
|
| |
| var meterID *string |
| if body.Meter != nil { |
| if body.Meter.Id == "" { |
| return CreateFeatureRequest{}, models.NewGenericValidationError( |
| fmt.Errorf("meter id is required"), |
| ) |
| } |
|
|
| m, err := h.meterService.GetMeterByIDOrSlug(ctx, meter.GetMeterInput{ |
| Namespace: ns, |
| IDOrSlug: body.Meter.Id, |
| }) |
| if err != nil { |
| return CreateFeatureRequest{}, err |
| } |
| meterID = &m.ID |
|
|
| |
| if body.Meter.Filters != nil { |
| if err := validateMeterFilters(*body.Meter.Filters, m); err != nil { |
| return CreateFeatureRequest{}, err |
| } |
| } |
| } |
|
|
| return convertCreateRequestToDomain(ns, body, meterID) |
| }, |
| func(ctx context.Context, req CreateFeatureRequest) (CreateFeatureResponse, error) { |
| created, err := h.connector.CreateFeature(ctx, req) |
| if err != nil { |
| return CreateFeatureResponse{}, err |
| } |
|
|
| return convertFeatureToAPI(created) |
| }, |
| commonhttp.JSONResponseEncoderWithStatus[CreateFeatureResponse](http.StatusCreated), |
| httptransport.AppendOptions( |
| h.options, |
| httptransport.WithOperationName("create-feature"), |
| httptransport.WithErrorEncoder(apierrors.GenericErrorEncoder()), |
| httptransport.WithErrorEncoder(errorEncoder()), |
| )..., |
| ) |
| } |
|
|
| |
| |
| |
| func validateMeterFilters(filters map[string]api.QueryFilterStringMapItem, m meter.Meter) error { |
| for k := range filters { |
| if _, ok := m.GroupBy[k]; !ok { |
| return models.NewGenericValidationError( |
| fmt.Errorf("filter key %q is not a valid dimension of meter %q", k, m.Key), |
| ) |
| } |
| } |
| return nil |
| } |
|
|