Accrue.Billing.Metadata (accrue v0.3.0)

Copy Markdown View Source

Stripe-compatible metadata validation and merge helpers.

Metadata in Accrue follows the exact Stripe metadata contract:

  • Flat %{String.t() => String.t()} map (no nested maps)
  • Maximum 50 keys
  • Key length: max 40 characters
  • Value length: max 500 characters
  • "" or nil value means "delete this key" on update

Merge semantics

shallow_merge/2 merges new keys into existing metadata. Keys whose value is "" or nil are removed from the result. No deep merge is supported (D2-10).

Summary

Functions

Shallow-merges new_metadata into existing_metadata.

Validates a metadata field on the given changeset.

Functions

shallow_merge(existing, new)

@spec shallow_merge(map(), map()) :: map()

Shallow-merges new_metadata into existing_metadata.

Keys with "" or nil values in new_metadata are deleted from the result. All other keys are set or overwritten.

Examples

iex> Accrue.Billing.Metadata.shallow_merge(%{"a" => "1"}, %{"b" => "2"})
%{"a" => "1", "b" => "2"}

iex> Accrue.Billing.Metadata.shallow_merge(%{"a" => "1", "b" => "2"}, %{"a" => ""})
%{"b" => "2"}

iex> Accrue.Billing.Metadata.shallow_merge(%{"a" => "1"}, %{"a" => nil})
%{}

validate_metadata(changeset, field)

@spec validate_metadata(Ecto.Changeset.t(), atom()) :: Ecto.Changeset.t()

Validates a metadata field on the given changeset.

Checks that the value is a flat string-key/string-value map within Stripe-compatible constraints. Returns the changeset with errors added if validation fails.