Interesting! I can see how
In the past, I have settled on using embedded schemas for everything except projections, which need regular schemas. Commands, events, aggregates, handlers, etc would all have embedded schemas so that readers wouldn’t have to understand structs vs schemas. That’s one less decision a developer has to make when adding new features.
Changesets are defined in each command, but not for aggregates. However, I would return a changeset when rejecting a command in an aggregate. This approach allows for validation before dispatching the command, which works nicely with LiveView.
def execute(%__MODULE__{status: nil}, %StartSession{} = command) do
[
%SessionStarted{
session_id: command.session_id,
name: command.name
}
]
end
def execute(%__MODULE__{}, %StartSession{}) do
{:error,
%__MODULE__{}
|> Changeset.change()
|> Changeset.add_error(:session_id, "has already started")}
end
It’s cool to see different approaches to working with ES code. Thanks for sharing.






















