WIP
This commit is contained in:
44
lib/customer_service/aggregates/customer.ex
Normal file
44
lib/customer_service/aggregates/customer.ex
Normal file
@@ -0,0 +1,44 @@
|
||||
defmodule CustomerService.Aggregates.Customer do
|
||||
defstruct [
|
||||
:id,
|
||||
:first_name,
|
||||
:last_name,
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone
|
||||
]
|
||||
|
||||
alias __MODULE__
|
||||
alias Commanded.Aggregates.Aggregate
|
||||
alias CustomerService.Commands
|
||||
alias CustomerService.Events
|
||||
|
||||
@behaviour Aggregate
|
||||
@impl Aggregate
|
||||
def execute(%Customer{id: nil}, %Commands.CreateCustomer{} = cmd) do
|
||||
%Events.CustomerCreated{
|
||||
id: cmd.id,
|
||||
first_name: cmd.first_name,
|
||||
last_name: cmd.last_name,
|
||||
birth_date: cmd.birth_date,
|
||||
gender: cmd.gender,
|
||||
email: cmd.email,
|
||||
phone: cmd.phone
|
||||
}
|
||||
end
|
||||
|
||||
@impl Aggregate
|
||||
def apply(%Customer{} = c, %Events.CustomerCreated{} = e) do
|
||||
%Customer{
|
||||
c
|
||||
| id: e.id,
|
||||
first_name: e.first_name,
|
||||
last_name: e.last_name,
|
||||
birth_date: e.birth_date,
|
||||
gender: e.gender,
|
||||
email: e.email,
|
||||
phone: e.phone
|
||||
}
|
||||
end
|
||||
end
|
||||
36
lib/customer_service/application.ex
Normal file
36
lib/customer_service/application.ex
Normal file
@@ -0,0 +1,36 @@
|
||||
defmodule CustomerService.Application do
|
||||
# See https://hexdocs.pm/elixir/Application.html
|
||||
# for more information on OTP Applications
|
||||
@moduledoc false
|
||||
|
||||
use Application
|
||||
|
||||
@impl true
|
||||
def start(_type, _args) do
|
||||
children = [
|
||||
CustomerService.CommandedApp,
|
||||
CustomerService.Repo,
|
||||
CustomerService.Projectors.Customer,
|
||||
CustomerServiceWeb.Telemetry,
|
||||
{DNSCluster, query: Application.get_env(:customer_service, :dns_cluster_query) || :ignore},
|
||||
{Phoenix.PubSub, name: CustomerService.PubSub},
|
||||
# Start a worker by calling: CustomerService.Worker.start_link(arg)
|
||||
# {CustomerService.Worker, arg},
|
||||
# Start to serve requests, typically the last entry
|
||||
CustomerServiceWeb.Endpoint
|
||||
]
|
||||
|
||||
# See https://hexdocs.pm/elixir/Supervisor.html
|
||||
# for other strategies and supported options
|
||||
opts = [strategy: :one_for_one, name: CustomerService.Supervisor]
|
||||
Supervisor.start_link(children, opts)
|
||||
end
|
||||
|
||||
# Tell Phoenix to update the endpoint configuration
|
||||
# whenever the application is updated.
|
||||
@impl true
|
||||
def config_change(changed, _new, removed) do
|
||||
CustomerServiceWeb.Endpoint.config_change(changed, removed)
|
||||
:ok
|
||||
end
|
||||
end
|
||||
15
lib/customer_service/commanded_app.ex
Normal file
15
lib/customer_service/commanded_app.ex
Normal file
@@ -0,0 +1,15 @@
|
||||
defmodule CustomerService.Router do
|
||||
use Commanded.Commands.Router
|
||||
alias CustomerService.Commands
|
||||
alias CustomerService.Aggregates
|
||||
|
||||
identify(Aggregates.Customer, by: :id)
|
||||
dispatch([Commands.CreateCustomer], to: Aggregates.Customer)
|
||||
end
|
||||
|
||||
defmodule CustomerService.CommandedApp do
|
||||
use Commanded.Application,
|
||||
otp_app: :customer_service
|
||||
|
||||
router(CustomerService.Router)
|
||||
end
|
||||
11
lib/customer_service/commands.ex
Normal file
11
lib/customer_service/commands.ex
Normal file
@@ -0,0 +1,11 @@
|
||||
defmodule CustomerService.Commands.CreateCustomer do
|
||||
defstruct [
|
||||
:id,
|
||||
:first_name,
|
||||
:last_name,
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone
|
||||
]
|
||||
end
|
||||
3
lib/customer_service/event_store.ex
Normal file
3
lib/customer_service/event_store.ex
Normal file
@@ -0,0 +1,3 @@
|
||||
defmodule CustomerService.EventStore do
|
||||
use EventStore, otp_app: :customer_service
|
||||
end
|
||||
12
lib/customer_service/events.ex
Normal file
12
lib/customer_service/events.ex
Normal file
@@ -0,0 +1,12 @@
|
||||
defmodule CustomerService.Events.CustomerCreated do
|
||||
@derive Jason.Encoder
|
||||
defstruct [
|
||||
:id,
|
||||
:first_name,
|
||||
:last_name,
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone
|
||||
]
|
||||
end
|
||||
28
lib/customer_service/projections/customer.ex
Normal file
28
lib/customer_service/projections/customer.ex
Normal file
@@ -0,0 +1,28 @@
|
||||
defmodule CustomerService.Projections.Customer do
|
||||
use Ecto.Schema
|
||||
|
||||
@derive {Jason.Encoder,
|
||||
only: [
|
||||
:id,
|
||||
:first_name,
|
||||
:last_name,
|
||||
:birth_date,
|
||||
:gender,
|
||||
:email,
|
||||
:phone,
|
||||
:inserted_at,
|
||||
:updated_at
|
||||
]}
|
||||
@primary_key {:id, :binary_id, autogenerate: false}
|
||||
@timestamps_opts [type: :utc_datetime_usec]
|
||||
schema "customers" do
|
||||
field :first_name, :string
|
||||
field :last_name, :string
|
||||
field :birth_date, :date
|
||||
field :gender, :string
|
||||
field :email, :string
|
||||
field :phone, :string
|
||||
|
||||
timestamps()
|
||||
end
|
||||
end
|
||||
31
lib/customer_service/projectors/customer.ex
Normal file
31
lib/customer_service/projectors/customer.ex
Normal file
@@ -0,0 +1,31 @@
|
||||
defmodule CustomerService.Projectors.Customer do
|
||||
use Commanded.Projections.Ecto,
|
||||
application: CustomerService.CommandedApp,
|
||||
repo: CustomerService.Repo,
|
||||
name: "CustomerService.Projetors.Customer",
|
||||
consistency: :strong
|
||||
|
||||
alias CustomerService.Events
|
||||
alias CustomerService.Projections.Customer
|
||||
|
||||
project(%Events.CustomerCreated{} = event, fn multi ->
|
||||
Ecto.Multi.insert(multi, :customer, %Customer{
|
||||
id: event.id,
|
||||
first_name: event.first_name,
|
||||
last_name: event.last_name,
|
||||
birth_date: event.birth_date,
|
||||
gender: event.gender,
|
||||
email: event.email,
|
||||
phone: event.phone
|
||||
})
|
||||
end)
|
||||
|
||||
# project %Events.CustomerDeactivated{} = event, _metadata do
|
||||
# Ecto.Multi.update_all(
|
||||
# multi,
|
||||
# :deactivate_customer,
|
||||
# from(c in Customer, where: c.customer_id == ^event.customer_id),
|
||||
# set: [active: false]
|
||||
# )
|
||||
# end
|
||||
end
|
||||
13
lib/customer_service/repo.ex
Normal file
13
lib/customer_service/repo.ex
Normal file
@@ -0,0 +1,13 @@
|
||||
defmodule CustomerService.Repo do
|
||||
use Ecto.Repo,
|
||||
otp_app: :customer_service,
|
||||
adapter: Ecto.Adapters.Postgres
|
||||
|
||||
@doc """
|
||||
Dynamically loads the repository url from the
|
||||
DATABASE_URL environment variable.
|
||||
"""
|
||||
def init(_, opts) do
|
||||
{:ok, Keyword.put(opts, :url, System.get_env("DATABASE_URL"))}
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user