Skip to content

LucasGabrielBecker/es_vehicle_tracking

Repository files navigation

๐Ÿš— Event Sourced Vehicle Tracking System

A modern, scalable vehicle tracking system built with Event Sourcing and CQRS patterns, powered by PostgreSQL and TypeScript. This project demonstrates the powerful advantages of event sourcing for real-world applications requiring audit trails, temporal queries, and bulletproof data consistency.

๐Ÿ—๏ธ Architecture Overview

This system implements a clean Event Sourcing architecture with Command Query Responsibility Segregation (CQRS):

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────────┐
│   HTTP API      │    │  Event Store     │    │   Projections       │
│   (Commands)    │───โ–ถ│  (PostgreSQL)    │───โ–ถ│  (Read Models)      │
└─────────────────┘    └──────────────────┘    └─────────────────────┘
                              │
                              โ–ผ
                       ┌──────────────────┐
                       │   Event Bus      │
                       │  (Subscribers)   │
                       └──────────────────┘

Key Components

  • Commands: RegisterVehicleCommand, TrackLocationCommand
  • Queries: GetVehicle, VehicleCurrentLocationQuery
  • Events: VehicleRegistered, LocationTracked
  • Projections: VehicleCurrentLocation (materialized view)
  • Event Store: PostgreSQL-based immutable event log

๐ŸŽฏ Why Event Sourcing with PostgreSQL?

1. Complete Audit Trail ๐Ÿ“‹

Every state change is captured as an immutable event, providing:

  • Full history of all vehicle registrations and location updates
  • Compliance-ready audit logs for regulatory requirements
  • Forensic analysis capabilities for debugging and investigation
// Every location update creates an immutable event
{
  eventType: "LocationTracked",
  payload: {
    locationTrackedId: "uuid-v7",
    latitude: 40.7128,
    longitude: -74.0060,
    scope: { vehicleRegisteredId: "vehicle-uuid" }
  },
  timestamp: "2024-01-15T10:30:00Z"
}

2. Time Travel Queries โฐ

Reconstruct system state at any point in time:

  • Historical reporting: "Where was vehicle ABC-123 at 2PM yesterday?"
  • Debugging: "What was the system state when the issue occurred?"
  • Analytics: Track movement patterns over time

3. Bulletproof Consistency ๐Ÿ›ก๏ธ

  • Immutable events prevent data corruption
  • Append-only storage eliminates race conditions
  • Event ordering ensures consistent state reconstruction

4. Scalable Read Models ๐Ÿ“ˆ

  • CQRS separation allows independent scaling of reads and writes
  • Multiple projections from the same event stream
  • Optimized queries with materialized views

5. PostgreSQL Advantages ๐Ÿ˜

  • ACID compliance for reliable event storage
  • JSON support for flexible event payloads
  • Mature ecosystem with excellent tooling
  • Cost-effective compared to specialized event stores

๐Ÿš€ Getting Started

Prerequisites

  • Bun runtime
  • Docker & Docker Compose
  • PostgreSQL 17

Quick Start

  1. Clone and install dependencies:
git clone <repository-url>
cd es_vehicle_tracking
bun install
  1. Start PostgreSQL:
docker-compose up -d
  1. Run the application:
bun start

The API will be available at http://localhost:3000

๐Ÿ“ก API Endpoints

Register a Vehicle

POST /register-vehicle
Content-Type: application/json

{
  "vehicleLicensePlate": "ABC-1234"
}

Response:

{
  "vehicleRegisteredId": "0199456d-fdb5-7000-a29f-b78450c75fd9"
}

Track Vehicle Location

POST /track-location
Content-Type: application/json

{
  "vehicleLicensePlate": "ABC-1234",
  "latitude": 40.7128,
  "longitude": -74.0060
}

Response:

{
  "locationTrackedId": "0199456e-2db3-7000-b45f-c89d60e82a1b"
}

Get Current Vehicle Location

GET /vehicle-current-location/{vehicleRegisteredId}

Response:

{
  "vehicleRegisteredId": "0199456d-fdb5-7000-a29f-b78450c75fd9",
  "vehicleLicensePlate": "ABC-1234",
  "latitude": 40.7128,
  "longitude": -74.0060
}

๐Ÿ”„ Event Sourcing in Action

Event Flow

  1. Command received via HTTP API
  2. Business logic validates the command
  3. Event generated and stored in event store
  4. Projections updated asynchronously via event listeners
  5. Read models provide optimized query performance

Example Event Stream

Event 1: VehicleRegistered
├─ vehicleRegisteredId: "uuid-1"
├─ vehicleLicensePlate: "ABC-1234"
└─ registeredAt: "2024-01-15T09:00:00Z"

Event 2: LocationTracked
├─ locationTrackedId: "uuid-2"
├─ latitude: 40.7128
├─ longitude: -74.0060
└─ scope: { vehicleRegisteredId: "uuid-1" }

Event 3: LocationTracked
├─ locationTrackedId: "uuid-3"
├─ latitude: 40.7589
├─ longitude: -73.9851
└─ scope: { vehicleRegisteredId: "uuid-1" }

๐Ÿ”ง Technical Implementation

Event Store

Built on @ricofritzsche/eventstore with PostgreSQL backend:

  • Immutable event log with automatic versioning
  • Optimistic concurrency control prevents conflicts
  • Event filtering and querying capabilities

Projections

Real-time materialized views updated via event listeners:

// Vehicle current location projection
export async function handleLocationTracked(event: EventRecord) {
  await pg`
    UPDATE vehicle_current_location
    SET latitude = ${latitude}, longitude = ${longitude}
    WHERE vehicle_registered_id = ${vehicleRegisteredId}
  `;
}

CQRS Implementation

  • Commands: Modify state by appending events
  • Queries: Read from optimized projections
  • Separation: Independent scaling and optimization

๐Ÿ› ๏ธ Advanced Features

Projection Rebuilding

Recreate any projection from the event stream:

export async function rebuildVehicleCurrentLocationProjection(
  eventStore: EventStore,
  connectionString: string
) {
  // Truncate existing projection
  await pg`TRUNCATE TABLE vehicle_current_location`;
  
  // Replay all events
  const { events } = await eventStore.query(createQuery(
    createFilter(["VehicleRegistered", "LocationTracked"])
  ));
  
  // Rebuild state from events
  for (const event of events) {
    await handleEvent(event);
  }
}

Error Handling & Resilience

  • Graceful degradation when projections lag
  • Event replay for failed projections
  • Idempotent event handlers prevent duplicate processing

๐Ÿ“Š Performance Benefits

Write Performance

  • Append-only writes are extremely fast
  • No complex joins during writes
  • Minimal locking in PostgreSQL

Read Performance

  • Optimized projections for specific query patterns
  • Denormalized data eliminates complex joins
  • Caching-friendly materialized views

Scalability

  • Horizontal scaling of read replicas
  • Event stream partitioning for high-throughput scenarios
  • Microservice decomposition via bounded contexts

๐Ÿ† Business Advantages

Regulatory Compliance

  • Immutable audit trail for compliance reporting
  • Data retention policies via event archiving
  • Change tracking for regulatory investigations

Analytics & Insights

  • Historical analysis of vehicle movement patterns
  • Temporal queries for business intelligence
  • Event-driven analytics pipelines

Debugging & Support

  • Complete system history for troubleshooting
  • Event replay for reproducing issues
  • Detailed logging of all state changes

๐Ÿงช Testing with HTTP Client

Use the included api.http file with your favorite HTTP client (VS Code REST Client, Postman, etc.):

### Register a vehicle
POST http://localhost:3000/register-vehicle
Content-Type: application/json

{
  "vehicleLicensePlate": "TEST-001"
}

### Track location
POST http://localhost:3000/track-location
Content-Type: application/json

{
  "vehicleLicensePlate": "TEST-001",
  "latitude": 37.7749,
  "longitude": -122.4194
}

๐Ÿ“š Technology Stack

  • Runtime: Bun - Fast JavaScript runtime
  • Framework: Hono - Lightweight web framework
  • Event Store: @ricofritzsche/eventstore - PostgreSQL event store
  • Database: PostgreSQL 17 - Reliable, ACID-compliant storage
  • Validation: Zod - TypeScript-first schema validation
  • Language: TypeScript - Type-safe development

๐ŸŽ“ Learning Resources

Event Sourcing Concepts

PostgreSQL for Event Sourcing

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Submit a pull request

Built with โค๏ธ and Event Sourcing

This project demonstrates the power of event sourcing for building scalable, auditable, and maintainable systems. The combination of PostgreSQL's reliability with modern TypeScript tooling creates a robust foundation for real-world applications.

This readme was generated using an LLM

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors