Leon4gr45's picture
Upload folder using huggingface_hub (part 2)
5a22efd verified
Raw
History Blame Contribute Delete
6.16 kB
package usagebased
import (
"context"
"errors"
"fmt"
"github.com/openmeterio/openmeter/openmeter/billing"
"github.com/openmeterio/openmeter/openmeter/billing/charges/meta"
"github.com/openmeterio/openmeter/openmeter/billing/models/totals"
"github.com/openmeterio/openmeter/openmeter/productcatalog/feature"
"github.com/openmeterio/openmeter/pkg/models"
)
type Service interface {
UsageBasedService
GetLineEngine() billing.LineEngine
}
type UsageBasedService interface {
// Create returns one result for each input intent, preserving input order.
// Pending gathering-line creation relies on this to pair charge targets with
// their source intents.
Create(ctx context.Context, input CreateInput) ([]ChargeWithGatheringLine, error)
// GetByIDs loads usage-based charges. Request realization expansions when
// callers need run, detailed-line, or credit-allocation state.
GetByIDs(ctx context.Context, input GetByIDsInput) ([]Charge, error)
// UpdateSubscriptionItemID repairs subscription ownership metadata on the
// base intent; it must not rewrite an active customer-facing override layer.
UpdateSubscriptionItemID(ctx context.Context, charge Charge, newSubscriptionItemID string) (Charge, error)
// AdvanceCharge drives one usage-based charge. Realization runs store
// cumulative usage snapshots; billing-line quantities are mapped separately.
AdvanceCharge(ctx context.Context, input AdvanceChargeInput) (*Charge, error)
// TriggerPatch applies an explicit base/override target patch and then
// reconciles invoice artifacts from the effective usage-based intent.
TriggerPatch(ctx context.Context, charge meta.ChargeID, patch meta.Patch) (meta.TriggerPatchResult[Charge], error)
// GetCurrentTotals calculates the current customer-facing totals from the
// effective intent and non-voided realization history.
GetCurrentTotals(ctx context.Context, input GetCurrentTotalsInput) (GetCurrentTotalsResult, error)
}
type CreateInput struct {
Namespace string
Intents []Intent
FeatureMeters feature.FeatureMeters
}
func (i CreateInput) Validate() error {
var errs []error
if i.Namespace == "" {
errs = append(errs, errors.New("namespace is required"))
}
if len(i.Intents) > 0 && i.FeatureMeters == nil {
errs = append(errs, errors.New("feature meters are required"))
}
for idx, intent := range i.Intents {
if err := intent.Validate(); err != nil {
errs = append(errs, fmt.Errorf("intent [%d]: %w", idx, err))
}
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
type ChargeWithGatheringLine struct {
Charge Charge
GatheringLineToCreate *billing.GatheringLine
}
type CreateIntent struct {
Intent OverridableIntent
Annotations models.Annotations `json:"annotations"`
FeatureID string
RatingEngine RatingEngine
}
func (i CreateIntent) Validate() error {
var errs []error
if err := i.Intent.Validate(); err != nil {
errs = append(errs, err)
}
if i.FeatureID == "" {
errs = append(errs, errors.New("feature id is required"))
}
if err := i.RatingEngine.Validate(); err != nil {
errs = append(errs, fmt.Errorf("rating engine: %w", err))
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
type CreateChargesInput struct {
Namespace string
Intents []CreateIntent
}
func (i CreateChargesInput) Validate() error {
var errs []error
if i.Namespace == "" {
errs = append(errs, errors.New("namespace is required"))
}
for idx, intent := range i.Intents {
if err := intent.Validate(); err != nil {
errs = append(errs, fmt.Errorf("intent [%d]: %w", idx, err))
}
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
type GetByIDsInput struct {
Namespace string
IDs []string
Expands meta.Expands
}
func (i GetByIDsInput) Validate() error {
var errs []error
if i.Namespace == "" {
errs = append(errs, errors.New("namespace is required"))
}
if err := validateExpands(i.Expands); err != nil {
errs = append(errs, fmt.Errorf("expands: %w", err))
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
type AdvanceChargeInput struct {
ChargeID meta.ChargeID
CustomerOverride billing.CustomerOverrideWithDetails
FeatureMeters feature.FeatureMeters
}
func (i AdvanceChargeInput) Validate() error {
var errs []error
if err := i.ChargeID.Validate(); err != nil {
errs = append(errs, fmt.Errorf("charge ID: %w", err))
}
if i.CustomerOverride.Customer == nil {
errs = append(errs, errors.New("expanded customer is required"))
}
if err := i.CustomerOverride.MergedProfile.Validate(); err != nil {
errs = append(errs, fmt.Errorf("merged profile is required: %w", err))
}
if i.FeatureMeters == nil {
errs = append(errs, errors.New("feature meters are required"))
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
type GetByIDInput struct {
ChargeID meta.ChargeID
Expands meta.Expands
}
func (i GetByIDInput) Validate() error {
var errs []error
if err := i.ChargeID.Validate(); err != nil {
errs = append(errs, fmt.Errorf("charge ID: %w", err))
}
if err := validateExpands(i.Expands); err != nil {
errs = append(errs, fmt.Errorf("expands: %w", err))
}
return models.NewNillableGenericValidationError(errors.Join(errs...))
}
type GetCurrentTotalsInput struct {
ChargeID meta.ChargeID
}
func (i GetCurrentTotalsInput) Validate() error {
if err := i.ChargeID.Validate(); err != nil {
return models.NewGenericValidationError(fmt.Errorf("charge ID: %w", err))
}
return nil
}
type GetCurrentTotalsResult struct {
Charge Charge
DueTotals totals.Totals
}
func validateExpands(expands meta.Expands) error {
if err := expands.Validate(); err != nil {
return err
}
if expands.Has(meta.ExpandDetailedLines) && !expands.Has(meta.ExpandRealizations) {
return fmt.Errorf("%q requires %q", meta.ExpandDetailedLines, meta.ExpandRealizations)
}
if expands.Has(meta.ExpandDeletedRealizations) && !expands.Has(meta.ExpandRealizations) {
return fmt.Errorf("%q requires %q", meta.ExpandDeletedRealizations, meta.ExpandRealizations)
}
return nil
}