cover/Elixir.WalletJourney.Journey.html

1 defmodule WalletJourney.Journey do
2 @moduledoc """
3 Journey struct representing an end-to-end transfer orchestration.
4
5 A journey progresses through a fixed sequence of steps:
6 1. :limits_check — verify transfer is within configured limits
7 2. :fee_calculation — compute applicable fees
8 3. :initiate_transfer — create the transfer record
9 4. :reserve_funds — reserve funds on the transfer
10 5. :complete_transfer — complete the reserved transfer
11
12 Lifecycle statuses:
13 :started -> :in_progress -> :completed
14 -> :failed
15 -> :compensating -> :compensated
16 """
17
18 @valid_steps [
19 :limits_check,
20 :fee_calculation,
21 :initiate_transfer,
22 :reserve_funds,
23 :complete_transfer
24 ]
25
26 @valid_statuses [
27 :started,
28 :in_progress,
29 :completed,
30 :failed,
31 :compensating,
32 :compensated
33 ]
34
35 @enforce_keys [
36 :journey_id,
37 :user_id,
38 :status,
39 :steps,
40 :completed_steps,
41 :transfer_params,
42 :correlation_id,
43 :started_at
44 ]
45
46 5 defstruct [
47 :journey_id,
48 :user_id,
49 status: :started,
50 current_step: nil,
51 completed_steps: [],
52 steps: @valid_steps,
53 transfer_id: nil,
54 transfer_params: %{},
55 fee_amount: 0,
56 failure_reason: nil,
57 correlation_id: nil,
58 started_at: nil,
59 completed_at: nil,
60 failed_at: nil,
61 metadata: %{}
62 ]
63
64 @type status ::
65 :started
66 | :in_progress
67 | :completed
68 | :failed
69 | :compensating
70 | :compensated
71
72 @type step ::
73 :limits_check
74 | :fee_calculation
75 | :initiate_transfer
76 | :reserve_funds
77 | :complete_transfer
78
79 @type t :: %__MODULE__{
80 journey_id: String.t(),
81 user_id: String.t(),
82 status: status(),
83 current_step: step() | nil,
84 completed_steps: [step()],
85 steps: [step()],
86 transfer_id: String.t() | nil,
87 transfer_params: map(),
88 fee_amount: non_neg_integer(),
89 failure_reason: String.t() | nil,
90 correlation_id: String.t(),
91 started_at: DateTime.t(),
92 completed_at: DateTime.t() | nil,
93 failed_at: DateTime.t() | nil,
94 metadata: map()
95 }
96
97 @doc "Creates a new journey struct with a generated journey_id and timestamp."
98 @spec new(user_id :: String.t(), transfer_params :: map(), opts :: keyword()) :: t()
99
:-(
def new(user_id, transfer_params, opts \\ []) do
100 14 %__MODULE__{
101 journey_id: WalletSharedKernel.TypedId.generate("jrn"),
102 user_id: user_id,
103 status: :started,
104 current_step: :limits_check,
105 completed_steps: [],
106 steps: @valid_steps,
107 transfer_params: transfer_params,
108 fee_amount: 0,
109 failure_reason: nil,
110 correlation_id:
111 Keyword.get(opts, :correlation_id, WalletSharedKernel.Correlation.new_correlation_id()),
112 started_at: DateTime.utc_now(),
113 completed_at: nil,
114 failed_at: nil,
115 metadata: Keyword.get(opts, :metadata, %{})
116 }
117 end
118
119 @doc "Returns the list of valid journey steps."
120 55 def valid_steps, do: @valid_steps
121
122 @doc "Returns the list of valid journey statuses."
123
:-(
def valid_statuses, do: @valid_statuses
124 end
Line Hits Source