1
- defmodule Fullstack.Wallet.Aggregate.WalletProjector do
1
+ defmodule Fullstack.Wallet.Aggregate.WalletAggregator do
2
2
use GenServer
3
3
require Logger
4
+ @ registry Fullstack.Wallet.Aggregate.WalletAggregators
4
5
5
- @ registry :wallet_projectors
6
6
defstruct [ :customer_id , :value , event_type: :amount_deposited ]
7
7
8
8
def start_link ( customer_id ) do
@@ -20,7 +20,7 @@ defmodule Fullstack.Wallet.Aggregate.WalletProjector do
20
20
apply_event ( pid , event )
21
21
22
22
_ ->
23
- Logger . debug ( "Attempt to apply event to non-existent account, starting projector " )
23
+ Logger . debug ( "Attempt to apply event to non-existent account, starting aggregator " )
24
24
{ :ok , pid } = start_link ( account )
25
25
apply_event ( pid , event )
26
26
end
@@ -30,14 +30,22 @@ defmodule Fullstack.Wallet.Aggregate.WalletProjector do
30
30
GenServer . cast ( pid , { :handle_event , event } )
31
31
end
32
32
33
- def get_balance ( pid ) do
34
- GenServer . call ( pid , :get_balance )
33
+ def get_balance ( customer_id ) when is_binary ( customer_id ) do
34
+ customer_id
35
+ |> lookup_aggregator
36
+ |> GenServer . call ( :get_balance )
35
37
end
36
38
37
- def lookup_balance ( customer_id ) when is_binary ( customer_id ) do
39
+ def get_history ( customer_id ) when is_binary ( customer_id ) do
40
+ customer_id
41
+ |> lookup_aggregator
42
+ |> GenServer . call ( :get_history )
43
+ end
44
+
45
+ defp lookup_aggregator ( customer_id ) when is_binary ( customer_id ) do
38
46
with [ { pid , _ } ] <-
39
47
Registry . lookup ( @ registry , customer_id ) do
40
- { :ok , get_balance ( pid ) }
48
+ pid
41
49
else
42
50
_ ->
43
51
{ :error , :unknown_account }
@@ -46,7 +54,7 @@ defmodule Fullstack.Wallet.Aggregate.WalletProjector do
46
54
47
55
@ impl true
48
56
def init ( customer_id ) do
49
- { :ok , % { balance: 0 , account_number: customer_id } }
57
+ { :ok , % { balance: 0 , account_number: customer_id , commands: [ ] } }
50
58
end
51
59
52
60
@ impl true
@@ -55,31 +63,42 @@ defmodule Fullstack.Wallet.Aggregate.WalletProjector do
55
63
end
56
64
57
65
def handle_event (
58
- % { balance: bal } = s ,
59
- % { event_type: :amount_withdrawn , value: v }
66
+ % { balance: _bal } = s ,
67
+ % { event_type: :amount_withdrawn , value: v } = evt
60
68
) do
61
- % { s | balance: bal - v }
69
+ s
70
+ |> Map . update ( :balance , 0 , & ( & 1 - v ) )
71
+ |> Map . update ( :commands , [ ] , & [ evt | & 1 ] )
62
72
end
63
73
64
74
def handle_event (
65
- % { balance: bal } = s ,
66
- % { event_type: :amount_deposited , value: v }
75
+ % { balance: _bal } = s ,
76
+ % { event_type: :amount_deposited , value: v } = evt
67
77
) do
68
- % { s | balance: bal + v }
78
+ s
79
+ |> Map . update ( :balance , 0 , & ( & 1 + v ) )
80
+ |> Map . update ( :commands , [ ] , & [ evt | & 1 ] )
69
81
end
70
82
71
83
def handle_event (
72
- % { balance: bal } = s ,
73
- % { event_type: :fee_applied , value: v }
84
+ % { balance: _bal } = s ,
85
+ % { event_type: :fee_applied , value: v } = evt
74
86
) do
75
- % { s | balance: bal - v }
87
+ s
88
+ |> Map . update ( :balance , 0 , & ( & 1 - v ) )
89
+ |> Map . update ( :commands , [ ] , & [ evt | & 1 ] )
76
90
end
77
91
78
92
@ impl true
79
93
def handle_call ( :get_balance , _from , state ) do
80
94
{ :reply , state . balance , state }
81
95
end
82
96
97
+ @ impl true
98
+ def handle_call ( :get_history , _from , state ) do
99
+ { :reply , state . commands , state }
100
+ end
101
+
83
102
defp register_via ( customer_id ) do
84
103
{ :via , Registry , { @ registry , customer_id } }
85
104
end
0 commit comments