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
""ornilvalue 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-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})
%{}
@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.