Skip to content

Instantly share code, notes, and snippets.

@mgiacomini
Created April 18, 2020 19:28
Show Gist options
  • Save mgiacomini/db36de97c941e166837c701d9e7c9b17 to your computer and use it in GitHub Desktop.
Save mgiacomini/db36de97c941e166837c701d9e7c9b17 to your computer and use it in GitHub Desktop.
domain_structure.ex
defmodule CustomerManagement.Accounts do
@moduledoc """
Accounts context.
Use this context for any interaction with business rules with person or company related.
"""
alias CustomerManagement.Accounts.Person
alias CustomerManagement.Accounts.Commands.CreatePersonCommand
@doc """
Create a new person.
## Examples:
iex> create_person(%{name: "mauricio})
{:ok, %Person{name: "mauricio"}}
"""
@spec create_person(map()) :: {:ok, Person.t()} | {:error, Ecto.Changeset.t()}
def create_person(attrs \\ %{}) do
CreatePersonCommand.execute(attrs)
end
end
defmodule CustomerManagement.Accounts.Person do
defstruct [:id, :name]
@type t :: %CustomerManagement.Accounts.Person{
id: String.t(),
name: String.t(),
}
end
defmodule CustomerManagement.Accounts.Commands.CreatePersonCommand do
@moduledoc false
alias CustomerManagement.Repo
alias CustomerManagementBroker, as: Broker
import Ecto.Changeset
alias CustomerManagement.Accounts.Person
@spec execute(map()) :: {:ok, Person.t()} | {:error, Ecto.Changeset.t()}
def execute(%{} = attrs) do
# bubble up the error when insert/1 returns {:error, changeset}
with {:ok, person} <- attrs |> changeset() |> Repo.insert() do
Logger.info("Person created: #{inspect(person)}")
publish_event(person)
{:ok, person}
end
end
defp changeset(attrs) do
%Person{}
|> cast(attrs, [:name])
|> validate_required([:name])
end
alias CustomerManagement.Accounts.Events.PersonCreatedEvent
defp publish_event(%Person{} = person) do
Broker.publish(:person_created, PersonCreatedEvent.new(person))
end
end
defmodule CustomerManagementBroker.B2b.IndicationCreatedSubscriber do
@moduledoc false
alias CustomerManagement.Accounts
alias Conduit.Message
# precisamos saber o correlation-id para tracing
# precisamos saber o usuário que está fazendo isso. (user-id?)
# => base de usuários não é centralizada, fodeu!
def process(message) do
Logger.info("Processing `b2b.indication.created` message: #{inspect(message)}")
with {:ok, _person} <- message |> attrs() |> Accounts.create_person() do
Logger.info("Message `b2b.indication.created` processed")
Message.ack(message)
else
{:error, changeset} ->
# When catch changeset errors, is because the contract for this event is wrong.
# For cases like this we want to send the message to a deadletter exchange or error queue to debug later.
# Sometimes, we can try to reprocess; but that's not usually.
Logger.error("Error processing the message `b2b.indication.created`: #{inspect(changeset)}")
end
defp attrs(%{body: body} = message) do
%{name: "#{body["first_name"]} #{body["last_name"]}"}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment