Multi-item subscription surface (BILL-12).
add_item/3, remove_item/2, and update_item_quantity/3 mutate
a subscription's item list through the processor adapter and project
the result to the local accrue_subscription_items table inside a
single Repo.transact/1 block.
All three require an explicit :proration option (BILL-09 carryover) —
Accrue never inherits Stripe's default proration behavior. Missing
proration raises at NimbleOptions validation time.
The WR-09 non-bang + reduce_while pattern is used for any list
upsert path so Ecto.InvalidChangesetError propagates cleanly
rather than aborting the enclosing transaction.
Summary
Functions
@spec add_item(Accrue.Billing.Subscription.t(), String.t(), keyword()) :: {:ok, Accrue.Billing.SubscriptionItem.t()} | {:error, term()}
@spec add_item!(Accrue.Billing.Subscription.t(), String.t(), keyword()) :: Accrue.Billing.SubscriptionItem.t()
@spec remove_item( Accrue.Billing.SubscriptionItem.t(), keyword() ) :: {:ok, Accrue.Billing.SubscriptionItem.t()} | {:error, term()}
@spec remove_item!( Accrue.Billing.SubscriptionItem.t(), keyword() ) :: Accrue.Billing.SubscriptionItem.t()
@spec update_item_quantity( Accrue.Billing.SubscriptionItem.t(), pos_integer(), keyword() ) :: {:ok, Accrue.Billing.SubscriptionItem.t()} | {:error, term()}
@spec update_item_quantity!( Accrue.Billing.SubscriptionItem.t(), pos_integer(), keyword() ) :: Accrue.Billing.SubscriptionItem.t()