hyeonjae/eventsourcing-ledger
Event Sourcing Stock Trading System
A fully functional Golang stock trading system built with Event Sourcing architecture, featuring order management, account handling, and real-time event processing.
🏗️ Architecture
This system implements Event Sourcing using:
- Domain-Driven Design (DDD) with clear separation of concerns
- CQRS (Command Query Responsibility Segregation) pattern
- Event Store for persistence of domain events
- Event Bus for asynchronous event processing
- Aggregates for business logic encapsulation
- Uber FX for dependency injection
- PostgreSQL for event storage and read models
📁 Project Structure
eventsourcing-ledger/
├── cmd/
│ └── main.go # Application entry point with FX setup
├── internal/
│ ├── application/ # Application layer
│ │ ├── handlers/ # Event handlers
│ │ └── services/ # Application services
│ ├── config/ # Configuration management
│ ├── domain/ # Domain layer (core business logic)
│ │ ├── aggregates/ # Domain aggregates
│ │ ├── entities/ # Domain entities
│ │ └── events/ # Domain events
│ ├── infrastructure/ # Infrastructure layer
│ │ ├── database/ # Database connections
│ │ ├── eventbus/ # Event bus implementation
│ │ └── eventstore/ # Event store implementation
│ └── ports/ # Ports & adapters
│ └── http/ # HTTP handlers and routes
├── migrations/ # Database schema migrations
├── scripts/ # Utility scripts
├── docker-compose.yml # Docker composition
├── Dockerfile # Container definition
└── README.md # This file
🚀 Quick Start
Prerequisites
- Go 1.23+
- Docker & Docker Compose
- PostgreSQL (if running locally)
Option 1: Using Docker Compose (Recommended)
- Clone and start the system:
git clone <repository-url>
cd eventsourcing-ledger
docker-compose up --build- Test the API:
./scripts/test-api.shOption 2: Local Development
- Start PostgreSQL:
docker run --name postgres-ledger -e POSTGRES_DB=eventsourcing_ledger -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:15-alpine- Apply database migrations:
psql -h localhost -U postgres -d eventsourcing_ledger -f migrations/001_initial_schema.sql- Set environment variables:
cp .env.example .env
# Edit .env file as needed- Run the application:
go mod tidy
go run cmd/main.go📚 API Documentation
The system exposes REST API endpoints for managing accounts and orders.
Base URL
http://localhost:8080/api/v1
Account Management
Create Account
POST /accounts
Content-Type: application/json
{
"account_number": "ACC001",
"initial_cash": 10000.00
}Get Account
GET /accounts/{accountNumber}Add Cash
POST /accounts/{accountNumber}/cash
Content-Type: application/json
{
"amount": 5000.00,
"reason": "Deposit"
}Add Stock
POST /accounts/{accountNumber}/stock
Content-Type: application/json
{
"symbol": "AAPL",
"quantity": 100,
"reason": "Initial allocation"
}Order Management
Create Order
POST /orders
Content-Type: application/json
{
"account_number": "ACC001",
"symbol": "AAPL",
"order_type": "BUY", // or "SELL"
"quantity": 50,
"price": 150.00
}Get Order
GET /orders/{orderID}Execute Order
POST /orders/{orderID}/execute
Content-Type: application/json
{
"quantity": 25,
"price": 148.50
}Cancel Order
POST /orders/{orderID}/cancel
Content-Type: application/json
{
"reason": "Market conditions changed"
}Health Check
GET /health🎯 Event Sourcing Explanation
Core Concepts
Event Sourcing is a design pattern where state changes are stored as a sequence of events rather than updating records in place.
Key Components
-
Events: Immutable facts about what happened
OrderCreated,ExecutionCreated,MarginReserved, etc.
-
Aggregates: Domain objects that ensure business invariants
OrderAggregate: Manages order lifecycleAccountAggregate: Manages account state and resources
-
Event Store: Persistence mechanism for events
- PostgreSQL-based implementation
- Optimistic concurrency control
- Snapshot support for performance
-
Event Bus: Asynchronous event processing
- In-memory implementation
- Event handler registration
- Error handling and logging
Business Logic Flow
Buy Order Process:
- Order Creation →
OrderCreatedevent - Margin Reservation →
MarginReserved+CashDeductedevents - Order Execution →
ExecutionCreatedevent - Settlement → Account balance updates
Sell Order Process:
- Order Creation →
OrderCreatedevent - Stock Reservation →
StockReserved+StockDeductedevents - Order Execution →
ExecutionCreatedevent - Settlement → Stock and cash updates
Benefits
- Audit Trail: Complete history of all changes
- Temporal Queries: State at any point in time
- Event Replay: Reconstruct state from events
- Scalability: Read/write separation with CQRS
- Reliability: Event-driven architecture with eventual consistency
🧪 Testing
Manual Testing
Use the provided test script to verify functionality:
chmod +x scripts/test-api.sh
./scripts/test-api.shThis script demonstrates:
- Account creation and management
- Order creation (buy/sell)
- Order execution (partial/full)
- Order cancellation
- Margin and stock reservation/release
Example Test Scenario
- Create account with $10,000 cash
- Add 100 AAPL shares to account
- Create buy order for 50 MSFT shares at $300/share
- Create sell order for 25 AAPL shares at $150/share
- Execute orders partially and fully
- Cancel remaining unfilled orders
- Verify account state consistency
⚙️ Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
DB_HOST |
localhost | PostgreSQL host |
DB_PORT |
5432 | PostgreSQL port |
DB_USER |
postgres | Database user |
DB_PASSWORD |
postgres | Database password |
DB_NAME |
eventsourcing_ledger | Database name |
DB_SSLMODE |
disable | SSL mode |
PORT |
8080 | HTTP server port |
LOG_LEVEL |
info | Log level (debug, info, warn, error) |
Database Schema
The system uses PostgreSQL with:
- Event Store:
eventsandsnapshotstables - Read Models: Optimized views for queries
- Indexes: Performance optimization
- Constraints: Data integrity
🔒 Production Considerations
Security
- Input validation on all endpoints
- SQL injection prevention
- Environment-based configuration
- Error handling without information leakage
Performance
- Database connection pooling
- Event snapshots for aggregate reconstruction
- Indexed queries for read models
- Asynchronous event processing
Reliability
- Transaction boundaries for consistency
- Optimistic concurrency control
- Event versioning
- Graceful error handling
🛠️ Development
Adding New Features
- Define Events: Add to
internal/domain/events/ - Update Aggregates: Modify business logic
- Create Handlers: Add event processing logic
- Update API: Add new endpoints if needed
- Test: Verify with integration tests
Common Patterns
- Command: Create/modify aggregate state
- Query: Read from read models
- Event Handler: React to domain events
- Service: Coordinate between aggregates
📝 License
This project is licensed under the MIT License.
🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
For more information about Event Sourcing and CQRS patterns, refer to: