Accrue.Billing.SubscriptionSchedule (accrue v0.3.1)

Copy Markdown View Source

Ecto schema for accrue_subscription_schedules (BILL-16).

Thin projection of Stripe's SubscriptionSchedule resource. Stripe is canonical for phase state; we persist only the typed columns accrue_admin LiveView filters and sorts on, plus a data jsonb that stores the full Stripe payload (string-keyed) for callers that want to inspect the raw shape.

Follows the D3-17 dual-changeset pattern — changeset/2 validates status transitions on the user path, force_status_changeset/2 bypasses that validation on the webhook path because Stripe is the source of truth for schedule state.

Summary

Functions

User-path changeset with status validation.

Webhook-path changeset (D3-17). Stripe is canonical for schedule state; this path skips the status allowlist so out-of-order events can settle arbitrary state without validation failing.

Canonical list of SubscriptionSchedule statuses.

Types

t()

@type t() :: %Accrue.Billing.SubscriptionSchedule{
  __meta__: term(),
  canceled_at: term(),
  current_phase_index: term(),
  customer: term(),
  customer_id: term(),
  data: term(),
  id: term(),
  inserted_at: term(),
  last_stripe_event_id: term(),
  last_stripe_event_ts: term(),
  lock_version: term(),
  metadata: term(),
  next_phase_at: term(),
  phases_count: term(),
  processor: term(),
  processor_id: term(),
  released_at: term(),
  status: term(),
  subscription: term(),
  subscription_id: term(),
  updated_at: term()
}

Functions

changeset(schedule_or_changeset, attrs \\ %{})

@spec changeset(
  %Accrue.Billing.SubscriptionSchedule{
    __meta__: term(),
    canceled_at: term(),
    current_phase_index: term(),
    customer: term(),
    customer_id: term(),
    data: term(),
    id: term(),
    inserted_at: term(),
    last_stripe_event_id: term(),
    last_stripe_event_ts: term(),
    lock_version: term(),
    metadata: term(),
    next_phase_at: term(),
    phases_count: term(),
    processor: term(),
    processor_id: term(),
    released_at: term(),
    status: term(),
    subscription: term(),
    subscription_id: term(),
    updated_at: term()
  }
  | Ecto.Changeset.t(),
  map()
) :: Ecto.Changeset.t()

User-path changeset with status validation.

force_status_changeset(schedule_or_changeset, attrs \\ %{})

@spec force_status_changeset(
  %Accrue.Billing.SubscriptionSchedule{
    __meta__: term(),
    canceled_at: term(),
    current_phase_index: term(),
    customer: term(),
    customer_id: term(),
    data: term(),
    id: term(),
    inserted_at: term(),
    last_stripe_event_id: term(),
    last_stripe_event_ts: term(),
    lock_version: term(),
    metadata: term(),
    next_phase_at: term(),
    phases_count: term(),
    processor: term(),
    processor_id: term(),
    released_at: term(),
    status: term(),
    subscription: term(),
    subscription_id: term(),
    updated_at: term()
  }
  | Ecto.Changeset.t(),
  map()
) :: Ecto.Changeset.t()

Webhook-path changeset (D3-17). Stripe is canonical for schedule state; this path skips the status allowlist so out-of-order events can settle arbitrary state without validation failing.

statuses()

@spec statuses() :: [String.t()]

Canonical list of SubscriptionSchedule statuses.