cover/Elixir.WalletLimitsFees.LimitPolicy.html

1 defmodule WalletLimitsFees.LimitPolicy do
2 @moduledoc """
3 Struct representing a limit policy rule set for a given tier and currency.
4
5 Controls maximum transaction amount, daily spend limit, and monthly spend limit.
6 Versioned to support audit traceability per ADR 0011.
7 """
8
9 alias WalletSharedKernel.TypedId
10
11 @valid_tiers [:standard, :premium, :business]
12
13 @enforce_keys [
14 :policy_id, :tier, :currency,
15 :max_transaction_amount, :daily_limit, :monthly_limit,
16 :version, :active, :created_at, :updated_at
17 ]
18
:-(
defstruct [
19 :policy_id, :tier, :currency,
20 :max_transaction_amount, :daily_limit, :monthly_limit,
21 :created_at, :updated_at,
22 version: 1,
23 active: true
24 ]
25
26 @type t :: %__MODULE__{
27 policy_id: String.t(),
28 tier: :standard | :premium | :business,
29 currency: String.t(),
30 max_transaction_amount: pos_integer(),
31 daily_limit: pos_integer(),
32 monthly_limit: pos_integer(),
33 version: pos_integer(),
34 active: boolean(),
35 created_at: DateTime.t(),
36 updated_at: DateTime.t()
37 }
38
39 @doc "Creates a new limit policy for the given tier and currency."
40 @spec new(tier :: atom(), currency :: String.t(), max_txn :: pos_integer(), daily :: pos_integer(), monthly :: pos_integer()) :: t()
41 def new(tier, currency, max_txn, daily, monthly) do
42 14 now = DateTime.utc_now()
43 14 %__MODULE__{
44 policy_id: TypedId.generate("lp"),
45 tier: tier,
46 currency: currency,
47 max_transaction_amount: max_txn,
48 daily_limit: daily,
49 monthly_limit: monthly,
50 version: 1,
51 active: true,
52 created_at: now,
53 updated_at: now
54 }
55 end
56
57 @doc "Bumps version and applies new attribute values from a map."
58 @spec bump_version(t(), attrs :: map()) :: t()
59 def bump_version(%__MODULE__{} = policy, attrs) do
60 1 %{policy |
61 1 version: policy.version + 1,
62 updated_at: DateTime.utc_now(),
63 1 max_transaction_amount: Map.get(attrs, :max_transaction_amount, policy.max_transaction_amount),
64 1 daily_limit: Map.get(attrs, :daily_limit, policy.daily_limit),
65 1 monthly_limit: Map.get(attrs, :monthly_limit, policy.monthly_limit)
66 }
67 end
68
69 @doc "Returns the list of valid tiers."
70
:-(
def valid_tiers, do: @valid_tiers
71 end
Line Hits Source