Documentation
¶
Index ¶
- Constants
- Variables
- func IsItemNotFoundError(err error) bool
- func IsPhaseNotFoundError(err error) bool
- func IsPlanNotFoundError(err error) bool
- func IsSubscriptionNotFoundError(err error) bool
- func NewItemNotFoundError(itemId string) error
- func NewPhaseNotFoundError(phaseId string) error
- func NewPlanNotFoundError(key string, version int) error
- func NewSubscriptionNotFoundError(id string) error
- type AlignmentError
- type AllowedDuringApplyingToSpecError
- type AnyValuePatch
- type AppliesToSpec
- type ApplyContext
- type BillingBehaviorOverride
- type CancelledEvent
- type ContinuedEvent
- type CreateSubscriptionCustomerInput
- type CreateSubscriptionEntityInput
- type CreateSubscriptionItemCustomerInput
- type CreateSubscriptionItemEntityInput
- type CreateSubscriptionItemInput
- type CreateSubscriptionItemPlanInput
- type CreateSubscriptionPhaseCustomerInput
- type CreateSubscriptionPhaseEntityInput
- type CreateSubscriptionPhaseInput
- type CreateSubscriptionPhasePlanInput
- type CreateSubscriptionPlanInput
- type CreatedEvent
- type DeletedEvent
- type EntitlementAdapter
- type ItemNotFoundError
- type ListSubscriptionsInput
- type NoBillingPeriodError
- type NoOpSubscriptionValidator
- func (NoOpSubscriptionValidator) ValidateCancel(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateContinue(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateCreate(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateDelete(context.Context, SubscriptionView) error
- func (NoOpSubscriptionValidator) ValidateUpdate(context.Context, SubscriptionView) error
- type Patch
- type PatchConflictError
- type PatchForbiddenError
- type PatchOperation
- type PatchValidationError
- type PhaseNotFoundError
- type Plan
- type PlanNotFoundError
- type PlanPhase
- type PlanRateCard
- type PlanRef
- type RemoveSubscriptionPhaseInput
- type RemoveSubscriptionPhaseShifting
- type ScheduleSubscriptionEntitlementInput
- type Service
- type SpecPath
- func (p SpecPath) IsParentOf(other SpecPath) bool
- func (p SpecPath) ItemKey() string
- func (p SpecPath) ItemVersion() int
- func (p SpecPath) MarshalJSON() ([]byte, error)
- func (p SpecPath) PhaseKey() string
- func (p SpecPath) Type() SpecPathType
- func (p *SpecPath) UnmarshalJSON(data []byte) error
- func (p SpecPath) Validate() error
- type SpecPathType
- type SpecValidationError
- type Subscription
- type SubscriptionAction
- type SubscriptionEntitlement
- type SubscriptionItem
- type SubscriptionItemRef
- type SubscriptionItemRepository
- type SubscriptionItemSpec
- func (s SubscriptionItemSpec) GetCadence(phaseCadence models.CadencedModel) models.CadencedModel
- func (s SubscriptionItemSpec) GetRef(subId string) SubscriptionItemRef
- func (s SubscriptionItemSpec) ToCreateSubscriptionItemEntityInput(phaseID models.NamespacedID, phaseCadence models.CadencedModel, ...) (CreateSubscriptionItemEntityInput, error)
- func (s SubscriptionItemSpec) ToScheduleSubscriptionEntitlementInput(opts ToScheduleSubscriptionEntitlementInputOptions) (ScheduleSubscriptionEntitlementInput, bool, error)
- func (s *SubscriptionItemSpec) Validate() error
- type SubscriptionItemView
- type SubscriptionList
- type SubscriptionNotFoundError
- type SubscriptionPhase
- type SubscriptionPhaseRepository
- type SubscriptionPhaseSpec
- func (s SubscriptionPhaseSpec) GetBillableItemsByKey() map[string][]*SubscriptionItemSpec
- func (s SubscriptionPhaseSpec) GetBillingCadence() (isodate.Period, error)
- func (s SubscriptionPhaseSpec) HasBillables() bool
- func (s SubscriptionPhaseSpec) HasEntitlements() bool
- func (s SubscriptionPhaseSpec) HasMeteredBillables() bool
- func (s SubscriptionPhaseSpec) ToCreateSubscriptionPhaseEntityInput(subscription Subscription, activeFrom time.Time) CreateSubscriptionPhaseEntityInput
- func (s SubscriptionPhaseSpec) Validate(phaseCadence models.CadencedModel, alignment productcatalog.Alignment) error
- type SubscriptionPhaseView
- type SubscriptionRepository
- type SubscriptionSpec
- func (s *SubscriptionSpec) Apply(applies AppliesToSpec, context ApplyContext) error
- func (s *SubscriptionSpec) ApplyMany(applieses []AppliesToSpec, aCtx ApplyContext) error
- func (s *SubscriptionSpec) GetAlignedBillingPeriodAt(phaseKey string, at time.Time) (timeutil.ClosedPeriod, error)
- func (s *SubscriptionSpec) GetCurrentPhaseAt(t time.Time) (*SubscriptionPhaseSpec, bool)
- func (s *SubscriptionSpec) GetPhaseCadence(phaseKey string) (models.CadencedModel, error)
- func (s *SubscriptionSpec) GetSortedPhases() []*SubscriptionPhaseSpec
- func (s *SubscriptionSpec) HasBillables() bool
- func (s *SubscriptionSpec) HasEntitlements() bool
- func (s *SubscriptionSpec) HasMeteredBillables() bool
- func (s *SubscriptionSpec) ToCreateSubscriptionEntityInput(ns string) CreateSubscriptionEntityInput
- func (s *SubscriptionSpec) Validate() error
- type SubscriptionStateMachine
- type SubscriptionStatus
- type SubscriptionValidator
- type SubscriptionView
- type Timing
- type TimingEnum
- type ToScheduleSubscriptionEntitlementInputOptions
- type UpdatedEvent
- type ValidatorService
- type ValuePatch
Constants ¶
const (
// AnnotationSubscriptionID is the ID of the subscription that created this entitlement
AnnotationSubscriptionID = "subscription.id"
)
const (
EventSubsystem metadata.EventSubsystem = "subscription"
)
Variables ¶
var AnnotationParser = annotationParser{}
Functions ¶
func IsItemNotFoundError ¶
IsItemNotFoundError returns true if the error is a ItemNotFoundError.
func IsPhaseNotFoundError ¶
IsPhaseNotFoundError returns true if the error is a PhaseNotFoundError.
func IsPlanNotFoundError ¶
IsPlanNotFoundError returns true if the error is a PlanNotFoundError.
func IsSubscriptionNotFoundError ¶
IsSubscriptionNotFoundError returns true if the error is a SubscriptionNotFoundError.
func NewItemNotFoundError ¶
NewItemNotFoundError returns a new ItemNotFoundError.
func NewPhaseNotFoundError ¶
NewPhaseNotFoundError returns a new PhaseNotFoundError.
func NewPlanNotFoundError ¶
NewPlanNotFoundError returns a new PlanNotFoundError.
func NewSubscriptionNotFoundError ¶
NewSubscriptionNotFoundError returns a new SubscriptionNotFoundError.
Types ¶
type AlignmentError ¶
type AlignmentError struct {
Inner error
}
AlignmentError is an error that occurs when the spec is not aligned but we expect it to be.
func (AlignmentError) Error ¶
func (e AlignmentError) Error() string
func (AlignmentError) Unwrap ¶
func (e AlignmentError) Unwrap() error
type AllowedDuringApplyingToSpecError ¶
type AllowedDuringApplyingToSpecError struct {
Inner error
}
Some errors are allowed during applying individual things to the spec, but still mean the Spec as a whole is invalid
func (*AllowedDuringApplyingToSpecError) Error ¶
func (e *AllowedDuringApplyingToSpecError) Error() string
func (*AllowedDuringApplyingToSpecError) Unwrap ¶
func (e *AllowedDuringApplyingToSpecError) Unwrap() error
type AnyValuePatch ¶
type AnyValuePatch interface {
ValueAsAny() any
}
type AppliesToSpec ¶
type AppliesToSpec interface {
ApplyTo(spec *SubscriptionSpec, actx ApplyContext) error
}
Things can apply themselves to the spec
func NewAggregateAppliesToSpec ¶
func NewAggregateAppliesToSpec(applieses []AppliesToSpec) AppliesToSpec
NewAggregateAppliesToSpec aggregates multiple applies to spec into a single applies to spec, and also validates the spec after applying all the patches
func NewAppliesToSpec ¶
func NewAppliesToSpec(fn func(spec *SubscriptionSpec, actx ApplyContext) error) AppliesToSpec
func ToApplies ¶
func ToApplies(p Patch, _ int) AppliesToSpec
type ApplyContext ¶
type BillingBehaviorOverride ¶
type BillingBehaviorOverride struct {
// If true, the billing cadence will be restarted
// The anchor time will be the time the originating change takes effect,
// which in practive translates to a SubscriptionItem's ActiveFrom property.
RestartBillingPeriod *bool `json:"restartBillingPeriod,omitempty"`
}
type CancelledEvent ¶
type CancelledEvent viewEvent
func NewCancelledEvent ¶
func NewCancelledEvent(ctx context.Context, view SubscriptionView) CancelledEvent
NewCancelledEvent creates a new deleted event
func (CancelledEvent) EventMetadata ¶
func (s CancelledEvent) EventMetadata() metadata.EventMetadata
func (CancelledEvent) EventName ¶
func (s CancelledEvent) EventName() string
func (CancelledEvent) Validate ¶
func (s CancelledEvent) Validate() error
type ContinuedEvent ¶
type ContinuedEvent viewEvent
func NewContinuedEvent ¶
func NewContinuedEvent(ctx context.Context, view SubscriptionView) ContinuedEvent
NewContinuedEvent creates a new continued event
func (ContinuedEvent) EventMetadata ¶
func (s ContinuedEvent) EventMetadata() metadata.EventMetadata
func (ContinuedEvent) EventName ¶
func (s ContinuedEvent) EventName() string
func (ContinuedEvent) Validate ¶
func (s ContinuedEvent) Validate() error
type CreateSubscriptionCustomerInput ¶
type CreateSubscriptionCustomerInput struct {
models.MetadataModel `json:",inline"`
Name string `json:"name"`
Description *string `json:"description,omitempty"`
CustomerId string `json:"customerId"`
Currency currencyx.Code `json:"currency"`
ActiveFrom time.Time `json:"activeFrom,omitempty"`
ActiveTo *time.Time `json:"activeTo,omitempty"`
}
type CreateSubscriptionEntityInput ¶
type CreateSubscriptionEntityInput struct {
models.CadencedModel
models.NamespacedModel
models.MetadataModel
productcatalog.Alignment
Plan *PlanRef
Name string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
CustomerId string `json:"customerId,omitempty"`
Currency currencyx.Code
}
type CreateSubscriptionItemCustomerInput ¶
type CreateSubscriptionItemCustomerInput struct {
ActiveFromOverrideRelativeToPhaseStart *isodate.Period `json:"activeFromOverrideRelativeToPhaseStart"`
ActiveToOverrideRelativeToPhaseStart *isodate.Period `json:"activeToOverrideRelativeToPhaseStart,omitempty"`
BillingBehaviorOverride
}
type CreateSubscriptionItemEntityInput ¶
type CreateSubscriptionItemEntityInput struct {
models.NamespacedModel
models.MetadataModel
ActiveFromOverrideRelativeToPhaseStart *isodate.Period
ActiveToOverrideRelativeToPhaseStart *isodate.Period
models.CadencedModel
BillingBehaviorOverride BillingBehaviorOverride
// PhaseID is the ID of the phase this item belongs to.
PhaseID string
// Key is the unique key of the item in the phase.
Key string
RateCard productcatalog.RateCard
EntitlementID *string
Name string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
}
func (CreateSubscriptionItemEntityInput) Equal ¶
func (i CreateSubscriptionItemEntityInput) Equal(other CreateSubscriptionItemEntityInput) bool
type CreateSubscriptionItemInput ¶
type CreateSubscriptionItemInput struct {
CreateSubscriptionItemPlanInput `json:",inline"`
CreateSubscriptionItemCustomerInput `json:",inline"`
}
type CreateSubscriptionItemPlanInput ¶
type CreateSubscriptionItemPlanInput struct {
PhaseKey string `json:"phaseKey"`
ItemKey string `json:"itemKey"`
RateCard productcatalog.RateCard `json:"rateCard"`
}
func (*CreateSubscriptionItemPlanInput) UnmarshalJSON ¶
func (i *CreateSubscriptionItemPlanInput) UnmarshalJSON(b []byte) error
type CreateSubscriptionPhaseCustomerInput ¶
type CreateSubscriptionPhaseCustomerInput struct {
models.MetadataModel `json:",inline"`
}
type CreateSubscriptionPhaseEntityInput ¶
type CreateSubscriptionPhaseEntityInput struct {
models.NamespacedModel
models.MetadataModel
// ActiveFrom is the time the phase becomes active.
ActiveFrom time.Time
// SubscriptionID is the ID of the subscription this phase belongs to.
SubscriptionID string `json:"subscriptionId"`
// Key is the unique key for Phase.
Key string `json:"key"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
// StartAfter
StartAfter isodate.Period `json:"interval"`
}
func (CreateSubscriptionPhaseEntityInput) Equal ¶
func (i CreateSubscriptionPhaseEntityInput) Equal(other CreateSubscriptionPhaseEntityInput) bool
type CreateSubscriptionPhaseInput ¶
type CreateSubscriptionPhaseInput struct {
// Duration is required exactly in cases where the phase wouldn't be the last phase.
Duration *isodate.Period `json:"duration"`
CreateSubscriptionPhasePlanInput
CreateSubscriptionPhaseCustomerInput
}
func (CreateSubscriptionPhaseInput) Validate ¶
func (i CreateSubscriptionPhaseInput) Validate() error
type CreateSubscriptionPhasePlanInput ¶
type CreateSubscriptionPhasePlanInput struct {
PhaseKey string `json:"key"`
StartAfter isodate.Period `json:"startAfter"`
Name string `json:"name"`
Description *string `json:"description,omitempty"`
}
func (CreateSubscriptionPhasePlanInput) Validate ¶
func (i CreateSubscriptionPhasePlanInput) Validate() error
type CreateSubscriptionPlanInput ¶
type CreateSubscriptionPlanInput struct {
Plan *PlanRef `json:"plan"`
productcatalog.Alignment
}
type CreatedEvent ¶
type CreatedEvent viewEvent
func NewCreatedEvent ¶
func NewCreatedEvent(ctx context.Context, view SubscriptionView) CreatedEvent
NewCreatedEvent creates a new created event
func (CreatedEvent) EventMetadata ¶
func (s CreatedEvent) EventMetadata() metadata.EventMetadata
func (CreatedEvent) EventName ¶
func (s CreatedEvent) EventName() string
func (CreatedEvent) Validate ¶
func (s CreatedEvent) Validate() error
type DeletedEvent ¶
type DeletedEvent viewEvent
func NewDeletedEvent ¶
func NewDeletedEvent(ctx context.Context, view SubscriptionView) DeletedEvent
NewDeletedEvent creates a new deleted event
func (DeletedEvent) EventMetadata ¶
func (s DeletedEvent) EventMetadata() metadata.EventMetadata
func (DeletedEvent) EventName ¶
func (s DeletedEvent) EventName() string
func (DeletedEvent) Validate ¶
func (s DeletedEvent) Validate() error
type EntitlementAdapter ¶
type EntitlementAdapter interface {
ScheduleEntitlement(ctx context.Context, input ScheduleSubscriptionEntitlementInput, annotations models.Annotations) (*SubscriptionEntitlement, error)
// At refers to a point in time for which we're querying the system state, meaning:
// if t1 < t2 < t3, and some entitlement was deleted effective at t2, then
// with at = t1 the entitlement will be returned, while with at = t3 it won't.
GetForSubscriptionAt(ctx context.Context, subscriptionID models.NamespacedID, at time.Time) ([]SubscriptionEntitlement, error)
DeleteByItemID(ctx context.Context, itemId models.NamespacedID) error
}
type ItemNotFoundError ¶
type ItemNotFoundError struct {
// contains filtered or unexported fields
}
ItemNotFoundError is returned when a meter is not found.
func (*ItemNotFoundError) Error ¶
func (e *ItemNotFoundError) Error() string
Error returns the error message.
func (*ItemNotFoundError) Unwrap ¶
func (e *ItemNotFoundError) Unwrap() error
Unwrap returns the wrapped error.
type ListSubscriptionsInput ¶
type ListSubscriptionsInput struct {
pagination.Page
Namespaces []string
Customers []string
ActiveAt *time.Time
}
func (ListSubscriptionsInput) Validate ¶
func (i ListSubscriptionsInput) Validate() error
type NoBillingPeriodError ¶
type NoBillingPeriodError struct {
Inner error
}
NoBillingPeriodError is an error that occurs when a phase has no billing period.
func (NoBillingPeriodError) Error ¶
func (e NoBillingPeriodError) Error() string
func (NoBillingPeriodError) Unwrap ¶
func (e NoBillingPeriodError) Unwrap() error
type NoOpSubscriptionValidator ¶
type NoOpSubscriptionValidator struct{}
func (NoOpSubscriptionValidator) ValidateCancel ¶
func (NoOpSubscriptionValidator) ValidateCancel(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateContinue ¶
func (NoOpSubscriptionValidator) ValidateContinue(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateCreate ¶
func (NoOpSubscriptionValidator) ValidateCreate(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateDelete ¶
func (NoOpSubscriptionValidator) ValidateDelete(context.Context, SubscriptionView) error
func (NoOpSubscriptionValidator) ValidateUpdate ¶
func (NoOpSubscriptionValidator) ValidateUpdate(context.Context, SubscriptionView) error
type Patch ¶
type Patch interface {
AppliesToSpec
Validate() error
Op() PatchOperation
Path() SpecPath
}
type PatchConflictError ¶
type PatchConflictError struct {
Msg string
}
func (*PatchConflictError) Error ¶
func (e *PatchConflictError) Error() string
type PatchForbiddenError ¶
type PatchForbiddenError struct {
Msg string
}
func (*PatchForbiddenError) Error ¶
func (e *PatchForbiddenError) Error() string
type PatchOperation ¶
type PatchOperation string
const ( PatchOperationAdd PatchOperation = "add" PatchOperationRemove PatchOperation = "remove" PatchOperationUnschedule PatchOperation = "unschedule" PatchOperationStretch PatchOperation = "stretch" )
func (PatchOperation) Validate ¶
func (o PatchOperation) Validate() error
type PatchValidationError ¶
type PatchValidationError struct {
Msg string
}
func (*PatchValidationError) Error ¶
func (e *PatchValidationError) Error() string
type PhaseNotFoundError ¶
type PhaseNotFoundError struct {
// contains filtered or unexported fields
}
PhaseNotFoundError is returned when a meter is not found.
func (*PhaseNotFoundError) Error ¶
func (e *PhaseNotFoundError) Error() string
Error returns the error message.
func (*PhaseNotFoundError) Unwrap ¶
func (e *PhaseNotFoundError) Unwrap() error
Unwrap returns the wrapped error.
type Plan ¶
type Plan interface {
ToCreateSubscriptionPlanInput() CreateSubscriptionPlanInput
GetName() string
// Phases are expected to be returned in the order they activate.
GetPhases() []PlanPhase
// Will not make sense on the long term
Currency() currencyx.Code
}
All methods are expected to return stable values.
type PlanNotFoundError ¶
type PlanNotFoundError struct {
// contains filtered or unexported fields
}
PlanNotFoundError is returned when a meter is not found.
func (*PlanNotFoundError) Error ¶
func (e *PlanNotFoundError) Error() string
Error returns the error message.
func (*PlanNotFoundError) Unwrap ¶
func (e *PlanNotFoundError) Unwrap() error
Unwrap returns the wrapped error.
type PlanPhase ¶
type PlanPhase interface {
ToCreateSubscriptionPhasePlanInput() CreateSubscriptionPhasePlanInput
GetRateCards() []PlanRateCard
GetKey() string
}
All methods are expected to return stable values.
type PlanRateCard ¶
type PlanRateCard interface {
ToCreateSubscriptionItemPlanInput() CreateSubscriptionItemPlanInput
GetKey() string
}
All methods are expected to return stable values.
type RemoveSubscriptionPhaseInput ¶
type RemoveSubscriptionPhaseInput struct {
Shift RemoveSubscriptionPhaseShifting `json:"shift"`
}
type RemoveSubscriptionPhaseShifting ¶
type RemoveSubscriptionPhaseShifting int
const ( RemoveSubscriptionPhaseShiftNext RemoveSubscriptionPhaseShifting = iota RemoveSubscriptionPhaseShiftPrev )
func (RemoveSubscriptionPhaseShifting) Validate ¶
func (s RemoveSubscriptionPhaseShifting) Validate() error
type ScheduleSubscriptionEntitlementInput ¶
type ScheduleSubscriptionEntitlementInput struct {
entitlement.CreateEntitlementInputs
}
func (ScheduleSubscriptionEntitlementInput) Equal ¶
func (s ScheduleSubscriptionEntitlementInput) Equal(other ScheduleSubscriptionEntitlementInput) bool
func (ScheduleSubscriptionEntitlementInput) Validate ¶
func (s ScheduleSubscriptionEntitlementInput) Validate() error
type Service ¶
type Service interface {
// Create a new subscription accotding to the given spec
Create(ctx context.Context, namespace string, spec SubscriptionSpec) (Subscription, error)
// Update the subscription with the given ID to the target spec
Update(ctx context.Context, subscriptionID models.NamespacedID, target SubscriptionSpec) (Subscription, error)
// Delete a scheduled subscription with the given ID
Delete(ctx context.Context, subscriptionID models.NamespacedID) error
// Cancel a running subscription at the provided time
Cancel(ctx context.Context, subscriptionID models.NamespacedID, timing Timing) (Subscription, error)
// Continue a canceled subscription (effectively undoing the cancellation)
Continue(ctx context.Context, subscriptionID models.NamespacedID) (Subscription, error)
// Get the subscription with the given ID
Get(ctx context.Context, subscriptionID models.NamespacedID) (Subscription, error)
// GetView returns a full view of the subscription with the given ID
GetView(ctx context.Context, subscriptionID models.NamespacedID) (SubscriptionView, error)
// List lists the subscriptions matching the set criteria
List(ctx context.Context, params ListSubscriptionsInput) (SubscriptionList, error)
// GetAllForCustomerSince returns all subscriptions for the given customer that are active or scheduled to start after the given timestamp
GetAllForCustomerSince(ctx context.Context, customerID models.NamespacedID, at time.Time) ([]Subscription, error)
ValidatorService
}
type SpecPath ¶
type SpecPath string
func NewItemPath ¶
func NewItemVersionPath ¶
func NewPhasePath ¶
func (SpecPath) IsParentOf ¶
Checks whether p is a parent of other where parent means all segments of p are present and in order in other
func (SpecPath) ItemVersion ¶
func (SpecPath) MarshalJSON ¶
Lets implement JSON Marshaler for Path
func (SpecPath) Type ¶
func (p SpecPath) Type() SpecPathType
func (*SpecPath) UnmarshalJSON ¶
Lets implement JSON Unmarshaler for Path
type SpecPathType ¶
type SpecPathType string
const ( SpecPathTypePhase SpecPathType = "phase" SpecPathTypeItem SpecPathType = "item" SpecPathTypeItemVersion SpecPathType = "item_version" )
type SpecValidationError ¶
func (*SpecValidationError) Error ¶
func (e *SpecValidationError) Error() string
type Subscription ¶
type Subscription struct {
models.NamespacedID
models.ManagedModel
models.CadencedModel
models.MetadataModel
productcatalog.Alignment
Name string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
// References the plan (if the Subscription was created form one)
PlanRef *PlanRef `json:"planRef"`
CustomerId string `json:"customerId,omitempty"`
Currency currencyx.Code `json:"currency,omitempty"`
}
func (Subscription) AsEntityInput ¶
func (s Subscription) AsEntityInput() CreateSubscriptionEntityInput
func (Subscription) GetStatusAt ¶
func (s Subscription) GetStatusAt(at time.Time) SubscriptionStatus
type SubscriptionAction ¶
type SubscriptionAction string
const ( SubscriptionActionCreate SubscriptionAction = "create" SubscriptionActionUpdate SubscriptionAction = "update" SubscriptionActionCancel SubscriptionAction = "cancel" SubscriptionActionContinue SubscriptionAction = "continue" SubscriptionActionDelete SubscriptionAction = "delete" )
type SubscriptionEntitlement ¶
type SubscriptionEntitlement struct {
Entitlement entitlement.Entitlement
Cadence models.CadencedModel
}
func (SubscriptionEntitlement) ToScheduleSubscriptionEntitlementInput ¶
func (s SubscriptionEntitlement) ToScheduleSubscriptionEntitlementInput() ScheduleSubscriptionEntitlementInput
func (SubscriptionEntitlement) Validate ¶
func (s SubscriptionEntitlement) Validate() error
type SubscriptionItem ¶
type SubscriptionItem struct {
models.NamespacedID `json:",inline"`
models.ManagedModel `json:",inline"`
models.MetadataModel `json:",inline"`
// SubscriptionItem doesn't have a separate Cadence, only one relative to the phase, denoting if it's intentionally different from the phase's cadence.
// The durations are relative to phase start.
ActiveFromOverrideRelativeToPhaseStart *isodate.Period `json:"activeFromOverrideRelativeToPhaseStart,omitempty"`
ActiveToOverrideRelativeToPhaseStart *isodate.Period `json:"activeToOverrideRelativeToPhaseStart,omitempty"`
// The defacto cadence of the item is calculated and persisted after each change.
models.CadencedModel `json:",inline"`
BillingBehaviorOverride BillingBehaviorOverride `json:"billingBehaviorOverride"`
// SubscriptionID is the ID of the subscription this item belongs to.
SubscriptionId string `json:"subscriptionId"`
// PhaseID is the ID of the phase this item belongs to.
PhaseId string `json:"phaseId"`
// Key is the unique key of the item in the phase.
Key string `json:"itemKey"`
RateCard productcatalog.RateCard `json:"rateCard"`
EntitlementID *string `json:"entitlementId,omitempty"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
}
func (SubscriptionItem) AsEntityInput ¶
func (i SubscriptionItem) AsEntityInput() CreateSubscriptionItemEntityInput
func (SubscriptionItem) GetCadence ¶
func (i SubscriptionItem) GetCadence(phaseCadence models.CadencedModel) models.CadencedModel
func (*SubscriptionItem) UnmarshalJSON ¶
func (i *SubscriptionItem) UnmarshalJSON(b []byte) error
type SubscriptionItemRef ¶
type SubscriptionItemRef struct {
SubscriptionId string `json:"subscriptionId"`
PhaseKey string `json:"phaseKey"`
ItemKey string `json:"itemKey"`
}
SubscriptionItemRef is an unstable reference to a SubscriptionItem
func (SubscriptionItemRef) Equals ¶
func (r SubscriptionItemRef) Equals(r2 SubscriptionItemRef) bool
type SubscriptionItemRepository ¶
type SubscriptionItemRepository interface {
entutils.TxCreator
GetForSubscriptionAt(ctx context.Context, subscriptionID models.NamespacedID, at time.Time) ([]SubscriptionItem, error)
Create(ctx context.Context, input CreateSubscriptionItemEntityInput) (SubscriptionItem, error)
Delete(ctx context.Context, id models.NamespacedID) error
GetByID(ctx context.Context, id models.NamespacedID) (SubscriptionItem, error)
}
type SubscriptionItemSpec ¶
type SubscriptionItemSpec struct {
CreateSubscriptionItemInput `json:",inline"`
}
func (SubscriptionItemSpec) GetCadence ¶
func (s SubscriptionItemSpec) GetCadence(phaseCadence models.CadencedModel) models.CadencedModel
func (SubscriptionItemSpec) GetRef ¶
func (s SubscriptionItemSpec) GetRef(subId string) SubscriptionItemRef
func (SubscriptionItemSpec) ToCreateSubscriptionItemEntityInput ¶
func (s SubscriptionItemSpec) ToCreateSubscriptionItemEntityInput( phaseID models.NamespacedID, phaseCadence models.CadencedModel, entitlement *entitlement.Entitlement, ) (CreateSubscriptionItemEntityInput, error)
func (SubscriptionItemSpec) ToScheduleSubscriptionEntitlementInput ¶
func (s SubscriptionItemSpec) ToScheduleSubscriptionEntitlementInput( opts ToScheduleSubscriptionEntitlementInputOptions, ) (ScheduleSubscriptionEntitlementInput, bool, error)
func (*SubscriptionItemSpec) Validate ¶
func (s *SubscriptionItemSpec) Validate() error
type SubscriptionItemView ¶
type SubscriptionItemView struct {
SubscriptionItem SubscriptionItem `json:"subscriptionItem"`
Spec SubscriptionItemSpec `json:"spec"`
Entitlement *SubscriptionEntitlement `json:"entitlement,omitempty"`
Feature *feature.Feature `json:"feature,omitempty"`
}
func (*SubscriptionItemView) AsSpec ¶
func (s *SubscriptionItemView) AsSpec() SubscriptionItemSpec
func (*SubscriptionItemView) Validate ¶
func (s *SubscriptionItemView) Validate() error
type SubscriptionList ¶
type SubscriptionList = pagination.PagedResponse[Subscription]
type SubscriptionNotFoundError ¶
type SubscriptionNotFoundError struct {
// contains filtered or unexported fields
}
SubscriptionNotFoundError is returned when a meter is not found.
func (*SubscriptionNotFoundError) Error ¶
func (e *SubscriptionNotFoundError) Error() string
Error returns the error message.
func (*SubscriptionNotFoundError) Unwrap ¶
func (e *SubscriptionNotFoundError) Unwrap() error
Unwrap returns the wrapped error.
type SubscriptionPhase ¶
type SubscriptionPhase struct {
models.NamespacedID `json:",inline"`
models.ManagedModel `json:",inline"`
models.MetadataModel `json:",inline"`
ActiveFrom time.Time `json:"activeFrom"`
// SubscriptionID is the ID of the subscription this phase belongs to.
SubscriptionID string `json:"subscriptionId"`
// Key is the unique key for Phase.
Key string `json:"key"`
// Name
Name string `json:"name"`
// Description
Description *string `json:"description,omitempty"`
}
type SubscriptionPhaseRepository ¶
type SubscriptionPhaseRepository interface {
entutils.TxCreator
// Returns the phases for a subscription
GetForSubscriptionAt(ctx context.Context, subscriptionID models.NamespacedID, at time.Time) ([]SubscriptionPhase, error)
// Create a new subscription phase
Create(ctx context.Context, input CreateSubscriptionPhaseEntityInput) (SubscriptionPhase, error)
Delete(ctx context.Context, id models.NamespacedID) error
}
type SubscriptionPhaseSpec ¶
type SubscriptionPhaseSpec struct {
// Duration is not part of the Spec by design
CreateSubscriptionPhasePlanInput `json:",inline"`
CreateSubscriptionPhaseCustomerInput `json:",inline"`
// In each key, for each phase, we have a list of item specs to account for mid-phase changes
ItemsByKey map[string][]*SubscriptionItemSpec `json:"itemsByKey"`
}
func (SubscriptionPhaseSpec) GetBillableItemsByKey ¶
func (s SubscriptionPhaseSpec) GetBillableItemsByKey() map[string][]*SubscriptionItemSpec
GetBillableItemsByKey returns a map of billable items by key
func (SubscriptionPhaseSpec) GetBillingCadence ¶
func (s SubscriptionPhaseSpec) GetBillingCadence() (isodate.Period, error)
func (SubscriptionPhaseSpec) HasBillables ¶
func (s SubscriptionPhaseSpec) HasBillables() bool
func (SubscriptionPhaseSpec) HasEntitlements ¶
func (s SubscriptionPhaseSpec) HasEntitlements() bool
func (SubscriptionPhaseSpec) HasMeteredBillables ¶
func (s SubscriptionPhaseSpec) HasMeteredBillables() bool
func (SubscriptionPhaseSpec) ToCreateSubscriptionPhaseEntityInput ¶
func (s SubscriptionPhaseSpec) ToCreateSubscriptionPhaseEntityInput( subscription Subscription, activeFrom time.Time, ) CreateSubscriptionPhaseEntityInput
func (SubscriptionPhaseSpec) Validate ¶
func (s SubscriptionPhaseSpec) Validate( phaseCadence models.CadencedModel, alignment productcatalog.Alignment, ) error
type SubscriptionPhaseView ¶
type SubscriptionPhaseView struct {
SubscriptionPhase SubscriptionPhase `json:"subscriptionPhase"`
Spec SubscriptionPhaseSpec `json:"spec"`
ItemsByKey map[string][]SubscriptionItemView `json:"itemsByKey"`
}
func (*SubscriptionPhaseView) ActiveFrom ¶
func (s *SubscriptionPhaseView) ActiveFrom(subscriptionCadence models.CadencedModel) time.Time
func (*SubscriptionPhaseView) AsSpec ¶
func (s *SubscriptionPhaseView) AsSpec() SubscriptionPhaseSpec
func (*SubscriptionPhaseView) Validate ¶
func (s *SubscriptionPhaseView) Validate(includeItems bool) error
type SubscriptionRepository ¶
type SubscriptionRepository interface {
entutils.TxCreator
models.CadencedResourceRepo[Subscription]
// Returns all subscriptions active or scheduled after the given timestamp
GetAllForCustomerSince(ctx context.Context, customerID models.NamespacedID, at time.Time) ([]Subscription, error)
// Returns the subscription by ID
GetByID(ctx context.Context, subscriptionID models.NamespacedID) (Subscription, error)
// Create a new subscription
Create(ctx context.Context, input CreateSubscriptionEntityInput) (Subscription, error)
// Delete a subscription
Delete(ctx context.Context, id models.NamespacedID) error
// List subscriptions
List(ctx context.Context, params ListSubscriptionsInput) (SubscriptionList, error)
}
type SubscriptionSpec ¶
type SubscriptionSpec struct {
CreateSubscriptionPlanInput `json:",inline"`
CreateSubscriptionCustomerInput `json:",inline"`
// We use pointers so Patches can manipulate the spec
Phases map[string]*SubscriptionPhaseSpec `json:"phases"`
}
func NewSpecFromPlan ¶
func NewSpecFromPlan(p Plan, c CreateSubscriptionCustomerInput) (SubscriptionSpec, error)
NewSpecFromPlan creates a SubscriptionSpec from a Plan and a CreateSubscriptionCustomerInput.
func (*SubscriptionSpec) Apply ¶
func (s *SubscriptionSpec) Apply(applies AppliesToSpec, context ApplyContext) error
func (*SubscriptionSpec) ApplyMany ¶
func (s *SubscriptionSpec) ApplyMany(applieses []AppliesToSpec, aCtx ApplyContext) error
func (*SubscriptionSpec) GetAlignedBillingPeriodAt ¶
func (s *SubscriptionSpec) GetAlignedBillingPeriodAt(phaseKey string, at time.Time) (timeutil.ClosedPeriod, error)
For a phase in an Aligned subscription, there's a single aligned BillingPeriod for all items in that phase. The period starts with the phase and iterates every BillingCadence duration, but can be reanchored to the time of an edit.
func (*SubscriptionSpec) GetCurrentPhaseAt ¶
func (s *SubscriptionSpec) GetCurrentPhaseAt(t time.Time) (*SubscriptionPhaseSpec, bool)
func (*SubscriptionSpec) GetPhaseCadence ¶
func (s *SubscriptionSpec) GetPhaseCadence(phaseKey string) (models.CadencedModel, error)
func (*SubscriptionSpec) GetSortedPhases ¶
func (s *SubscriptionSpec) GetSortedPhases() []*SubscriptionPhaseSpec
GetSortedPhases returns the subscription phase references time sorted order ASC.
func (*SubscriptionSpec) HasBillables ¶
func (s *SubscriptionSpec) HasBillables() bool
func (*SubscriptionSpec) HasEntitlements ¶
func (s *SubscriptionSpec) HasEntitlements() bool
func (*SubscriptionSpec) HasMeteredBillables ¶
func (s *SubscriptionSpec) HasMeteredBillables() bool
func (*SubscriptionSpec) ToCreateSubscriptionEntityInput ¶
func (s *SubscriptionSpec) ToCreateSubscriptionEntityInput(ns string) CreateSubscriptionEntityInput
func (*SubscriptionSpec) Validate ¶
func (s *SubscriptionSpec) Validate() error
type SubscriptionStateMachine ¶
type SubscriptionStateMachine struct {
// contains filtered or unexported fields
}
SubscriptionStateMachine is a very simple state machine that determines what actions can be taken on a Subscription
func NewStateMachine ¶
func NewStateMachine(status SubscriptionStatus) SubscriptionStateMachine
func (SubscriptionStateMachine) CanTransitionOrErr ¶
func (sm SubscriptionStateMachine) CanTransitionOrErr(ctx context.Context, action SubscriptionAction) error
type SubscriptionStatus ¶
type SubscriptionStatus string
const ( // Active means the subscription is active and the customer is being billed SubscriptionStatusActive SubscriptionStatus = "active" // Canceled means the subscription has already been canceled but is still active SubscriptionStatusCanceled SubscriptionStatus = "canceled" // Inactive means the subscription is inactive (might have been previously active) and the customer is not being billed SubscriptionStatusInactive SubscriptionStatus = "inactive" // Scheduled means the subscription is scheduled to be active in the future SubscriptionStatusScheduled SubscriptionStatus = "scheduled" )
func (SubscriptionStatus) Validate ¶
func (s SubscriptionStatus) Validate() error
type SubscriptionValidator ¶
type SubscriptionValidator interface {
ValidateCreate(context.Context, SubscriptionView) error
ValidateUpdate(context.Context, SubscriptionView) error
ValidateCancel(context.Context, SubscriptionView) error
ValidateContinue(context.Context, SubscriptionView) error
ValidateDelete(context.Context, SubscriptionView) error
}
type SubscriptionView ¶
type SubscriptionView struct {
Subscription Subscription `json:"subscription"`
Customer customer.Customer `json:"customer"`
Spec SubscriptionSpec `json:"spec"`
Phases []SubscriptionPhaseView `json:"phases"`
}
func NewSubscriptionView ¶
func NewSubscriptionView( sub Subscription, cust customer.Customer, phases []SubscriptionPhase, items []SubscriptionItem, ents []SubscriptionEntitlement, entFeats []feature.Feature, itemFeats []feature.Feature, ) (*SubscriptionView, error)
func (SubscriptionView) AsSpec ¶
func (s SubscriptionView) AsSpec() SubscriptionSpec
func (SubscriptionView) GetPhaseByKey ¶
func (s SubscriptionView) GetPhaseByKey(key string) (*SubscriptionPhaseView, bool)
func (*SubscriptionView) Validate ¶
func (s *SubscriptionView) Validate(includePhases bool) error
type Timing ¶
type Timing struct {
Custom *time.Time
Enum *TimingEnum
}
Timing represents the timing of a change in a subscription, such as a plan change or a cancellation.
func (Timing) ResolveForSpec ¶
func (c Timing) ResolveForSpec(spec SubscriptionSpec) (time.Time, error)
func (Timing) ValidateForAction ¶
func (c Timing) ValidateForAction(action SubscriptionAction, subView *SubscriptionView) error
type TimingEnum ¶
type TimingEnum string
const ( // Immediate means the change will take effect immediately. TimingImmediate TimingEnum = "immediate" // NextBillingCycle means the change will take effect at the start of the next billing cycle. // This value is only supported for aligned subscriptions. TimingNextBillingCycle TimingEnum = "next_billing_cycle" )
func (TimingEnum) Validate ¶
func (c TimingEnum) Validate() error
type ToScheduleSubscriptionEntitlementInputOptions ¶
type ToScheduleSubscriptionEntitlementInputOptions struct {
Customer customer.Customer
Cadence models.CadencedModel
PhaseCadence models.CadencedModel
IsAligned bool
}
type UpdatedEvent ¶
type UpdatedEvent struct {
// We can consider adding the old version or diff here if needed
UpdatedView SubscriptionView `json:"updatedView"`
UserID *string `json:"userId,omitempty"`
}
func NewUpdatedEvent ¶
func NewUpdatedEvent(ctx context.Context, view SubscriptionView) UpdatedEvent
NewUpdatedEvent creates a new updated event
func (UpdatedEvent) EventMetadata ¶
func (s UpdatedEvent) EventMetadata() metadata.EventMetadata
func (UpdatedEvent) EventName ¶
func (s UpdatedEvent) EventName() string
func (UpdatedEvent) Validate ¶
func (s UpdatedEvent) Validate() error
type ValidatorService ¶
type ValidatorService interface {
RegisterValidator(SubscriptionValidator) error
}
type ValuePatch ¶
type ValuePatch[T any] interface { Patch Value() T AnyValuePatch }