Created
April 18, 2020 19:28
-
-
Save mgiacomini/db36de97c941e166837c701d9e7c9b17 to your computer and use it in GitHub Desktop.
domain_structure.ex
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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