Skip to content

Rooster212/event-sourced-example-app-banking

Repository files navigation

DynamoDB Event Sourcing Example - Banking

A small React app for explaining event sourcing with a DynamoDB-flavoured example. It uses @rooster212/event-sourced-rules-engine for aggregate orchestration, event processing rules, and the browser storage adapter.

The app uses a bank account aggregate to show how commands such as CreateAccount, Deposit, Withdraw, and FreezeAccount become immutable events. Those events are then committed through the rules engine and replayed in order to build an account projection with a balance, status, counters, and the latest stream version.

A hosted version of this is available here: https://eventsourcing.jamieroos.dev/

Purpose

Event sourcing can be hard to explain because the important behaviour is indirect: the application does not simply update a row of current state. It appends facts to an event stream, then derives current state from those facts.

This project makes that flow visible:

  • A command represents an intention to change an account.
  • The rules engine commits accepted events to an aggregate stream.
  • A Processor rule updates projection state for each event type.
  • A projection is rebuilt by applying each event in sequence.
  • A DynamoDB item preview shows how an event could be stored with partition and sort keys.

The example is deliberately small. It uses the library's browser storage contract with an in-memory Storage implementation so refreshing the browser still resets the demo. It is intended as a teaching aid, not as a production event store.

What The App Demonstrates

  • Command handling for a simple account aggregate.
  • Appending immutable account events through Aggregate.append.
  • Replaying events with Processor rules to derive a projection.
  • Rejected commands becoming explicit audit events, such as WithdrawalRejected.
  • A DynamoDB single-table style event item:
    • PK as the aggregate stream key, for example ACCOUNT#ACCOUNT-1001.
    • SK as the ordered event key, for example EVENT#000003.
    • metadata showing the originating command and recorded timestamp.
    • a secondary index shape for querying by event type.
  • DynamoDB deployment concepts such as append-only writes, optimistic concurrency, and projection updates from streams or workers.

Requirements

  • Node.js 20.19.0 or newer, or Node.js 22.12.0 or newer.
  • npm.
  • Access to GitHub Packages for the @rooster212 npm scope.
  • Docker, if you want to build and run the production container.

The local project was built with Node 24.

The project .npmrc points @rooster212 at GitHub Packages and uses legacy-peer-deps=true so npm does not install the library's optional AWS/CDK peer dependencies for this browser-only demo.

Run Locally

Install dependencies:

npm install

Start the Vite development server:

npm run dev

Open:

http://localhost:5173

Build

Create a production build:

npm run build

The static site is written to dist/.

To preview the production build locally:

npm run preview

Docker Deployment

Build the container image for your current machine:

docker build --secret id=npmrc,src=$HOME/.npmrc -t dynamodb-event-sourcing-lab .

Run it locally:

docker run --rm -p 8080:80 dynamodb-event-sourcing-lab

Open:

http://localhost:8080

The Docker image uses a multi-stage build:

  • node:24-alpine installs dependencies and runs npm run build.
  • nginx:stable-alpine serves the generated dist/ files.
  • BuildKit uses the native build platform for the Node/Vite build, then selects the nginx runtime image for the requested target platform.
  • The npmrc secret gives npm ci access to GitHub Packages without copying your token into the image.

To build one target architecture and load it into your local Docker image store:

docker buildx build --platform linux/arm64 --secret id=npmrc,src=$HOME/.npmrc -t dynamodb-event-sourcing-lab --load .
docker buildx build --platform linux/amd64 --secret id=npmrc,src=$HOME/.npmrc -t dynamodb-event-sourcing-lab --load .

To publish a multi-architecture image for both ARM64 and AMD64, tag it with your registry name and push it:

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --secret id=npmrc,src=$HOME/.npmrc \
  -t ghcr.io/rooster212/event-sourced-example-app-banking:latest .

# push to github registry
docker push ghcr.io/rooster212/event-sourced-example-app-banking:latest

The nginx config includes a fallback to index.html, so the app can support client-side routes if routes are added later.

Notes

  • The app stores demo events through the rules engine's browser storage adapter, backed by an in-memory Storage implementation. Refreshing the browser resets the demo.
  • There is no real DynamoDB table in this project.
  • The DynamoDB JSON shown in the UI is an educational representation of how events can be shaped for storage.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors