Skip to content

mostafasayed/wallet-service

Repository files navigation

Event-Driven Wallet Microservice

A production-ready event-driven wallet system with strong consistency guarantees, real-time analytics, and fraud detection.

Features

  • Deposits, Withdrawals & Transfers with ACID guarantees
  • Idempotency via request IDs for all operations
  • Immutable Event Log for complete audit trail
  • Background Worker for analytics and fraud detection
  • RabbitMQ for asynchronous event processing
  • Dead Letter Queue (DLQ) for fault tolerance
  • Pessimistic Locking for concurrency control
  • Real-time Analytics and fraud detection

Table of Contents


Project Structure

.
β”œβ”€β”€ services/
β”‚   β”œβ”€β”€ api/           # NestJS HTTP API service
β”‚   └── worker/        # NestJS event worker service
β”œβ”€β”€ libs/
β”‚   β”œβ”€β”€ common/        # Shared enums, types, and event contracts
β”‚   └── db-orm/        # TypeORM entities shared across services
β”œβ”€β”€ tools/
β”‚   └── monkey-test.js # Load testing utility
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ DESIGN.md          # Detailed architecture documentation
└── README.md

Technology Stack

Category Technologies
Runtime Node.js, TypeScript
Framework NestJS
Database PostgreSQL 16
ORM TypeORM
Message Broker RabbitMQ
Testing Jest
DevOps Docker, Docker Compose
Package Manager NPM Workspaces

Quick Start

Prerequisites

  • Node.js 18+
  • Docker & Docker Compose
  • npm 9+

Installation

# Install dependencies
npm install

Run with Docker Compose

Create a .env at the repo root (see Environment Variables or copy .env.example) so the API and worker containers get DB/RabbitMQ settings:

# Start all services
docker-compose up --build

This starts:

Service URL/Port Credentials
API http://localhost:3000 -
Swagger UI http://localhost:3000/api -
PostgreSQL localhost:5432 wallet / wallet
RabbitMQ UI http://localhost:15672 guest / guest
RabbitMQ AMQP localhost:5672 guest / guest

API Documentation

Interactive API Documentation

The API is fully documented using Swagger/OpenAPI. Once the services are running, visit:

http://localhost:3000/docs

This provides:

  • Complete endpoint documentation
  • Interactive API testing
  • Request/response schemas
  • Validation rules

Generate Swagger JSON

To generate a static swagger.json file:

cd services/api
npm run generate:swagger

Quick API Overview

Endpoint Method Description
/wallet/:id/deposit POST Deposit funds into a wallet
/wallet/:id/withdraw POST Withdraw funds from a wallet
/wallet/:id/transfer POST Transfer funds between wallets
/wallet/:id GET Get wallet balance and details
/wallet/:id/history GET Get transaction history
/wallet/:id/stats GET Get wallet statistics

πŸ’‘ Tip: All write operations support idempotency via the requestId field.


Background Worker

The worker service processes events asynchronously and provides:

Analytics

  • Tracks total deposited/withdrawn amounts
  • Monitors transfer activity (in/out)
  • Records last activity timestamp
  • Maintains per-wallet statistics

Fraud Detection

Rule 1: Rapid Withdrawals

  • Flags wallets with β‰₯3 withdrawals within 60 seconds

Rule 2: Large Transactions

  • Flags single withdrawals β‰₯ configurable threshold (default: 10,000)

Fault Tolerance

wallet.events.worker (main queue)
        ↓
    [Processing]
        ↓
   Success β†’ ACK
        ↓
   Failure β†’ NACK β†’ wallet.events.worker.dlq (DLQ)

Dead Letter Queue (DLQ):

  • Failed messages are routed to wallet.events.worker.dlq
  • Messages can be inspected and replayed manually
  • Prevents poison messages from blocking the queue

Testing

Unit Tests

API Service:

cd services/api
npm test

Coverage:

  • βœ… Deposit/Withdraw/Transfer operations
  • βœ… Idempotency guarantees
  • βœ… Saga pattern & compensation
  • βœ… Event emission

Worker Service:

cd services/worker
npm test

Coverage:

  • βœ… Analytics aggregation
  • βœ… Fraud detection rules
  • βœ… Worker idempotency

Stress Testing

Validate the system under high concurrency:

# Default: 1000 requests, 100 concurrent
npm run monkey

Validates:

  • Pessimistic row-level locking
  • Saga correctness for transfers
  • Idempotency under retry load
  • No race conditions
  • Worker throughput

Script: tools/monkey-test.js


Monitoring & Logging

Application Logs

Logs are written to:

logs/api.log      # API service logs
logs/worker.log   # Worker service logs

Features:

  • JSON format for structured logging
  • Automatic log rotation
  • Configurable log levels
  • Winston logger integration

API Audit Trail

All POST requests are recorded in the api_audit table:

Field Description
method HTTP method
url Request URL
body Request body
headers Request headers
client_ip Client IP address
timestamp Request timestamp
api_audit_id Unique audit ID (linked to events)

Development

Environment Variables

Create a .env file in the root directory:

Docker Compose (default):

DB_HOST=postgres
DB_PORT=5432
DB_USER=wallet
DB_PASS=wallet
DB_NAME=wallet

RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672
RABBITMQ_EXCHANGE=wallet.events
RABBITMQ_DLX=wallet.events.dlx

ENABLE_SWAGGER=true

Running Locally (without Docker Compose)

1. Start PostgreSQL:

docker run --name wallet-pg \
  -p 5432:5432 \
  -e POSTGRES_USER=wallet \
  -e POSTGRES_PASSWORD=wallet \
  -e POSTGRES_DB=wallet \
  -d postgres:16

2. Start RabbitMQ:

docker run --name wallet-rmq \
  -p 5672:5672 \
  -p 15672:15672 \
  -d rabbitmq:3-management

3. Start API Service:

cd services/api
npm run start:dev

4. Start Worker Service:

cd services/worker
npm run start:dev

Code Quality

Pre-commit Hooks (Husky + lint-staged):

  • βœ… TypeScript type checking
  • βœ… ESLint validation
  • βœ… Automatic formatting

CI/CD (GitHub Actions):

  • Runs on every PR and commit
  • Executes: lint β†’ type-check β†’ tests

Architecture Highlights

Strong Consistency

  • Pessimistic locking ensures wallet balance integrity
  • ACID transactions for all write operations
  • No negative balances enforced at database level

Event-Driven Design

  • Immutable event log for complete audit trail
  • Event sourcing enables time-travel debugging
  • Asynchronous processing for analytics and notifications

Saga Pattern

Transfer operations use the Saga pattern:

Initiated β†’ Debited β†’ Completed
                ↓
           Compensated β†’ Failed

Idempotency

  • API operations: (requestId, walletId) uniqueness
  • Transfers: requestId on TransferEntity
  • Worker: ProcessedEventEntity prevents duplicate processing

Scalability

  • Horizontal scaling of API and worker services
  • Database connection pooling for high throughput
  • Per-wallet locking allows parallel operations on different wallets

Documentation


Summary

This project demonstrates a production-ready event-driven wallet microservice with:

  • βœ… Strong consistency for balance updates
  • βœ… Event-driven architecture with RabbitMQ
  • βœ… Saga pattern for distributed transactions
  • βœ… Idempotency at every layer
  • βœ… Fault-tolerant background processing with DLQ
  • βœ… Real-time fraud detection and analytics
  • βœ… Comprehensive test suite with stress testing
  • βœ… Production-ready logging and monitoring

About

Event-Driven Wallet Microservice

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors