AuroraMeter.Entitlements (Aurora Meter v0.1.0)

View Source

Plan resolution and the entitlement gate.

Semantics (see plan.md D12): a :hard limit blocks at its cap; a :metered feature is always allowed (overage is billed); a {:feature, false} is denied; an undeclared feature is permissive. with_quota/4 reserves atomically so hard limits are correct under concurrency, releasing the reservation if the wrapped function raises.

Summary

Types

Result of an entitlement check.

Functions

Whether check/2 currently returns :ok.

Checks whether tenant may use feature right now.

Whether the tenant's plan grants access to feature at all (ignores quota).

Returns the plan for tenant (its subscription's plan, else the default).

Remaining quota for a hard-limited feature, or :unlimited.

Atomically reserves qty of feature against the plan (increments the counter).

Assigns plan_id to tenant locally (no billing provider).

Gates, runs, and meters in one atomic step.

Types

check_result()

@type check_result() :: :ok | {:error, :limit_exceeded | :not_entitled}

Result of an entitlement check.

Functions

allowed?(tenant, feature)

@spec allowed?(term(), atom()) :: boolean()

Whether check/2 currently returns :ok.

check(tenant, feature)

@spec check(term(), atom()) :: check_result()

Checks whether tenant may use feature right now.

entitled?(tenant, feature)

@spec entitled?(term(), atom()) :: boolean()

Whether the tenant's plan grants access to feature at all (ignores quota).

plan(tenant)

@spec plan(term()) :: AuroraMeter.Plan.t() | nil

Returns the plan for tenant (its subscription's plan, else the default).

remaining(tenant, feature)

@spec remaining(term(), atom()) :: non_neg_integer() | :unlimited

Remaining quota for a hard-limited feature, or :unlimited.

reserve(tenant, feature, qty \\ 1)

@spec reserve(term(), atom(), pos_integer()) ::
  :ok | {:error, :limit_exceeded | :not_entitled}

Atomically reserves qty of feature against the plan (increments the counter).

subscribe(tenant, plan_id)

@spec subscribe(term(), atom() | String.t()) ::
  {:ok, AuroraMeter.Schema.Subscription.t()} | {:error, Ecto.Changeset.t()}

Assigns plan_id to tenant locally (no billing provider).

with_quota(tenant, feature, fun)

@spec with_quota(term(), atom(), (-> result)) :: {:ok, result} | {:error, term()}
when result: term()

Gates, runs, and meters in one atomic step.

Reserves qty of feature; if allowed, runs fun and returns {:ok, result} (the reservation is the usage). If the reservation is denied, returns {:error, reason} without running fun. If fun raises, the reservation is released and the error re-raised.

with_quota(tenant, feature, qty, fun)

@spec with_quota(term(), atom(), pos_integer(), (-> result)) ::
  {:ok, result} | {:error, term()}
when result: term()