API inventory
Everything Aurora Meter Pro offers a host application, with a stability class per entry. It is the authority for what the support policy covers: see Support policy.
If something is not on this page, it is not part of the supported surface, even when the module or function happens to be public in the compiled code.
test/aurora_meter/pro/api_inventory_test.exs checks this page against the code
on every mix test. Every Module.function/arity below must exist, no internal
module may be listed, every telemetry event and PubSub tag must appear verbatim
in lib/, and the core version requirement in section 12 must match mix.exs.
Aurora Meter Pro is a commercial package. The free core has an inventory of its own, and this page never restates it: core entries are core’s promise, not Pro’s.
How to read this page
| Class | Meaning | Change rule |
|---|---|---|
stable |
Part of the supported surface. | Covered by SemVer. No breaking change before 2.0. Additive change is allowed in a minor release. |
optional-dep |
Stable, but it only exists when an optional dependency is installed. |
Same promise as stable. The dependency’s absence is documented and is never a compile error. |
deprecated |
Still works, warns, and is removed in 2.0. | Never removed during 1.x. |
internal |
Not part of the supported surface. | May change in any release, including a patch. Callers get no warning. |
Since is the package version that introduced the entry. Pro 0.4.0 was never
published, so everything written for it carries 1.0.0, the release that
shipped it.
Test helpers (AuroraMeter.Pro.Stripe.Fake,
AuroraMeter.Pro.Credits.StripeClient.Fake) are stable, but they are for host
test suites. Nothing in production should depend on them, and the support policy
governs them under its own heading rather than by SemVer on every helper name.
1. Facade functions
1.1 AuroraMeter.Pro
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.version/0 |
() :: String.t() |
stable | 0.1.0 | The compiled package version. |
AuroraMeter.Pro.validate!/0 |
() :: keyword() |
stable | 1.0.0 |
Validates the whole :aurora_meter_pro environment against the schema, resolves every {:system, "VAR"} once, and stores the result for the accessors. Raises AuroraMeter.Pro.ConfigError. Safe to call from a release health check. |
AuroraMeter.Pro.start_link/1 |
(keyword()) :: :ignore |
stable | 1.0.0 |
The boot checks: validate!/0, the source cutover refusal, and the Stripe account assertion. Returns :ignore and starts no process, so a supervisor containing it shows nothing under it. Options :validate, :cutover_check, :account_check. |
AuroraMeter.Pro.child_spec/1 |
(keyword()) :: Supervisor.child_spec() |
stable | 1.0.0 |
restart: :transient, which with :ignore is a clean start a supervisor never restarts. Add AuroraMeter.Pro to your tree after your Repo. |
AuroraMeter.Pro.account_confirmed?/0 |
() :: boolean() |
stable | 1.0.0 |
Whether the startup assertion confirmed :stripe_account_id against Stripe on this node. false when the check was skipped, has not run, or could not reach Stripe; a live-mode outbox enqueue then quarantines with :account_unconfirmed. |
1.2 Prepaid credit top-ups
Pro sells credit; the core ledger holds it. Every grant goes through
AuroraMeter.Credits.grant/3 keyed on the Stripe PaymentIntent id, so two
deliveries of one payment fund the account exactly once.
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Credits.checkout/3 |
(tenant, pos_integer(), keyword()) :: {:ok, String.t()} | {:error, :invalid_amount | term()} |
stable | 0.3.0 |
amount_cents, not micro-dollars: this is a Stripe boundary. Arity 2 exists through defaults. |
AuroraMeter.Pro.Credits.checkout_params/3 |
(tenant, pos_integer(), keyword()) :: {:ok, map()} | {:error, :invalid_amount | term()} |
stable | 0.3.0 | Pure. Build the params without calling Stripe, for a host that posts them itself. |
AuroraMeter.Pro.Credits.portal_url/2 |
(tenant, keyword()) :: {:ok, String.t()} | {:error, :no_customer | term()} |
stable | 0.3.0 |
Billing Portal for the credit customer. Option :configuration. |
AuroraMeter.Pro.Credits.account/1 |
(tenant) :: AuroraMeter.Pro.Schema.CreditAccount.t() | nil |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.customer_id/1 |
(tenant) :: String.t() | nil |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.close_account/1 |
(tenant) :: :ok |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.presets_cents/0 |
() :: [pos_integer()] |
stable | 0.3.0 | The configured top-up amounts, for a pricing page. |
AuroraMeter.Pro.Credits.update_auto_top_up/3 |
(tenant, map(), keyword()) :: {:ok, Schema.CreditAccount.t()} | {:error, Ecto.Changeset.t() | :no_payment_method} |
stable | 0.3.0 | Stores a threshold and an amount per tenant and mirrors the threshold to the core’s per-tenant low-balance threshold. Arity 2 exists through defaults. |
AuroraMeter.Pro.Credits.disable_auto_top_up/2 |
(tenant, term()) :: {:ok, Schema.CreditAccount.t()} | {:error, :not_found | Ecto.Changeset.t()} |
stable | 0.3.0 | The second argument is the reason, and it is kept. |
AuroraMeter.Pro.Credits.re_enable_auto_top_up/1 |
(tenant) :: {:ok, Schema.CreditAccount.t()} | {:error, Ecto.Changeset.t() | :no_payment_method} |
stable | 0.3.0 | Clears the disable reason and the failure count. |
AuroraMeter.Pro.Credits.on_low_balance/1 |
(map()) :: :ok | {:error, term()} |
stable | 0.3.0 |
The core hook: config :aurora_meter, credits_low_balance_handler: &AuroraMeter.Pro.Credits.on_low_balance/1. |
AuroraMeter.Pro.Credits.credit_cents/2 |
(non_neg_integer(), map() | nil) :: non_neg_integer() |
stable | 1.1.0 |
Pure. The credit a payment buys: its metadata’s credit_cents when tax went on top (credits_tax: :exclusive), else the whole payment, and never more than was paid. |
AuroraMeter.Pro.Credits.record_payment/4 |
(tenant, String.t(), pos_integer(), map()) :: {:ok, term()} | {:error, term()} |
stable | 0.3.0 | Arity 3 exists through an empty metadata map. |
AuroraMeter.Pro.Credits.record_failure/3 |
(tenant, term(), String.t() | nil) :: {:ok, Schema.CreditAccount.t()} | {:error, :not_found | Ecto.Changeset.t()} |
stable | 0.3.0 |
Arity 2 exists through a nil reference. |
AuroraMeter.Pro.Credits.handle_event/1 |
(map()) :: result() |
stable | 0.3.0 |
The credit half of the webhook. AuroraMeter.Pro.Webhook calls it; a host that routes Stripe events itself may call it directly. Since 1.0.0 it can answer {:refused, reason}: nothing was applied and a redelivery would be refused the same way, so a host routing events itself should answer 200 to that and 500 only to {:error, _}. |
AuroraMeter.Pro.Credits.notify/1 |
(term()) :: :ok |
stable | 0.3.0 |
Sends one event to the configured :credits_handler. |
AuroraMeter.Pro.Credits.with_lock/2 |
(String.t(), (-> result)) :: result |
stable | 0.3.0 | The advisory lock the webhook handlers already take, so a host can serialise its own work on the same tenant key. |
AuroraMeter.Pro.Credits.AutoTopUpWorker.attempt/2 |
(String.t(), String.t() | nil) :: {:ok, AuroraMeter.Schema.CreditTransaction.t()} | {:skip, skip()} | {:error, term()} |
stable | 0.3.0 |
Directly callable as well as an Oban worker. Arity 1 exists through a nil idempotency key. |
AuroraMeter.Pro.Credits.AutoTopUpSweeper.sweep/0 |
() :: non_neg_integer() |
stable | 0.3.0 | The level-triggered pass, for accounts that are already below the threshold. |
AuroraMeter.Pro.Credits.Expirer.run/0 |
() :: {:ok, non_neg_integer()} |
deprecated | 0.3.0 |
An Oban wrapper around AuroraMeter.Credits.expire_due/1, from when the core shipped no scheduler. The replacement has landed: AuroraMeter.Oban.CreditExpiry, in the free core. This is now a shim that delegates to it, carries @deprecated, and is removed in 2.0. Registering both in one crontab is refused by AuroraMeter.Oban.validate!/1. |
AuroraMeter.Pro.Credits.Product.ensure/0 |
() :: {:ok, String.t()} | {:error, term()} |
stable | 0.3.0 | Finds or creates the Stripe product credit is sold against, and caches the id. |
AuroraMeter.Pro.Credits.Product.reset_cache/0 |
() :: :ok |
stable | 0.3.0 | For tests and for a mode switch. |
1.3 Subscriptions, checkout and the webhook
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Stripe.checkout_params/2 |
(tenant, keyword()) :: {:ok, map()} | {:error, :not_configured} |
stable | 0.2.0 | Pure. Attaches every flat price (quantity 1) and every metered price (no quantity) of the plan. |
AuroraMeter.Pro.Stripe.portal_params/2 |
(tenant, keyword()) :: {:ok, map()} | {:error, :no_customer} |
stable | 0.2.0 | Pure. |
AuroraMeter.Pro.Stripe.meter_event_params/1 |
(map()) :: map() |
stable | 0.3.0 | Pure. The Billing Meter event body for one usage entry. |
AuroraMeter.Pro.Subscriptions.sync/1 |
(map()) :: {:ok, AuroraMeter.Schema.Subscription.t()} | {:error, term()} |
stable | 0.1.0 |
Writes through AuroraMeter.Storage.put_subscription/1, so the core’s subscription cache is evicted on every node. |
AuroraMeter.Pro.Subscriptions.sync_from_session/1 |
(map()) :: {:ok, AuroraMeter.Schema.Subscription.t()} | {:error, term()} |
stable | 0.1.0 | |
AuroraMeter.Pro.Subscriptions.plan_ref/1 |
(map()) :: {String.t(), String.t() | nil} |
additive | 1.0.0 |
The {plan_id, plan_version} a Stripe subscription or session maps to: the item prices first, then metadata.plan_id with metadata.plan_version, then {"unknown", nil}. |
AuroraMeter.Pro.Subscriptions.plan_id/1 |
(map()) :: String.t() |
deprecated | 0.2.0 |
elem(plan_ref/1, 0). Deprecated in 1.0 and removed in 2.0: it drops the version, which is half of a commercial contract. |
AuroraMeter.Pro.Transitions.schedule/3 |
(tenant, {atom(), String.t()}, keyword()) :: {:ok, AuroraMeter.Schema.PlanTransition.t()} | {:error, term()} |
additive | 1.0.0 |
Schedules a plan change the billing provider makes first: confirm: :provider, with the target price id resolved and stored on the row before it is written. |
AuroraMeter.Pro.Transitions.status/2 |
(tenant, String.t()) :: AuroraMeter.Schema.PlanTransition.t() | nil |
additive | 1.0.0 | Reads one transition back by tenant and reference. |
AuroraMeter.Pro.Transitions.Applier.run/1 |
(keyword()) :: {:ok, map()} |
additive | 1.0.0 | Drives every due provider transition. An Oban worker; safe to run from every node at once. |
AuroraMeter.Pro.Webhook.handle_event/1 |
(map()) :: AuroraMeter.Pro.Subscriptions.result() | AuroraMeter.Pro.Credits.result() | :ok |
stable | 0.1.0 | The event router, for a host that verifies and routes Stripe events itself. |
AuroraMeter.Pro.Webhook.verify/3 |
(binary(), String.t(), String.t() | [String.t()]) :: :ok | {:error, term()} |
stable | 0.1.0 | HMAC-SHA256 over Stripe’s signed payload, with a 300 second timestamp tolerance. |
AuroraMeter.Pro.Webhook.sign/3 |
(String.t(), integer(), binary()) :: String.t() |
stable | 0.1.0 | The signature a test needs to post a believable event. |
AuroraMeter.Pro.Webhook is also a Plug (stable since 0.1.0; :path since
1.2.0). Mount it in the endpoint, above Plug.Parsers, because the signature is
over the raw body: plug AuroraMeter.Pro.Webhook, path: "/webhooks/stripe".
With :path it handles only a POST to exactly that path and passes every
other request through untouched; a :path that is not a string starting with
/ raises ArgumentError at init/1. Without :path every request that
reaches it is treated as a Stripe event, which suits only a pipeline that sees
nothing else. A router forward cannot work: it runs after the endpoint’s
parsers have consumed the body. handle_event/1 answers
{:refused, :untenanted_subscription} (since 1.2.0) for a subscription event
whose subscription carries no tenant_key metadata; the plug turns it into a
200.
1.4 Usage reporting, reconciliation, rollups and export
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.UsageReporter.report_all/0 |
() :: :ok | {:error, [term()]} |
stable | 0.1.0 |
Reports metered deltas to Stripe Billing Meters through the aurora_meter_usage_reports ledger: at least once, under an identifier naming the window, which is what Stripe deduplicates on, so a retried send does not bill those units twice. Also an Oban worker. |
AuroraMeter.Pro.Reconcile.run/1 |
(keyword()) :: %{local_drift: [map()], items_open: non_neg_integer()} |
stable | 0.1.0 |
A local over-reporting check: it flags last_reported values greater than the persisted counter, under :local_drift; :items_open counts the provider findings waiting for a person. It does not detect unreported usage, query Stripe, or prove that an accepted meter event reached an invoice. Options :flush (default true), :since, :limit, :tenant. Arity 0 exists through defaults. |
AuroraMeter.Pro.Rollup.rollup_all/1 |
(keyword()) :: :ok |
stable | 0.1.0 |
Rebuilds month buckets from counters and day buckets from history (or events when history: false). Option :since_days (90). Arity 0 exists through defaults. Also an Oban worker. |
AuroraMeter.Pro.Rollup.history/2 |
(tenant, String.t()) :: [AuroraMeter.Pro.Schema.Rollup.t()] |
stable | 0.1.0 |
The second argument is a bucket kind ("month" or "day"), not a feature name. A feature name matches no bucket kind and returns []. |
AuroraMeter.Pro.Export.usage_csv/2 |
(tenant, keyword()) :: String.t() |
stable | 0.1.0 |
Header feature,bucket_start,value. The only option read is :bucket_kind (default "month"); :days, :from and :to are ignored. Arity 1 exists through defaults. |
AuroraMeter.Pro.Export.daily_csv/3 |
(tenant, atom(), keyword()) :: String.t() |
stable | 0.2.0 |
Header date,value. Options are passed through to AuroraMeter.history/3 (:days, :from, :to). Arity 2 exists through defaults. |
1.5 Alerts
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Alerts.check_all/0 |
() :: :ok |
stable | 0.1.0 | Deduplicated per tenant, feature, period and threshold. A handler that fails rolls the dedup record back, so the next sweep tries again. Also an Oban worker. |
1.6 Request audit log
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.AuditLog.record/1 |
(map()) :: :ok |
stable | 0.3.0 |
Never raises and never blocks the request. A :tenant (or :tenant_key) is required; :method, :path and :status are what make the row worth having. Unknown keys are ignored. |
AuroraMeter.Pro.AuditLog.list/2 |
(tenant, keyword()) :: %{data: [event()], has_more: boolean(), next_cursor: String.t() | nil} |
stable | 0.3.0 |
Options :limit (50, capped at 200), :before, :status, :status_class (:success, :client_error, :server_error), :method, :path (a prefix), :mode, :from, :to. Arity 1 exists through defaults. |
AuroraMeter.Pro.AuditLog.stats/2 |
(tenant, keyword()) :: %{total: non_neg_integer(), by_status_class: map(), p50_ms: non_neg_integer() | nil, p95_ms: non_neg_integer() | nil} |
stable | 0.3.0 |
The same filters as list/2; :limit and :before are ignored. Arity 1 exists through defaults. |
AuroraMeter.Pro.AuditLog.any?/2 |
(tenant, keyword()) :: boolean() |
stable | 0.3.0 | Has this tenant ever called the API. Arity 1 exists through defaults. |
AuroraMeter.Pro.AuditLog.cursor/1 |
(AuroraMeter.Pro.Schema.AuditEvent.t()) :: String.t() |
stable | 0.3.0 |
The keyset cursor for one row, over (inserted_at, id). |
AuroraMeter.Pro.AuditLog.prune/1 |
(keyword()) :: {:ok, non_neg_integer()} |
stable | 0.3.0 | Deletes in bounded batches. Arity 0 exists through defaults. |
AuroraMeter.Pro.AuditLog.plan/1 |
(keyword()) :: {:ok, non_neg_integer()} |
additive | 1.0.0 |
Counts what prune/1 would delete, by the same predicate. Writes nothing. Arity 0 exists through defaults. |
AuroraMeter.Pro.AuditLog.Pruner.run/1 |
(keyword()) :: :ok |
deprecated | 0.3.0 |
The audit-log sweep, now a shim for AuroraMeter.Pro.Retention. Also an Oban worker. Arity 0 exists through defaults. |
AuroraMeter.Pro.Retention.plan/1 |
(keyword()) :: {:ok, map()} | {:blocked, map(), [map()]} |
additive | 1.0.0 |
Dry run. Writes nothing. Options :only, :older_than_days, :older_than. |
AuroraMeter.Pro.Retention.prune/1 |
(keyword()) :: {:ok, map()} | {:blocked, map(), [map()]} |
additive | 1.0.0 |
Options :only, :older_than_days, :older_than, :batch_size, :max_items. A table outside the allow list raises ArgumentError. |
AuroraMeter.Pro.Retention.tables/0 |
() :: [atom()] |
additive | 1.0.0 | The allow-list keys. |
AuroraMeter.Pro.Retention.protected/0 |
() :: [String.t()] |
additive | 1.0.0 | The tables a prune must never delete a row from. |
AuroraMeter.Pro.Retention.operation/1 |
(atom()) :: String.t() |
additive | 1.0.0 |
The AuroraMeter.Operations name one table’s prune pauses under. |
AuroraMeter.Pro.Retention.Pruner.operations/0 |
() :: [String.t()] |
additive | 1.0.0 | Every operation name the worker pauses under, one per table. |
AuroraMeter.Pro.Plugs.AuditLog is the Plug. Everything host-shaped arrives
as a resolver function of the conn (:tenant, :actor, :metadata), so the
package never guesses at a host’s schema. A :tenant resolver returning nil
skips the write, which is how unauthenticated requests stay out of the log: put
the plug after your authentication, not before.
1.7 Dashboard
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Dashboard.load/2 |
(tenant, keyword()) :: map() |
stable | 0.2.0 |
Everything the components render, in one call, so a LiveView re-renders on a usage broadcast. Option credits: false. Arity 1 exists through defaults. |
AuroraMeter.Pro.Dashboard.money?/1 |
(map()) :: boolean() |
stable | 0.3.0 | Whether the tenant has a credit ledger, which is what guards the money section. |
AuroraMeter.Pro.Components.usage_dashboard/1 |
HEEx component | optional-dep | 0.1.0 |
Needs phoenix_live_view and phoenix_html. Attributes tenant, data, money. |
AuroraMeter.Pro.Components.usage_chart/1 |
HEEx component | optional-dep | 0.2.0 |
Needs phoenix_live_view and phoenix_html. |
AuroraMeter.Pro.Components.quota_card/1 |
HEEx component | optional-dep | 0.2.0 |
Needs phoenix_live_view and phoenix_html. |
AuroraMeter.Pro.Components.money_section/1 |
HEEx component | optional-dep | 0.3.0 |
Needs phoenix_live_view and phoenix_html. |
AuroraMeter.Pro.Components.styles/1 |
HEEx component | optional-dep | 0.2.0 |
Needs phoenix_live_view and phoenix_html. Inline CSS scoped to .aurora-dashboard, themeable through CSS custom properties. |
AuroraMeter.Pro.Components.format_int/1 |
(integer()) :: String.t() |
optional-dep | 0.2.0 |
Needs phoenix_live_view and phoenix_html, because the whole module is compiled only when Phoenix.Component is loaded. |
1.8 Configuration accessors
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Config.stripe_prices/0 |
() :: map() |
stable | 0.1.0 | |
AuroraMeter.Pro.Config.stripe_metered_prices/0 |
() :: map() |
stable | 0.2.0 | |
AuroraMeter.Pro.Config.stripe_meters/0 |
() :: map() |
stable | 0.1.0 |
Keyed by feature, unlike stripe_prices, which is keyed by plan id. |
AuroraMeter.Pro.Config.prices_for/1 |
(atom() | String.t()) :: [String.t()] |
stable | 0.2.0 | |
AuroraMeter.Pro.Config.price_for/1 |
(atom() | String.t()) :: String.t() | nil |
stable | 0.1.0 |
The first of prices_for/1. |
AuroraMeter.Pro.Config.metered_prices_for/1 |
(atom() | String.t()) :: [String.t()] |
stable | 0.2.0 | Keyed by plan id. |
AuroraMeter.Pro.Config.plan_for_price/1 |
(String.t() | nil) :: atom() | nil |
stable | 0.2.0 |
Returns {plan_id, version} in 1.0 through a new plan_ref/1; this name keeps this shape for one major and is deprecated then. |
AuroraMeter.Pro.Config.meter_for/1 |
(atom() | String.t()) :: String.t() | nil |
stable | 0.1.0 | |
AuroraMeter.Pro.Config.webhook_secret/0 |
() :: String.t() | [String.t()] | nil |
stable | 0.1.0 |
Resolves {:system, "VAR"}. |
AuroraMeter.Pro.Config.portal_configuration/0 |
() :: String.t() | nil |
stable | 0.2.0 |
Reads :stripe_portal_configuration. |
AuroraMeter.Pro.Config.alert_thresholds/0 |
() :: [pos_integer()] |
stable | 0.1.0 | |
AuroraMeter.Pro.Config.alert_handler/0 |
() :: (map() -> term()) | nil |
stable | 0.1.0 | |
AuroraMeter.Pro.Config.credits_stripe_client/0 |
() :: module() |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.credits_product_id/0 |
() :: String.t() | nil |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.credits_product_name/0 |
() :: String.t() |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.credits_currency/0 |
() :: String.t() |
stable | 0.3.0 |
Falls back to the core’s :credits_currency, so the two cannot disagree by accident. |
AuroraMeter.Pro.Config.credits_presets_cents/0 |
() :: [pos_integer()] |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.credits_min_cents/0 |
() :: pos_integer() |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.credits_max_cents/0 |
() :: pos_integer() |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.credits_tax/0 |
() :: :none | :exclusive |
stable | 1.1.0 | |
AuroraMeter.Pro.Config.credits_handler/0 |
() :: (term() -> term()) | nil |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.auto_top_up_cooldown_seconds/0 |
() :: pos_integer() |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.auto_top_up_max_failures/0 |
() :: pos_integer() |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.audit_log_retention_days/0 |
() :: pos_integer() |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.audit_log_writer/0 |
() :: :async | :sync |
stable | 0.3.0 | |
AuroraMeter.Pro.Config.stripe_account_id/0 |
() :: String.t() | nil |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.stripe_mode/0 |
() :: :test | :live |
stable | 1.0.0 |
Falls back to the API key’s prefix when :stripe_mode is unset. |
AuroraMeter.Pro.Config.stripe_account_check/0 |
() :: :skip | :best_effort | :require |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.api_version/0 |
() :: String.t() |
stable | 1.0.0 |
The Stripe-Version Pro sends. validate!/0 writes it into config :stripity_stripe, :api_version. |
AuroraMeter.Pro.Config.webhook_api_version/0 |
() :: :pinned | :any | String.t() |
stable | 1.0.0 | The version received events are expected to carry, which Pro cannot set and the host can. |
AuroraMeter.Pro.Config.expected_webhook_api_version/0 |
() :: String.t() | nil |
stable | 1.0.0 |
webhook_api_version/0 resolved: api_version/0 for :pinned, nil for :any. |
AuroraMeter.Pro.Config.mapping_version/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.mapping_fingerprint/0 |
() :: String.t() |
stable | 1.0.0 |
A sha256 over the three mapping maps, stable across key order. mapping_version/0 is the host’s promise that a mapping changed; this is the fact, so a change without a bump is detectable afterwards. |
AuroraMeter.Pro.Config.exporter/0 |
() :: module() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.outbox_lease_seconds/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.outbox_max_attempts/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.outbox_batch_size/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.outbox_backoff_base_seconds/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.outbox_backoff_cap_seconds/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.outbox_rate_limit_delay_seconds/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.outbox_retention_days/0 |
() :: pos_integer() |
stable | 1.0.0 |
Days a confirmed outbox item is kept. |
AuroraMeter.Pro.Config.webhook_event_retention_days/0 |
() :: pos_integer() |
additive | 1.0.0 | Days. |
AuroraMeter.Pro.Config.recovery_action_retention_days/0 |
() :: pos_integer() |
additive | 1.0.0 | Days. |
AuroraMeter.Pro.Config.reconciliation_item_retention_days/0 |
() :: pos_integer() |
additive | 1.0.0 | Days a resolved reconciliation item is kept. |
AuroraMeter.Pro.Config.uncertainty_horizon_seconds/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.reporter_batch_size/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.stripe_meter_ids/0 |
() :: map() |
stable | 1.0.0 |
Keyed by feature, like stripe_meters/0, and holding a different value: the meter id, which is what a summary read takes in its path. |
AuroraMeter.Pro.Config.meter_id_for/1 |
(atom() | String.t()) :: String.t() | nil |
stable | 1.0.0 |
The meter id for one feature, or nil. A feature with no id can be exported and cannot be reconciled. |
AuroraMeter.Pro.Config.adjustment_window_seconds/0 |
() :: pos_integer() |
stable | 1.0.0 | Stripe documents 24 hours from receipt for a meter event cancellation; the default keeps an hour under it. |
AuroraMeter.Pro.Config.confirmation_delay_seconds/0 |
() :: non_neg_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.confirmation_grace_seconds/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.reconciler_max_requests/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.reconciler_max_groups/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.reconciler_time_budget_ms/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.reconciler_check_invoices?/0 |
() :: boolean() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.reconciler_error_report_batch/0 |
() :: pos_integer() |
stable | 1.0.0 | |
AuroraMeter.Pro.Config.invalidate!/0 |
() :: :ok |
stable | 1.0.0 | Forgets the validated configuration on this node, so the next accessor validates again. For tests and for a health check that has just rewritten the environment. |
AuroraMeter.Pro.Config.validated/0 |
() :: map() | nil |
stable | 1.0.0 |
The validated configuration, or nil when none has been installed. |
1.9 The source cutover
Moving a feature from buffered reporting to event reporting, once, at a period
boundary. The reporter stages a buffered window only while period_start < w
and the outbox accepts an event only while period_start >= w, so a period
belongs to exactly one path. See the cutover guide.
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Cutover.schedule/3 |
(atom(), DateTime.t(), keyword()) :: {:ok, struct()} | {:error, :already_scheduled | :not_a_period_start | :in_the_past | Ecto.Changeset.t()} |
stable | 1.0.0 |
Options :actor, :reason, :tenant. Arity 2 exists through a default. A second call for one feature writes nothing; moving a watermark goes through the recovery API. |
AuroraMeter.Pro.Cutover.watermark/1 |
(atom()) :: DateTime.t() | nil |
stable | 1.0.0 |
Read on the durable record path. Not cached: a lagging cache would hold nil while the row held a watermark, and a reader that believes there is no watermark accepts an event for a period the buffered reporter already reported. |
AuroraMeter.Pro.Cutover.status/1 |
(atom()) :: map() |
stable | 1.0.0 |
%{feature, watermark, buffered_periods_open, event_items, drained?}. drained? is the condition for deploying the :events source. |
AuroraMeter.Pro.Cutover.list/0 |
() :: [struct()] |
stable | 1.0.0 | Every scheduled cutover, oldest watermark first. |
1.10 Guarded recovery
What an operator may do to a financial record that is stuck. Every mutation
takes the subject first and one keyword list second, carrying expected: (the
state the operator believes they are acting on), reason: and evidence:. A
mutation writes exactly one aurora_meter_recovery_actions row whether it
applies or refuses. There is no force: option. Nothing here calls a provider.
See Recovery.
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Recovery.list_uncertain/1 |
(keyword()) :: [map()] |
stable | 1.0.0 |
uncertain, rejected and quarantined items, newest first. Options :state (one, a list, or :all), :tenant, :kind, :older_than (seconds against first_attempt_at), :limit (50, capped at 500) and :cursor. Writes nothing. Arity 0 exists through a default. |
AuroraMeter.Pro.Recovery.inspect_item/1 |
(Ecto.UUID.t()) :: {:ok, map()} | {:error, :not_found} |
stable | 1.0.0 |
The row, the payload, the exporter’s describe/0, whether the first attempt is inside the idempotency horizon, the staged usage_reports row, matching open reconciliation items, the eligibility the item would be re-checked against, and the recovery actions already recorded against it. |
AuroraMeter.Pro.Recovery.actions/2 |
(String.t(), keyword()) :: [map()] |
stable | 1.0.0 |
The audit trail for one subject, newest first. Option :limit (20). Arity 1 exists through a default. |
AuroraMeter.Pro.Recovery.pending_payments/1 |
(keyword()) :: [map()] |
stable | 1.0.0 |
Every credit account with a charge in flight, oldest first. Option :tenant. Arity 0 exists through a default. |
AuroraMeter.Pro.Recovery.acknowledge_item/2 |
(Ecto.UUID.t(), keyword()) :: {:ok, summary()} | {:error, refusal()} |
stable | 1.0.0 |
uncertain to accepted. expected: takes :state, :lease_token, :subject_ref and a non-empty :provider_ref. For a usage_window item it advances usage_reports.last_reported and clears the staged link in the same transaction. Never moves an item to confirmed. |
AuroraMeter.Pro.Recovery.abandon_item/2 |
(Ecto.UUID.t(), keyword()) :: {:ok, summary()} | {:error, refusal()} |
stable | 1.0.0 |
uncertain or quarantined to rejected. expected: takes :state, :lease_token and :subject_ref. Leaves last_reported where it is and clears the staged link, so the next reporter run stages the window again under a new identity. |
AuroraMeter.Pro.Recovery.requeue_item/2 |
(Ecto.UUID.t(), keyword()) :: {:ok, summary()} | {:error, refusal()} |
stable | 1.0.0 |
quarantined to pending. expected: takes :state, :lease_token, :subject_ref and :quarantine_reason. Refuses {:error, :mapping_changed} and {:error, {:still_ineligible, check}}. |
AuroraMeter.Pro.Recovery.attach_payment_intent/2 |
(tenant, keyword()) :: {:ok, map()} | {:skip, atom()} | {:error, refusal() | term()} |
stable | 1.0.0 |
Records a pi_... an operator identified and resumes the payment through the GET-only path. expected: takes :pending_idempotency_key; intent_id: is required; resume: defaults to true. Creates no charge and grants nothing by itself. |
AuroraMeter.Pro.Recovery.abandon_payment/2 |
(tenant, keyword()) :: {:ok, map()} | {:error, refusal()} |
stable | 1.0.0 |
Clears the four pending payment columns and nothing else. expected: takes :pending_idempotency_key and :pending_payment_intent_id, which must be nil. Refuses {:error, :intent_known} when an intent is known. |
AuroraMeter.Pro.Recovery.reschedule_cutover/2 |
(atom(), keyword()) :: {:ok, map()} | {:error, refusal()} |
stable | 1.0.0 |
Moves a watermark AuroraMeter.Pro.Cutover.schedule/3 refuses to move. expected: takes :effective_period_start; to: is required; :tenant optional. Refuses {:error, {:already_effective, counts}} once anything has been billed at or after the earlier of the two watermarks. |
1.11 Periods and migrations
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Period.containing/2 |
(tenant, DateTime.t()) :: AuroraMeter.Period.t() |
stable | 1.0.0 |
The subscription window when the instant falls inside it, and the calendar month with source: :calendar_fallback otherwise. The optional AuroraMeter.Period callback. |
AuroraMeter.Pro.Migration.latest_version/0 |
() :: pos_integer() |
stable | 0.3.0 |
9 in this release. |
AuroraMeter.Pro.Migration.up/1 |
(keyword()) :: :ok |
stable | 0.3.0 |
Options :version, :from, :to. Arity 0 exists through defaults. Every version is idempotent. |
AuroraMeter.Pro.Migration.down/1 |
(keyword()) :: :ok |
stable | 0.3.0 |
Options :version, :from, :to. Arity 0 exists through defaults. |
AuroraMeter.Pro.Period implements the whole AuroraMeter.Period behaviour.
Configure it with config :aurora_meter, period_source: AuroraMeter.Pro.Period;
c:AuroraMeter.Period.current/2 is a callback and is not called directly.
1.12 Telemetry
The Pro event catalogue as data, and the Telemetry.Metrics presets over it.
The tag rules themselves are core’s: see
AuroraMeter.Telemetry.tag_allow_list/0 and Telemetry.
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Telemetry.events/0 |
() :: [AuroraMeter.Pro.Telemetry.event_doc()] |
stable | 1.0.0 |
Every Pro event, with its real measurement and metadata keys, the tags a preset may use, the emitter and the version it arrived in. Checked against lib/, docs/api.md and docs/telemetry.md on every run. |
AuroraMeter.Pro.Telemetry.event_names/0 |
() :: [[atom()]] |
stable | 1.0.0 | Every concrete Pro event name. |
AuroraMeter.Pro.Outbox.gauge/0 |
() :: :ok |
stable | 1.0.0 |
Emits one [:aurora_meter, :pro, :outbox, :gauge] sample. The deliverer calls it at the end of every run; it is public so a host with a paused queue or another scheduler can still chart the backlog. Raises and emits nothing when the aggregate query fails, because a zero would read as an empty backlog. |
AuroraMeter.Pro.Telemetry.provider_span/2 |
(atom(), (-> result)) :: result |
stable | 1.0.0 |
Wraps one outbound provider call in a [:aurora_meter, :pro, :provider] span, at the seam where Pro calls the configured client, so one span is one HTTP attempt and never a retry loop. The result is returned untouched. Raises ArgumentError on an operation outside provider_operations/0. |
AuroraMeter.Pro.Telemetry.provider_operations/0 |
() :: [atom()] |
stable | 1.0.0 |
The closed set of operation values the provider span can carry, one per client callback. It is a list rather than a derivation so a reader can see every value the metadata can take. |
1.13 AuroraMeter.Pro.Telemetry.Metrics (optional dependency)
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Telemetry.Metrics.metrics/1 |
(keyword()) :: [Telemetry.Metrics.t()] |
optional-dep | 1.0.0 |
Needs telemetry_metrics (~> 0.6 or ~> 1.0). Options :feature_label and :include. Arity 0 exists through defaults. A host wanting both writes AuroraMeter.Telemetry.Metrics.metrics() ++ AuroraMeter.Pro.Telemetry.Metrics.metrics(). |
AuroraMeter.Pro.Telemetry.Metrics.groups/0 |
() :: [atom()] |
optional-dep | 1.0.0 |
Needs telemetry_metrics. The groups :include accepts. |
Without telemetry_metrics installed the module is not defined at all. Every
Pro event is still emitted and AuroraMeter.Pro.Telemetry still works.
1.14 AuroraMeter.Pro.LiveDashboard.Page (optional dependency)
A Phoenix.LiveDashboard page for Pro’s commercial operations: the export
backlog, uncertain and quarantined items, leases, open reconciliation
differences, pending payments, the recovery audit trail and the provider
mapping.
:authorized_by is required and there is no default. This page refuses
authorized_by: :host_route, which AuroraMeter.LiveDashboard.Page accepts:
every section here renders tenant keys, subject references and payment state,
and “the route is authenticated” is not a basis for showing one customer’s
payment state to whoever reached the dashboard. The accepted forms are in
AuroraMeter.LiveDashboard.Auth.
The page is read-only. It renders the recovery audit trail and the exact
AuroraMeter.Pro.Recovery call to paste, and ships no button that performs one:
those mutations require an expected: map and an evidence: string that a
one-click button cannot supply honestly.
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.LiveDashboard.Page.init/1 |
(keyword()) :: {:ok, map()} |
optional-dep | 1.0.0 |
Needs phoenix_live_dashboard (>= 0.8.0 and < 0.10.0). Raises ArgumentError when :authorized_by is absent or unrecognised, and with a distinct message for :host_route. |
AuroraMeter.Pro.LiveDashboard.Page.menu_link/2 |
(map(), map()) :: {:ok, String.t()} | {:disabled, String.t()} |
optional-dep | 1.0.0 |
Needs phoenix_live_dashboard. Disabled with “Aurora Meter Pro: not configured” when AuroraMeter.Pro.validate!/0 raises. |
AuroraMeter.Pro.LiveDashboard.Page.mount/3 |
(map(), map(), Phoenix.LiveView.Socket.t()) :: {:ok, Phoenix.LiveView.Socket.t()} |
optional-dep | 1.0.0 |
Needs phoenix_live_dashboard. Evaluates the configured check before reading anything. |
AuroraMeter.Pro.LiveDashboard.Page.handle_refresh/1 |
(Phoenix.LiveView.Socket.t()) :: {:noreply, Phoenix.LiveView.Socket.t()} |
optional-dep | 1.0.0 |
Needs phoenix_live_dashboard. Re-evaluates the check on every refresh. |
AuroraMeter.Pro.LiveDashboard.Page.render/1 |
HEEx | optional-dep | 1.0.0 |
Needs phoenix_live_dashboard. No form, no button, no phx-click. |
2. Behaviours and their callbacks
| Entry | Callbacks | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Credits.StripeClient |
create_checkout_session/1, create_payment_intent/2, create_portal_session/1, create_product/1, search_products/1, update_customer/2, retrieve_customer/1, retrieve_payment_intent/1, retrieve_payment_method/1, retrieve_charge/1, list_charge_disputes/1, create_tax_calculation/1 |
stable | 0.3.0 |
12 callbacks; create_tax_calculation/1 (new in 1.1.0) is optional and called only with credits_tax: :exclusive. The slice of Stripe the top-ups use. A custom client must implement retrieve_charge/1 and list_charge_disputes/1, because refund reconciliation reads the charge’s current state rather than trusting an event’s snapshot, and retrieve_customer/1, because a payment may not credit a tenant on a customer this installation’s Stripe account does not have. retrieve_customer/1 is new since 0.3.0. |
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Credits.StripeClient.impl/0 |
() :: module() |
stable | 0.3.0 | The configured implementation. |
Pro implements two core behaviours:
| Entry | Implements | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Stripe |
AuroraMeter.Billing.Provider |
stable | 0.1.0 |
config :aurora_meter, provider: AuroraMeter.Pro.Stripe. |
AuroraMeter.Pro.Period |
AuroraMeter.Period |
stable | 0.1.0 |
config :aurora_meter, period_source: AuroraMeter.Pro.Period. |
AuroraMeter.Pro.Credits.StripeClient.Live |
AuroraMeter.Pro.Credits.StripeClient |
stable | 0.3.0 |
The default, backed by stripity_stripe. |
3. Structs and public types
| Entry | Shape | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Schema.UsageReport |
aurora_meter_usage_reports row |
stable | 0.1.0 | The usage reporting ledger: one row per reported window, carrying what was sent, the identifier it was sent under, and what came back. |
AuroraMeter.Pro.Schema.Rollup |
aurora_meter_rollups row |
stable | 0.1.0 | |
AuroraMeter.Pro.Schema.Alert |
aurora_meter_alerts row |
stable | 0.1.0 | The dedup record, one per tenant, feature, period and threshold. |
AuroraMeter.Pro.Schema.CreditAccount |
aurora_meter_credit_accounts row |
stable | 0.3.0 | The Stripe customer, the saved card and the auto top-up settings. Never the balance: that is the core ledger’s. |
AuroraMeter.Pro.Schema.AuditEvent |
aurora_meter_audit_events row |
stable | 0.3.0 |
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Schema.CreditAccount.changeset/2 |
(t(), map()) :: Ecto.Changeset.t() |
stable | 0.3.0 | |
AuroraMeter.Pro.Schema.CreditAccount.auto_top_up_changeset/2 |
(t(), map()) :: Ecto.Changeset.t() |
stable | 0.3.0 | |
AuroraMeter.Pro.Schema.AuditEvent.changeset/1 |
(map()) :: Ecto.Changeset.t() |
stable | 0.3.0 |
Named types a host will meet in a spec: t:AuroraMeter.Pro.AuditLog.event/0,
t:AuroraMeter.Pro.AuditLog.page/0, t:AuroraMeter.Pro.AuditLog.stats/0 and
t:AuroraMeter.Pro.AuditLog.status_class/0,
t:AuroraMeter.Pro.Credits.AutoTopUpWorker.skip/0, and
t:AuroraMeter.Pro.Subscriptions.result/0.
4. Return values and error tuples
Pro returns {:ok, value} | {:error, reason} almost everywhere, and the two
places it does not are worth knowing.
-
AuroraMeter.Pro.Credits.AutoTopUpWorker.attempt/2has a third outcome,{:skip, reason}: the guards said no (no account, disabled, no saved payment method, still inside the cooldown, balance already above the threshold). A skip is not a failure and does not count against:auto_top_up_max_failures. -
AuroraMeter.Pro.Reconcile.run/1returns%{local_drift: [drift], items_open: integer}. There is no:okwrapper, because a map with two keys is the answer. It returned a bare list before 1.0.0. -
AuroraMeter.Pro.Recovery‘s mutations return{:error, {:expected_state_mismatch, current}}wherecurrentholds the present values of exactly the keys the caller claimed, so the call can be re-issued from the refusal itself. The other refusals are{:missing_evidence, :reason | :evidence | :provider_ref},:not_found,:intent_known,:not_a_payment_intent,:mapping_changed,{:still_ineligible, check},:staged_link_changed,:not_scheduled,:in_the_past,:not_a_period_startand{:already_effective, counts}. A missingexpected:,reason:orevidence:raises: it is a call that never reached the API’s semantics, and it is the one failure that writes no audit row.
Money crosses the provider boundary in minor units (amount_cents), and
lives in the core ledger in micro-dollars. Every Pro entry that names an amount
says which. AuroraMeter.Credits.Money converts, and nothing rounds inside a
transaction.
Idempotency keys: Pro keys a credit grant on the Stripe PaymentIntent id and
passes it to the core ledger as reference:. A charge carries a Stripe
idempotency key of its own, stored on the account row, so a retried charge is
one charge at Stripe as well as one grant locally.
A webhook handler that returns {:error, reason} makes the plug answer 500,
so Stripe retries the event. That is deliberate: a top-up whose grant failed on
a transient database error must not be dropped.
5. Configuration keys
Read from the :aurora_meter_pro application environment. {:system, "VAR"} is
accepted wherever the notes say so, and is resolved at read time.
| Key | Type and default | Class | Since | Notes |
|---|---|---|---|---|
:stripe_prices |
map, %{} |
compat | 0.1.0 |
%{{plan_id, version} => price_id | [price_id]}. Flat prices, attached with quantity 1. A bare plan_id key means version "1", so every 0.x mapping keeps working unchanged. One price id may belong to exactly one {plan_id, version}, and boot refuses a mapping where two claim the same one. |
:stripe_metered_prices |
map, %{} |
compat | 0.2.0 |
%{{plan_id, version} => [price_id]}. Attached without a quantity. Keyed exactly as :stripe_prices, and checked for price-id uniqueness against it. |
:proration_behavior |
:none | :create_prorations | :always_invoice, :none |
additive | 1.0.0 | What Stripe is asked to do about the unused part of the period when a plan change is sent. Aurora Meter computes no proration of its own; the other two values are Stripe’s own, passed through, and what they produce is Stripe’s arithmetic. |
:stripe_subscription_client |
module, Stripe.Subscription |
internal | 1.0.0 |
The module retrieve/1 and update/3 are called on for a provider-ordered plan change. |
:stripe_meters |
map, %{} |
stable | 0.1.0 |
%{feature => meter_event_name}. Keyed by feature, not by plan. |
:webhook_secret |
string, list of strings, {:system, var} or nil, nil |
stable | 0.1.0 | A list supports a secret rotation. |
:stripe_portal_configuration |
string, {:system, var} or nil, nil |
stable | 0.2.0 | Stripe’s default portal often has plan switching and cancellation disabled. |
:alert_thresholds |
list of integers, [80, 100] |
stable | 0.1.0 | Percentages. |
:alert_handler |
1-arity function or nil, nil |
stable | 0.1.0 | A handler that raises rolls the dedup record back. |
:credits_stripe_client |
module, AuroraMeter.Pro.Credits.StripeClient.Live |
stable | 0.3.0 | |
:credits_product_id |
string, {:system, var} or nil, nil |
stable | 0.3.0 | Set it to skip the product lookup at boot. |
:credits_product_name |
string, "Prepaid credits" |
stable | 0.3.0 | |
:credits_currency |
string, the core’s :credits_currency |
stable | 0.3.0 | |
:credits_presets_cents |
list of integers, [1_000, 2_500, 5_000, 10_000] |
stable | 0.3.0 | |
:credits_min_cents |
integer, 500 |
stable | 0.3.0 | |
:credits_max_cents |
integer, 100_000 |
stable | 0.3.0 | |
:credits_tax |
:none or :exclusive, :none |
stable | 1.1.0 |
:exclusive adds tax on top through Stripe Tax and credits the pre-tax amount. See docs/top-ups.md. |
:credits_handler |
1-arity function or nil, nil |
stable | 0.3.0 |
Receives {:granted, txn}, {:low_balance, event}, {:auto_top_up_failed, key, reason, count} and {:auto_top_up_disabled, key, reason}. |
:auto_top_up_cooldown_seconds |
integer, 600 |
stable | 0.3.0 | |
:auto_top_up_max_failures |
integer, 3 |
stable | 0.3.0 | |
:audit_log_retention_days |
integer, 30 |
stable | 0.3.0 | |
:audit_log_writer |
:async | :sync, :async |
stable | 0.3.0 |
:async runs the insert under a Task.Supervisor the host registers as AuroraMeter.Pro.TaskSupervisor (that name is a registered process, not a module this package defines). Right in production, useless in a test, where the assertion runs before the write: use :sync there. |
:stripe_account_id |
string, {:system, var} or nil, nil |
stable | 1.0.0 |
The acct_... every outbox item is addressed to. Part of the item’s identity, so two environments pointed at one database cannot settle each other’s usage. Pro schema version 10 refuses to migrate staged reports without it. |
:stripe_mode |
:test | :live, inferred from the API key |
stable | 1.0.0 | Part of the outbox identity. An item staged in one mode is quarantined rather than sent in another. |
:mapping_version |
integer, 1 |
stable | 1.0.0 |
The host’s mapping generation. Bump it when a change to :stripe_meters changes what a feature means; items staged before and after are then different identities. |
:exporter |
module, AuroraMeter.Pro.Exporter.StripeMeterEvents |
stable | 1.0.0 |
The AuroraMeter.Exporter the outbox delivers through. |
:outbox_lease_seconds |
integer, 120 |
stable | 1.0.0 | How long a claim holds an item before another worker may take it. A liveness setting: what stops two workers acknowledging one item is the row’s fencing token, not this number. |
:outbox_max_attempts |
integer, 20 |
stable | 1.0.0 |
Attempts before an item escalates to uncertain. Never to rejected. |
:outbox_batch_size |
integer, 100 |
stable | 1.0.0 |
Items claimed per deliverer run, chunked to the exporter’s max_batch. |
:outbox_backoff_base_seconds |
integer, 5 |
stable | 1.0.0 | First retry delay; it doubles per attempt. |
:outbox_backoff_cap_seconds |
integer, 900 |
stable | 1.0.0 | Largest computed retry delay. |
:outbox_rate_limit_delay_seconds |
integer, 30 |
stable | 1.0.0 | Delay after a rate limit, instead of the exponential backoff. Stripe’s per-endpoint limit is 25 requests per second, so backing off by five seconds is not an answer to being over it. |
:uncertainty_horizon_seconds |
integer, 82_800 |
stable | 1.0.0 |
How long after its first attempt an item may still be resent. Past it the item becomes uncertain and waits for reconciliation. Stripe documents “at least 24 hours” for both the meter event identifier and the idempotency key, so the default keeps an hour of margin. |
:reporter_batch_size |
integer, 200 |
stable | 1.0.0 | Subscriptions per keyset page in one reporter run. |
:stripe_meter_client |
module, Stripe.Billing.MeterEvent |
internal | 1.0.0 |
The module the meter event call goes through, so a test can substitute a double visible across processes. Not a supported production seam: write an AuroraMeter.Exporter instead. |
:stripe_account_client |
module, Stripe.Account |
internal | 1.0.0 |
The module retrieve/2 is called on for the startup account assertion. It exists so that assertion can be exercised without a network. |
:stripe_account_check |
:skip | :best_effort | :require, :best_effort |
stable | 1.0.0 |
Whether boot confirms :stripe_account_id against the account the API key reaches. :best_effort warns and continues on a network failure, so a Stripe outage cannot stop a deploy; :require refuses to boot; :skip makes no call, which is what a test configuration wants. |
:api_version |
string, "2025-11-17.clover" |
stable | 1.0.0 |
The Stripe-Version Pro sends on every request, written into config :stripity_stripe, :api_version at validation. The default is the version this release was tested against, so an SDK upgrade that changes its own default no longer changes the wire contract silently. |
:webhook_api_version |
:pinned | :any | string, :pinned |
stable | 1.0.0 |
The version received webhook events are expected to be serialised at. Stripe serialises an event at the endpoint’s version, or the account’s default when the endpoint names none, which is not the version above. A disagreement is recorded on the event row, carried in telemetry and logged once per distinct version; it is never refused, because the event is a real fact about money. :any switches the observation off. |
:outbox_retention_days |
integer, 90 |
stable | 1.0.0 |
Days a confirmed outbox item is kept before AuroraMeter.Pro.Retention may delete it. An item in any other state is never deleted. Floor 1 day. |
:webhook_event_retention_days |
integer, 30 |
additive | 1.0.0 | Days a recorded provider webhook event is kept. Floor 1 day. |
:recovery_action_retention_days |
integer, 365 |
additive | 1.0.0 | Days a recorded recovery action is kept. Floor 1 day. |
:reconciliation_item_retention_days |
integer, 365 |
additive | 1.0.0 | Days a resolved reconciliation item is kept. An open one is never deleted. Floor 1 day. |
:stripe_meter_ids |
map, %{} |
stable | 1.0.0 |
%{feature => "mtr_..."}. Not the same value as :stripe_meters: sending a meter event takes the meter’s event name, reading a meter event summary takes its id in the path. A feature with no id here is exported and never reconciled, which the reconciler logs rather than passing over. |
:adjustment_window_seconds |
integer, 82_800 |
stable | 1.0.0 |
How long after Stripe received a meter event it can still be cancelled. Stripe’s cancel.identifier documentation says “You can only cancel events within 24 hours of Stripe receiving them”; the default keeps an hour of margin. Measured from the original item’s accepted_at, never from when the usage occurred. |
:confirmation_delay_seconds |
integer, 300 |
stable | 1.0.0 | How long an accepted item is left alone before the reconciler looks for a summary accounting for it. Stripe documents that meter events aggregate asynchronously but states no bound, so this is a choice, not a documented number. |
:confirmation_grace_seconds |
integer, 86_400 |
stable | 1.0.0 |
How long an item may stay accepted with nothing accounting for it before an unconfirmed_item finding is opened. It is never auto-confirmed and never resent. |
:reconciler_max_requests |
integer, 200 |
stable | 1.0.0 | Provider requests one reconciler run may make. |
:reconciler_max_groups |
integer, 50 |
stable | 1.0.0 | Groups one reconciler run may examine. |
:reconciler_time_budget_ms |
integer, 60_000 |
stable | 1.0.0 |
Elapsed-time budget for one run, measured with AuroraMeter.Clock.monotonic_ms/0. |
:reconciler_check_invoices |
boolean, false |
stable | 1.0.0 | Whether a run also reads invoices, at one request per customer. Off by default; the four provider states are reported as they are observed and nothing is inferred from an invoice nobody read. |
:reconciler_error_report_batch |
integer, 50 |
stable | 1.0.0 | How many recorded meter error reports one run processes. |
:recovery_actor |
string or nil, nil |
stable | 1.0.0 |
Who an AuroraMeter.Pro.Recovery mutation is recorded as when the call passes no :actor. Unset means the node name, which is the honest default: the package cannot know who is at the console. A host that fronts recovery with its own admin screen should pass :actor per call, because one name for every operator is the same as no name. |
:stripe_adjustment_client |
module, Stripe.Billing.MeterEventAdjustment |
internal | 1.0.0 |
The module the cancellation call goes through. Separate from :stripe_meter_client because a correction is two requests against two endpoints and a test needs to fail one without failing the other. |
:stripe_summary_client |
module, Stripe.Billing.MeterEventSummary |
internal | 1.0.0 |
The module list/3 is called on to read a meter event summary. |
:stripe_invoice_client |
module, Stripe.Invoice |
internal | 1.0.0 |
The module list/2 is called on when :reconciler_check_invoices is true. |
Every key above is declared in a schema and validated once, by
AuroraMeter.Pro.validate!/0, which AuroraMeter.Pro runs from the host’s
supervision tree. {:system, "VAR"} is resolved at validation, not at read
time: a variable unset after boot no longer changes what a running node does.
An unknown key logs a warning in this release and stops the boot in 1.0.
A host that does not add AuroraMeter.Pro to its tree keeps working: the first
accessor validates lazily and logs one warning naming the module. If that lazy
validation fails it is logged and the raw value is used, rather than raised: a
configuration problem belongs at boot, not on a metering call with money in
flight.
6. Telemetry events
The Matched in lib/ column holds the exact source text the inventory test
greps for, so a renamed event fails the build.
| Event | Measurements | Metadata | Class | Since | Matched in lib/ |
|---|---|---|---|---|---|
[:aurora_meter, :alert] |
threshold, usage, percent |
tenant_key, feature, kind |
stable | 0.1.0 |
[:aurora_meter, :alert] |
[:aurora_meter, :usage_report] |
delta |
tenant_key, feature, period_start |
stable | 0.1.0 |
[:aurora_meter, :usage_report] |
[:aurora_meter, :reconcile] |
drift |
tenant_key, feature |
stable | 0.1.0 |
[:aurora_meter, :reconcile] |
[:aurora_meter, :pro, :auto_top_up] |
amount_cents |
tenant_key, result, reason |
stable | 0.3.0 |
[:aurora_meter, :pro, :auto_top_up] |
[:aurora_meter, :pro, :outbox, :deliver] |
duration_ms |
state, outcome, subject_kind, attempts, reason |
stable | 1.0.0 |
[:aurora_meter, :pro, :outbox, :deliver] |
[:aurora_meter, :pro, :provider] |
duration, monotonic_time, system_time |
operation, result, kind, reason, stacktrace |
stable | 1.0.0 |
[:aurora_meter, :pro, :provider] |
[:aurora_meter, :pro, :credits, :gauge] |
armed, below_threshold, enqueued, reconciliation_required |
operation |
stable | 1.0.0 |
[:aurora_meter, :pro, :credits, :gauge] |
[:aurora_meter, :pro, :credits, :wallet_wide_fallback] |
count |
tenant_key, payment_intent_id, operation |
stable | 0.6.0 |
[:aurora_meter, :pro, :credits, :wallet_wide_fallback] |
[:aurora_meter, :pro, :outbox, :gauge] |
pending, leased, accepted, confirmed, uncertain, rejected, quarantined, oldest_pending_age_seconds, legacy_pending |
none | stable | 1.0.0 |
[:aurora_meter, :pro, :outbox, :gauge] |
[:aurora_meter, :pro, :outbox, :stale_worker] |
count |
item_id, lease_token, transition |
stable | 1.0.0 |
[:aurora_meter, :pro, :outbox, :stale_worker] |
[:aurora_meter, :pro, :webhook] |
duration_ms |
type, outcome, duplicate, api_version |
stable | 1.0.0 |
[:aurora_meter, :pro, :webhook] |
[:aurora_meter, :pro, :cutover] |
none |
feature, watermark, action |
stable | 1.0.0 |
[:aurora_meter, :pro, :cutover] |
[:aurora_meter, :pro, :correction] |
count |
outcome, subject_ref, item_id, window, net_value, original_age_seconds |
stable | 1.0.0 |
[:aurora_meter, :pro, :correction] |
[:aurora_meter, :pro, :reconciliation, :difference] |
expected, observed |
kind, tenant_key, feature |
stable | 1.0.0 |
[:aurora_meter, :pro, :reconciliation, :difference] |
[:aurora_meter, :pro, :reconciliation, :run] |
duration_ms, requests, groups, confirmed, items_opened |
stopped |
stable | 1.0.0 |
[:aurora_meter, :pro, :reconciliation, :run] |
[:aurora_meter, :pro, :transition] |
count |
tenant_key, ref, to_plan_id, to_version, result |
stable | 1.0.0 |
[:aurora_meter, :pro, :transition] |
[:aurora_meter, :pro, :usage_report, :plan_fallback] |
count |
tenant_key, feature, period_start, plan_id, plan_version |
stable | 1.0.0 |
[:aurora_meter, :pro, :usage_report, :plan_fallback] |
[:aurora_meter, :pro, :recovery, :action] |
count |
subject, action, outcome, tenant_key |
stable | 1.0.0 |
[:aurora_meter, :pro, :recovery, :action] |
[:aurora_meter, :pro, :retention, :prune] |
deleted, duration |
table, blocked |
stable | 1.0.0 |
[:aurora_meter, :pro, :retention, :prune] |
Three of the four sit in the core’s [:aurora_meter, ...] namespace without
being core events, and the core’s telemetry guide does not list them, because
the core does not know Pro exists. This page is where a host attaching handlers
reads them. New Pro events use the [:aurora_meter, :pro, ...] prefix; the
three historical names are kept, because renaming them would silently detach
every handler already attached.
tenant_key is metadata, never a metric tag: the cardinality is unbounded. The
closed set of names a metric may tag on is core’s
AuroraMeter.Telemetry.tag_allow_list/0, stated once there rather than twice;
AuroraMeter.Pro.Telemetry.events/0 names the tags each event offers, and
Telemetry gives the reason for each.
[:aurora_meter, :pro, :retention, :prune] is listed here since 1.0.0, the
release that first emitted it. It is emitted through a module
attribute, and the guard that checks this page against lib/ matched only a
literal event name, so the event could not be found and could not be documented
without failing that guard. The guard now reads the parsed source.
7. PubSub messages
Aurora Meter Pro broadcasts nothing. There is no Pro PubSub message and no
Pro topic. Live usage and credit balance updates come from the core
(AuroraMeter.Broadcaster.topic/1 and AuroraMeter.Credits.topic/1), which is
what AuroraMeter.Pro.Live.Dashboard subscribes to.
8. Mix tasks
| Entry | Command | Class | Since | Notes |
|---|---|---|---|---|
Mix.Tasks.AuroraMeterPro.Gen.Migration |
mix aurora_meter_pro.gen.migration |
stable | 0.3.0 |
Options -r, --from, --upgrade. The core’s migration is generated separately: both are required. |
Mix.Tasks.AuroraMeterPro.Cutover |
mix aurora_meter_pro.cutover |
stable | 1.0.0 |
Options --list, --feature, --at, --status, --reason, --actor, --tenant. With --feature and no --at it refuses and prints the next period start rather than guessing. It never changes :feature_sources: that is the host’s deploy. |
Mix.Tasks.AuroraMeterPro.Recovery |
mix aurora_meter_pro.recovery |
stable | 1.0.0 |
Subcommands list, inspect, payments, actions, acknowledge, abandon, requeue, attach-intent, abandon-payment. Read-only by default. A mutating subcommand exits non-zero without --reason and --evidence, and without --yes it prints the planned change and writes nothing. --format json for a run pasted into an incident record. |
9. Migration entry points
Section 1.9 lists them. The schema-version contract is the core’s, restated: versions are additive during 1.x, every version is idempotent, and a host calls them from its own Ecto migration. Pro schema version 11 pairs with core schema version 10 in this release, and the two migrations must both run.
10. Test helpers
Supported, and shipped in the Hex tarball, so a host test suite may depend on them. They are governed by the test-helper heading of the support policy rather than by SemVer on every name, and nothing in production should call them.
| Entry | Signature and return | Class | Since | Notes |
|---|---|---|---|---|
AuroraMeter.Pro.Stripe.Fake.reset/0 |
() :: :ok |
stable | 0.1.0 | |
AuroraMeter.Pro.Stripe.Fake.reported/0 |
() :: [map()] |
stable | 0.1.0 | Every usage entry the fake accepted. |
AuroraMeter.Pro.Stripe.Fake.report_attempts/0 |
() :: non_neg_integer() |
stable | 0.3.0 | Attempts, not acceptances: what a test asserts on when it needs to know a retry sent once rather than twice. |
AuroraMeter.Pro.Stripe.Fake.fail_reports/1 |
(term()) :: :ok |
stable | 0.1.0 |
Arity 0 exists and defaults to :stripe_unavailable. |
AuroraMeter.Pro.Stripe.Fake.fail_after_accept/1 |
(term()) :: :ok |
stable | 0.3.0 | Accept at the provider, then fail locally: the uncertain-outcome case. |
AuroraMeter.Pro.Stripe.Fake.clear_failure/0 |
() :: :ok |
stable | 0.1.0 | |
AuroraMeter.Pro.Stripe.Fake.put_subscription/1 |
(map()) :: :ok |
stable | 0.1.0 | |
AuroraMeter.Pro.Stripe.Fake.share_globally!/0 |
() :: :ok |
stable | 0.3.0 | Lets a process other than the test own the fake’s state, for an async-unsafe case. |
AuroraMeter.Pro.Stripe.Fake.global_used?/0 |
() :: boolean() |
stable | 0.3.0 | Whether the shared state was actually read, so a test cannot claim isolation it did not have. |
AuroraMeter.Pro.Credits.StripeClient.Fake.reset/0 |
() :: :ok |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.StripeClient.Fake.calls/0 |
() :: [term()] |
stable | 0.3.0 | Every call the fake received, in order. |
AuroraMeter.Pro.Credits.StripeClient.Fake.fail_payment_intents/1 |
(term()) :: :ok |
stable | 0.3.0 |
Arity 0 exists and defaults to :card_declined. |
AuroraMeter.Pro.Credits.StripeClient.Fake.hold_payment_intents/1 |
(String.t()) :: :ok |
stable | 0.3.0 | Holds intents at a chosen status, for the delayed-notification path. |
AuroraMeter.Pro.Credits.StripeClient.Fake.clear_failure/0 |
() :: :ok |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.StripeClient.Fake.put_payment_intent/1 |
(map()) :: :ok |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.StripeClient.Fake.put_customer/2 |
(String.t(), term()) :: :ok |
stable | 1.0.0 |
What retrieve_customer/1 will answer for one id. Every customer exists until one says otherwise. |
AuroraMeter.Pro.Credits.StripeClient.Fake.no_such_customer/1 |
(String.t()) :: {:error, Stripe.Error.t()} |
stable | 1.0.0 |
Stripe’s own 404 answer in the shape stripity_stripe produces it (code: :invalid_request_error, extra.card_code: :resource_missing), so a test refuses for the reason Stripe would. |
AuroraMeter.Pro.Credits.StripeClient.Fake.put_charge/2 |
(String.t(), term()) :: :ok |
stable | 0.3.0 |
What retrieve_charge/1 will answer, which is what refund reconciliation reads. |
AuroraMeter.Pro.Credits.StripeClient.Fake.put_charge_disputes/2 |
(String.t(), term()) :: :ok |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.StripeClient.Fake.put_tax_rate/1 |
(non_neg_integer()) :: :ok |
stable | 1.1.0 |
Basis points of tax create_tax_calculation/1 adds; zero until set. |
AuroraMeter.Pro.Credits.StripeClient.Fake.fail_tax_calculations/1 |
(term()) :: :ok |
stable | 1.1.0 |
nil clears it. |
AuroraMeter.Pro.Credits.StripeClient.Fake.put_product/1 |
(String.t()) :: :ok |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.StripeClient.Fake.share_globally!/0 |
() :: :ok |
stable | 0.3.0 | |
AuroraMeter.Pro.Credits.StripeClient.Fake.global_used?/0 |
() :: boolean() |
stable | 0.3.0 |
11. Internal modules
Not part of the supported surface. Each carries a stability banner at the top of its module docs where it has module docs at all, and each renders under the “Internal” group in the generated documentation.
The inventory test holds this list as a module attribute and fails when a module
on it appears anywhere in the tables above, and when this list and the
groups_for_modules “Internal” group in mix.exs disagree.
| Entry | Why it is internal |
|---|---|
AuroraMeter.Pro.LiveDashboard.Sections |
The readers behind the Pro operator page. They answer {:ok, data} or {:unavailable, class} and never a zero in place of a figure they could not read. |
AuroraMeter.Pro.LiveDashboard.View |
The HEEx the Pro operator page renders. It reads nothing. |
AuroraMeter.Pro.Install.Templates |
The source snippets mix aurora_meter_pro.install writes into a host. A host reads the generated file, never this module. |
AuroraMeter.Pro.Config.Schema |
The NimbleOptions schema and the whole-environment validator. AuroraMeter.Pro.validate!/0 and the AuroraMeter.Pro.Config accessors are the interface; the schema itself is where a key’s type and default are written, and both are documented in section 5. |
AuroraMeter.Pro.Credits.StripeClient.Fake.State |
The agent behind the credit client fake. The fake’s own functions are the interface. |
AuroraMeter.Pro.Migration.V1 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V2 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V3 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V4 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V5 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V6 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V7 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V8 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V9 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V10 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Migration.V11 |
One schema version. Call AuroraMeter.Pro.Migration.up/1. |
AuroraMeter.Pro.Outbox.Store |
Every read and write of the outbox table. Operators query through AuroraMeter.Pro.Recovery. |
AuroraMeter.Pro.Reconcile.Items |
Every read and write of the reconciliation items table. AuroraMeter.Pro.Reconcile.list_items/1 and resolve_item/3 are the interface. |
AuroraMeter.Pro.Recovery.Action |
The expected-state comparison every recovery mutation runs first, and the one writer of aurora_meter_recovery_actions. AuroraMeter.Pro.Recovery is the interface. |
AuroraMeter.Pro.Schema.OutboxItem |
The outbox row. There is deliberately no update changeset; every transition is a conditional statement in the store. |
AuroraMeter.Pro.Schema.WebhookEvent |
The inbound provider event dedupe record. |
AuroraMeter.Pro.Schema.SourceCutover |
The per-feature watermark between buffered and event reporting. |
AuroraMeter.Pro.Schema.ReconciliationItem |
An open difference between what Pro sent and what the provider shows. |
AuroraMeter.Pro.Schema.RecoveryAction |
The record of what an operator did to a stuck financial record. Append only but for outcome, which an attach rewrites once when its resume answers. Read it through AuroraMeter.Pro.Recovery.actions/2. |
AuroraMeter.Pro.Stripe.Fake.State |
The agent behind the billing provider fake. The fake’s own functions are the interface. |
A function carrying @doc false inside any module is internal for the same
reason, whether or not its module is on this list. That includes every
Oban.Worker callback (perform/1, new/2, backoff/1, timeout/1), every
Plug callback (init/1, call/2), every Phoenix.LiveView callback, and
every AuroraMeter.Billing.Provider and
AuroraMeter.Pro.Credits.StripeClient callback implementation. Call the named
entry point instead: report_all/0 rather than perform/1.
12. Core dependency
Pro consumes the free core through its public API only. It never copies a core schema definition, and the core never references Pro.
| Package | Requirement | Notes |
|---|---|---|
:aurora_meter |
>= 1.0.0-rc.1 and < 2.0.0 |
The requirement in mix.exs. Pro 1.0 requires core 1.0 and nothing older: the previous requirement, ~> 0.4 or ~> 0.5, admitted every 0.x, Hex resolved the newest published core (0.4.0), and this package does not compile against it. Spelled out rather than ~> 1.0 because a ~> requirement never admits a pre-release. The inventory test compares this cell with Mix.Project.config()[:deps], so the two cannot drift. |
The core entries Pro relies on, all of them stable in the core’s own
inventory: the facade (usage/2, usage_all/1, history/3, period/1,
plan/1, quota/2, check/2, entitled?/2, feature_value/3);
AuroraMeter.Storage.load_counter/3, get_subscription/1,
put_subscription/1, load_history_range/4 and stream_counters/1;
everything in AuroraMeter.Credits and AuroraMeter.Credits.Money;
AuroraMeter.Plans.get/1 and AuroraMeter.Plan;
AuroraMeter.Subscriptions.get/1 and invalidate/1;
AuroraMeter.Period.current!/2; AuroraMeter.Clock.now/0 and db_now/0;
AuroraMeter.Flusher.flush/0; AuroraMeter.Test; and the behaviours
AuroraMeter.Billing.Provider and AuroraMeter.Period.
12.1 Direct core-table reads that remain
Two places still build an Ecto query against a core schema module rather than
going through a core function. They are recorded here because an undocumented
coupling is worse than a documented one, and recording them is not endorsing
them: each is internal and each is scheduled for removal. Until then, a core
schema change can break Pro in a way the core’s own inventory does not warn
about.
The alerts sweep’s is gone as of 1.0.0: it walks
AuroraMeter.Storage.list_subscriptions/2 in pages instead, which also stops
it loading every subscription in the installation into one list. Pro’s lib/ now
builds no query against AuroraMeter.Schema.Subscription at all.
The usage reporter’s two are gone as of 1.0.0: subscriptions come from
AuroraMeter.Storage.list_subscriptions/2 and counters from
AuroraMeter.Storage.load_counter/3. The file still names
AuroraMeter.Schema.Subscription, and that is not coupling: it calls
entitled?/1 and entitled_statuses/0, which are pure functions over a struct
the core hands back. See the note at the end of this section.
The inventory test asserts each of these is still there, by matching the query text rather than a line number, so the list cannot quietly rot before the work lands.
The “Replaced by” column is plain text rather than code, because the core
functions it names do not exist yet. A code span would make mix docs warn on every build, which is how
a real broken reference gets missed.
| File | Core schema | Replaced by | Matched in lib/ |
|---|---|---|---|
lib/aurora_meter/pro/rollup.ex |
AuroraMeter.Schema.Counter |
AuroraMeter.Storage.stream_counters/2 |
from(c in Counter, |
lib/aurora_meter/pro/rollup.ex |
AuroraMeter.Schema.History |
AuroraMeter.Storage.stream_history/2 |
from(h in History, |
Reading a core struct is not on this list and is not coupling: the schema modules are public structs in the core’s inventory. What is recorded here is building a query against one.