Incident

Event Sourcing and CQRS in Elixir abstractions.

Special thanks to my friend Paulo Gonzalez for the name suggestion for this library.

Goals

Event Sourcing and CQRS

In a nutshell, Event Sourcing ensures that all changes to application state are stored as a sequence of events. But if you are new to Event Sourcing and CQRS I highly recommend watch Greg Young's presentation at Code on the Beach 2014 before moving forward.

Main Components

Planned Next Steps

The list below is the upcoming enhacements or fixes, it will grow as the library is being developed.

Installation

If available in Hex, the package can be installed by adding incident to your list of dependencies in mix.exs:

def deps do
[
{:incident, "~> 0.4.0"}
]
end

Configuration

Event Store and Projection Store Setup

Configure incidentEvent Store and Projection Store adapters and some options. The options will be passed in during the adapter initialization.

In Memory Adapter

The goal of using the In Memory Adapter is to provide a quick way to store events and projections, as a playground tool. This adapter is not suppose to be used in a real application.

config :incident, :event_store, adapter: Incident.EventStore.InMemoryAdapter,
options: [
initial_state: []
]
config :incident, :projection_store, adapter: Incident.ProjectionStore.InMemoryAdapter,
options: [
initial_state: %{}
]

Postgres Adapter

The Postgres adapter uses Ecto behind the scenes so a lot of its configuration it is simply how you should configure a Postgres database for any application using Ecto.

There will be two databases, one to store the events and another one to be used by the projections. The events database will contain only one table (events) and the projections database will contain one table fore each projection type.

Add the Ecto Repo modules for both databases:

defmodule AppName.EventStoreRepo do
use Ecto.Repo,
otp_app: :app_name,
adapter: Ecto.Adapters.Postgres
end
defmodule AppName.ProjectionStoreRepo do
use Ecto.Repo,
otp_app: :app_name,
adapter: Ecto.Adapters.Postgres
end

In your application config.exs specify the repositories:

config :app_name, ecto_repos: [AppName.EventStoreRepo, AppName.ProjectionStoreRepo]

In your application dev|test|prod.exs:

config :app_name, AppName.EventStoreRepo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "app_name_event_store_dev"
config :app_name, AppName.ProjectionStoreRepo,
username: "postgres",
password: "postgres",
hostname: "localhost",
database: "app_name_projection_store_dev"
config :incident, :event_store, adapter: Incident.EventStore.PostgresAdapter,
options: [
repo: AppName.EventStoreRepo
]
config :incident, :projection_store, adapter: Incident.ProjectionStore.PostgresAdapter,
options: [
repo: AppName.ProjectionStoreRepo
]

Create the application databases running the Ecto mix task:

mix ecto.create

Use the Incident Mix task to generate the events table migration, and run the migration:

mix incident.postgres.init -r AppName.EventStoreRepo
mix ecto.migrate

The migrations and schemas for the projections will depend on your application domains.

Getting Started

There is an example application that implements a Bank application for reference, including all the details and usage in IEx as well.

It also contains projections specific to the application domain with migration and schemas defined.

This example application will give you all the details in how to use Incident, including integration tests.

Documentation

The full documentation can be found at https://hexdocs.pm/incident.