A robust, concurrency-safe financial ledger API designed for atomic transactions and idempotency.
The Bank Transfer API is a production-grade backend service built to safely handle financial transactions, account creation, and balance tracking. Handling money in distributed systems is notoriously difficult due to race conditions and network failures. This project was built to address those challenges by implementing strict distributed concurrency control, including SELECT ... FOR UPDATE row-level locking, deadlock prevention algorithms, and rigorous idempotency guarantees to ensure zero double-spending or corrupted states.
- Concurrency Safe: Utilizes PostgreSQL row-level locks and predictable lock ordering (
Math.min/Math.max) to completely eliminate race conditions and deadlocks during concurrent transfers. - Idempotent Transfers: Distributed idempotency key checks via
ON CONFLICTconstraints, allowing clients to safely retry network-failed requests without the risk of double charging. - ACID Transactions: Full database transaction support with guaranteed rollbacks for failed or rejected transfers (e.g., insufficient funds).
- Structured Logging via Pino: Zero-cost, JSON-based structured logging for maximum production observability and debugging.
- Automated Testing: Comprehensive integration and concurrency test suites via Supertest and Jest, simulating simultaneous conflicting transfers to prove robustness.
- Self-Documenting API: Fully integrated Swagger UI for interactive, real-time endpoint documentation.
- Containerized: Docker and Docker Compose configurations for instant deployment and isolated database dependencies.
| Category | Technology | Purpose |
|---|---|---|
| Backend Framework | Express.js | High-performance, minimalist web framework for routing. |
| Language | TypeScript | Strong typing, interfaces, and compile-time error catching. |
| Database | PostgreSQL | Relational database utilizing robust ACID compliance and locks. |
| Database Driver | pg (node-postgres) |
Direct, low-overhead PostgreSQL connection pooling. |
| Testing | Jest & Supertest | Unit, integration, and concurrency race-condition testing. |
| Logging | Pino | High-speed structured JSON logging for production. |
| Containerization | Docker & Compose | Infrastructure orchestration and environment parity. |
| Documentation | Swagger / OpenAPI | Interactive API documentation generation. |
.
└── backend/
├── app.ts # Express application setup, middlewares, and swagger init
├── server.ts # Server entry point and database initialization
├── controllers/ # Route controllers handling HTTP request/response validation
├── db/ # PostgreSQL connection pool and schema init scripts
├── routes/ # Express API route definitions
├── services/ # Core business logic and database transaction queries
├── tests/ # Jest test suites (including heavy concurrency tests)
├── utils/ # Utilities (e.g., Pino logger configuration)
├── Dockerfile # Production-ready Docker image configuration
├── docker-compose.yml # Orchestration for the API and PostgreSQL containers
├── package.json # Dependencies and NPM scripts
└── tsconfig.json # TypeScript compilation configuration
- Node.js (v20+ recommended)
- Docker & Docker Compose
-
Clone the repository:
git clone https://github.com/devdesai06/Bank-Transfer-api.git cd "Bank Transfer Project"/backend
-
Install dependencies:
npm install
-
Environment Setup: Create a
.envfile in thebackenddirectory based on your environment:# .env PORT=3000 DB_HOST=localhost DB_PORT=5433 DB_USER=postgres DB_PASSWORD=postgres DB_NAME=bank_transfer LOG_LEVEL=info
You must have a PostgreSQL instance running locally.
npm run devTo run the entire ecosystem (API + Database) in isolated containers without needing local PostgreSQL installed:
docker compose up --build- The API will be available at
http://localhost:3000. - The PostgreSQL database is mapped to host port
5433(to avoid conflicts with local DBs). - Docker Compose utilizes a built-in startup retry loop in the application to gracefully wait for the database to become healthy.
Once the server is running, navigate to the Swagger UI to view and interact with the endpoints: 👉 http://localhost:3000/api-docs
Request:
POST /api/transfers
Content-Type: application/json
Idempotency-Key: a3d2c88f-1234-5678-abcd-ef9012345678
{
"fromAccountId": 1,
"toAccountId": 2,
"amount": 500
}Response (201 Created):
{
"success": true,
"data": {
"id": 1,
"from_account_id": 1,
"to_account_id": 2,
"amount": "500.00",
"created_at": "2026-06-18T12:00:00.000Z"
}
}The project contains comprehensive tests that evaluate basic functionality, boundary conditions (insufficient funds), and complex asynchronous race conditions.
To run the test suite:
npm testNote: Ensure your test database is running and credentials match your .env.
The project utilizes Pino for logging.
- Development: When
NODE_ENVis notproduction, logs are piped throughpino-prettyto provide colorized, human-readable console output. - Production: In production environments, logs default to high-performance, machine-readable JSON formats, which are strictly optimized for ingestion by log aggregators like Datadog, ELK, or AWS CloudWatch.
Contributions, issues, and feature requests are welcome! Feel free to check the issues page.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is open-source and available under the MIT License.