---
title: Event
---

Chronicle is optimized for the scenario of [domain events](https://www.martinfowler.com/eaaDev/DomainEvent.html).
Figuring out the correct name of an [event type](/chronicle/concepts/event-type/) and what properties it should have can be hard.
This page walks through some general guidance on how to do so. Recommend also reading the [Microsoft guide](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/domain-events-design-implementation) on this.

> Note: Read more about the relationship to [event source](/chronicle/concepts/event-source/)

A well-designed event is a single, immutable, past-tense fact. Captured well, the lifecycle
of one thing in your domain reads as a sequence of these facts in the order they happened:

```mermaid
flowchart LR
    subgraph Stream["one person · facts in order, never changed"]
        direction LR
        R["PersonRegistered"] --> N["NameChangedForPerson"] --> A["AddressChangedForPerson"]
    end
```

## Past tense

All events should be named as past tense, something that has happened:

- ItemAddedToCart
- UserRegistered
- AddressChangedForPerson

## Singular purpose

An event should never be ambiguous. It should have a clear meaning and purpose.
It should not be holding information for multiple purposes. For instance holding properties that are empty and only used
for specific purposes. Doing so makes the event unclear to reason about and requires logic in all observers and consumers
of the event.

## Immutable

In an event sourced system, events are considered immutable because they represent facts that have occurred in the past.
Once an event is recorded, it should not be altered, as doing so would compromise the integrity and reliability of the event log.
Immutability ensures that the history of changes is preserved accurately, allowing the system to reconstruct past states and understand the sequence of events that led to the current state.
This immutability is crucial for debugging, auditing, and maintaining a consistent and trustworthy system.

## Avoid nullables / empty values

An event has happened, and it should not represent unclear states.
As with singular purpose, nullable properties are open for interpretation and require extra logic
for every observer and consumer of the event.

Chronicle supports nullable properties on event types when needed.
However, consider this a design smell and prefer introducing a new event type when the meaning differs.
The .NET analyzer rule [CHR0012](/chronicle/code-analysis/chr0012/) warns when nullable event properties are used so you can review the design choice.

> Note: There are conditions where it makes sense to allow null, typical data collection scenario might be the case.
> For instance, a person might not have a middle name.

## Cohesion

Figuring out how "big" an event should be can be even harder.
The things that needs to go together to represent a meaningful change in the system should constitute the boundaries.
If we take a system that holds personal details, the name and social security numbers would be separate from
the address.

Below are some samples of events.

### PersonRegistered

During registration, it might be necessary to capture all the details about a person as below:

```json
{
    "socialSecurityNumber": "12345678901",
    "firstName": "John",
    "middleName": "David",
    "lastName": "Doe",
    "address": "32nd & Main street",
    "postalCode": "123456",
    "city": "Somewhere",
    "country": "Atlantis"
}
```

### NameChangedForPerson

Once registered, changing the name could then only be:

```json
{
    "firstName": "John",
    "middleName": "David",
    "lastName": "Doe"
}
```

### AddressChangedForPerson

Similar for address:

```json
{
    "address": "32nd & Main street",
    "postalCode": "123456",
    "city": "Somewhere",
    "country": "Atlantis"
}
```

## Integrations

When integrating with systems that are non event sourced you would need to deduct the event types from the data structure.
The same approach applies for defining the events as described in this document.

## Event discovery

There are a couple of well known approaches to discovering events in your domain; [Event Storming](https://www.eventstorming.com)
and [Event Modelling](https://eventmodeling.org). We tend to favor the latter as it has more focused building blocks. It gives a good
overview of a an entire system and the flows in it.
