cover/Elixir.WalletSettlement.Commands.RunSettlementBatch.html

1 defmodule WalletSettlement.Commands.RunSettlementBatch do
2 @moduledoc """
3 Command to create and enqueue a settlement batch for async execution.
4
5 Creates a pending `SettlementBatch`, persists it, then enqueues a
6 `SettlementWorker` job on the `:settlement_high` queue.
7
8 Returns `{:ok, batch}` on success or `{:error, reason}`.
9 """
10
11 alias WalletSettlement.{SettlementBatch, SettlementStore, JobQueue}
12 alias WalletSettlement.Workers.SettlementWorker
13 alias WalletObservability.AuditEvent
14
15 @spec execute(
16 window_start :: DateTime.t(),
17 window_end :: DateTime.t(),
18 transfer_ids :: [String.t()],
19 opts :: keyword()
20 ) :: {:ok, SettlementBatch.t()} | {:error, term()}
21 14 def execute(window_start, window_end, transfer_ids, opts \\ []) do
22 7 correlation_id = Keyword.get(opts, :correlation_id, WalletSharedKernel.Correlation.new_correlation_id())
23
24 7 batch = SettlementBatch.new(window_start, window_end, transfer_ids,
25 total_amount: Keyword.get(opts, :total_amount, 0),
26 currency: Keyword.get(opts, :currency),
27 correlation_id: correlation_id,
28 metadata: Keyword.get(opts, :metadata, %{})
29 )
30
31 7 with :ok <- SettlementStore.store(batch),
32 7 {:ok, _job_id} <- JobQueue.enqueue(:settlement_high, SettlementWorker, %{
33 7 "batch_id" => batch.batch_id,
34 "correlation_id" => correlation_id
35 }) do
36 7 emit_audit(batch.batch_id, correlation_id, length(transfer_ids))
37 {:ok, batch}
38 end
39 rescue
40
:-(
error -> {:error, error}
41 end
42
43 7 defp emit_audit(batch_id, correlation_id, transfer_count) do
44 7 audit = AuditEvent.build(:settlement, "settlement_batch_queued", "settlement_batch", batch_id,
45 :success, correlation_id: correlation_id, metadata: %{transfer_count: transfer_count})
46 7 :telemetry.execute([:wallet_settlement, :audit], %{}, audit)
47 rescue
48
:-(
_ -> :ok
49 end
50 end
Line Hits Source