featuremeter

package
v1.0.0-beta.236 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

README

Billing feature-meter resolution

  • This package overlaps with the newer product catalog feature resolvers.
  • It predates those resolvers and should eventually converge with them rather than remain a separate resolution path.
  • Convergence is only safe after feature IDs are snapshotted throughout every product catalog layer, including subscriptions, and existing database records have been backfilled. Until then, this package's historical lookup behavior is what allows billing to invoice archived features.

Purpose and ownership

This package defines the feature-meter contracts used to rate and invoice billing lines. The service subpackage owns catalog access and the concrete resolved collection. This keeps billing's domain contracts independent from the resolver implementation while retaining a billing-specific compatibility boundary rather than a canonical product catalog resolver.

Billing data may still refer to a feature by key. Keys identify the current logical feature, while IDs identify a specific persisted version. The resolver therefore returns collections addressable by both key and ID and lets callers declare whether a meter association is required.

Historical resolution

Resolution deliberately includes archived features and deleted meters. This preserves the definitions required by historical or pending invoices after the corresponding catalog resources have been archived.

For a key, the collection selects the active feature when one exists. If all features with that key are archived, it selects the most recently archived one. Every returned feature remains addressable by its exact ID, including older archived versions. A meter is attached by its snapshotted meter ID even when that meter has since been deleted.

These semantics are compatibility behavior. Once all billing inputs carry snapshotted feature IDs and existing records are backfilled, billing should use the product catalog resolver path and this package can be converged into it.

Validation contract

By default, every requested feature must exist. A missing feature or required meter is returned as a critical validation issue. Persisted gathering lines and charges additionally implement the optional owner contract, which scopes the issue to that entity. Pre-persistence intents and static references do not claim an owner and therefore produce issues without an entity path. Validation issues retain the requested feature ID or key and, when the feature resolves, its canonical ID, key, and known meter ID or legacy slug as attributes.

Resolution accepts billing entities that provide an optional feature-meter reference. Entities without a feature dependency are skipped. Duplicate ID or key references are fetched once, then every original entity is validated so each failure retains its line or charge identity. The resolved collection is returned alongside validation failures. Callers may continue with that partial collection only after splitting the error into validation issues and confirming that no system error remains. Feature and meter service failures remain fatal.

FeatureMeterRef is only the dependency value returned by those entities; it is intentionally not itself a resolution or lookup target. This prevents callers from discarding the originating line or charge identity while mapping references for resolution.

Collection lookups accept the same entity references. An explicit feature ID takes precedence when a reference also contains a key, preserving access to the exact historical feature version. Get rejects an empty reference, while Has returns false for one and checks only feature existence, not the meter requirement. When a feature exists but its required meter is absent, Get returns both the resolved feature and the validation error so callers can retain usable billing output.

The service subpackage constructs billing validation issues directly. Higher level billing services own the validation component and remain responsible for deciding whether a workflow can continue with the returned collection and validation issues.

Why resolution is lazy

Charge advancement also acts as reconciliation and can inspect charges that are not due. Determining that no transition can fire does not require their feature or meter, so eager catalog resolution would let an unused missing meter or catalog outage block otherwise independent work.

The lazy collection snapshots feature references and usable owner identities when it is created, then resolves the snapshot once on the first Get or Has. This preserves a consistent view for the operation without repeating catalog queries. Get returns resolution failures when the dependency is actually consumed, while Has reports false after a failed resolution. Missing features and meters therefore remain validation failures on paths that need them, and catalog system errors remain fatal.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FeatureMeter

type FeatureMeter struct {
	Feature feature.Feature
	Meter   *meter.Meter
}

type FeatureMeterRef

type FeatureMeterRef struct {
	IDOrKey      ref.IDOrKey
	RequireMeter bool
}

func (*FeatureMeterRef) CloneIfPresent

func (r *FeatureMeterRef) CloneIfPresent() *FeatureMeterRef

type FeatureMeters

type FeatureMeters interface {
	Get(reference FeatureReferenceGetter) (FeatureMeter, error)
	Has(reference FeatureReferenceGetter) bool
}

type FeatureReferenceGetter

type FeatureReferenceGetter interface {
	GetFeatureMeterRef() *FeatureMeterRef
}

FeatureReferenceGetter provides the feature and meter dependency of a billing entity. A nil reference means that the entity has no feature dependency.

func WithoutMeters

func WithoutMeters(reference FeatureReferenceGetter) FeatureReferenceGetter

WithoutMeters returns a feature-only copy of a reference. The returned reference deliberately does not retain the owner's identity.

type FeatureReferenceIdentity

type FeatureReferenceIdentity struct {
	Kind FeatureReferenceKind
	ID   string
}

type FeatureReferenceKind

type FeatureReferenceKind string
const (
	FeatureReferenceKindLines   FeatureReferenceKind = "lines"
	FeatureReferenceKindCharges FeatureReferenceKind = "charges"
)

type FeatureReferenceOwner

type FeatureReferenceOwner interface {
	GetFeatureMeterOwner() FeatureReferenceIdentity
}

FeatureReferenceOwner provides the stable identity of the billing entity that owns a feature reference. Reference types without a stable identity must not implement this interface.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL