A production-grade, highly secure Banking Ledger System API built with Node.js, Express, and MongoDB. This system implements double-entry bookkeeping principles where the immutable ledger serves as the single source of truth for all account balances.
The application follows a clean MVC/layered structure separating routes, request validation, authentication middlewares, business logic controllers, and database access schemas.
graph TD
Client[Client Browser / API Client] -->|HTTP Request| Express[Express App Server]
subgraph Express [Express App Pipeline]
Router[Router] --> Middleware[Middleware Layer]
Middleware -->|1. Validate Payload| Zod[Zod Validation Middleware]
Zod -->|2. Authenticate & Blacklist| Auth[Auth Middleware]
Auth --> Controller[Controllers Layer]
end
Controller -->|Read/Write| Models[Mongoose Models]
subgraph Database [Database Layer]
Models -->|ACID Session| MongoDB[(MongoDB Atlas)]
end
Controller -->|SMTP TLS / OAuth2| GmailAPI[Gmail OAuth2 Service]
All account balances are derived in real-time from matching debit/credit ledger records. Balances are never stored as mutable numbers directly in accounts.
erDiagram
USER {
ObjectId _id PK
string name
string email
string password
boolean systemUser
}
ACCOUNT {
ObjectId _id PK
ObjectId user FK
string status "ACTIVE | FROZEN | CLOSED"
string currency "INR | etc."
boolean systemAccount
}
TRANSACTION {
ObjectId _id PK
ObjectId fromAccount FK
ObjectId toAccount FK
number amount
string status "PENDING | COMPLETED | FAILED | REVERSED"
string idempotencyKey
}
LEDGER {
ObjectId _id PK
ObjectId account FK
ObjectId transaction FK
number amount
string type "DEBIT | CREDIT"
}
BLACKLIST {
ObjectId _id PK
string token
date blacklistdAt
}
USER ||--o{ ACCOUNT : owns
ACCOUNT ||--o{ LEDGER : has
TRANSACTION ||--o{ LEDGER : references
This diagram illustrates the sequence of checks, transactions, and notification dispatches during a peer-to-peer money transfer.
sequenceDiagram
autonumber
actor Client
participant API as Express API
participant DB as MongoDB (ACID Session)
participant Mail as Gmail OAuth2 Service
Client->>API: POST /api/transactions (payload)
API->>API: Run Zod request validation
API->>API: Verify JWT & Blacklist check
API->>DB: Check if idempotencyKey already exists
alt Key exists
DB-->>API: Return transaction state (COMPLETED/PENDING/FAILED)
API-->>Client: Respond with cached transaction state
end
API->>DB: Verify both fromAccount & toAccount status is ACTIVE
API->>DB: Calculate sender's balance (aggregation sum of CREDITs - DEBITs)
alt Balance < amount
API-->>Client: Return 400 Insufficient Balance
end
API->>DB: Start MongoDB session & startTransaction
API->>DB: Create Transaction record (status: PENDING)
API->>DB: Create DEBIT ledger entry for sender
API->>DB: Create CREDIT ledger entry for receiver
API->>DB: Update Transaction record (status: COMPLETED)
API->>DB: Commit Transaction & endSession
API-->>Client: Respond 201 Transaction Completed Successfully
API->>Mail: Trigger sendTransactionEmail (Async)
- Immutable Ledger Integrity: Ledger records cannot be updated or deleted. Database-level
prehooks and field immutability constraints block all tampering attempts, ensuring a perfect audit trail. - Full ACID Safety: Peer-to-peer transfers are wrapped in MongoDB database sessions. If any individual database insertion fails (e.g. database network drops), the entire operation rolls back.
- Hardened Idempotency Guarantee: Submitting the same transaction payload twice returns the cached result of the original transaction, eliminating double-spending risk.
- JWT Session Blacklisting (Secure Logout): Blacklisted tokens are stored in a high-speed collection with a MongoDB TTL index (automatically expiring and cleaning up from the DB after 3 days).
- Defensive Schema Parsing: Powered by Zod, payload validation runs at the router level, automatically sanitizing inputs (trimming/lowercasing emails) and short-circuiting malformed requests before hitting controllers.
Banking_System_Backend(Advanced)/
βββ server.js # Entry point & connection boot
βββ package.json # Core dependencies and runtime scripts
βββ setup-system-user.js # Privileged system user bootstrap script
βββ src/
βββ app.js # Express configuration, routing, and Swagger UI
βββ config/
β βββ db.js # MongoDB connection management
β βββ swagger.js # Swagger OpenAPI specification definitions
βββ controllers/
β βββ auth.controller.js # User auth handlers (Register, Login, Logout)
β βββ account.controller.js# Account management & dynamic ledger balance
β βββ transaction.controller.js # Atomic transfer logic & funds seeding
βββ middleware/
β βββ auth.middleware.js # JWT authentication & session blacklist checks
β βββ validate.middleware.js # Generic Zod validation handler
βββ model/
β βββ user.model.js # User document schema
β βββ account.model.js # Account document schema
β βββ transaction.model.js # Transaction tracking schema
β βββ ledger.model.js # Immutable double-entry ledger database schema
β βββ blacklist.model.js # Token blacklist document schema (TTL indexed)
βββ routes/
β βββ auth.route.js # Auth routing rules & Swagger specs
β βββ account.route.js # Account routing rules & Swagger specs
β βββ transaction.route.js # Transaction routing rules & Swagger specs
βββ services/
β βββ email.service.js # Nodemailer and Gmail OAuth2 service
βββ validators/
βββ auth.validator.js # Schema constraints for register & login
βββ account.validator.js # Schema constraints for account creations
βββ transaction.validator.js # Schema constraints for transaction transfers
- Node.js (v18+)
- MongoDB Atlas (or a local MongoDB replica set for transaction sessions support)
- Google Cloud Project Credentials (for Gmail OAuth2 email dispatch)
- Clone the repository:
git clone https://github.com/devbyhimans/Bank_ledger.git cd Bank_ledger/Banking_System_Backend(Advanced) - Install the required dependencies:
npm install
Create a .env file in the root directory (Banking_System_Backend(Advanced)/):
PORT=3000
MONGO_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/BankingLedger
JWT_SECRET=your_high_entropy_jwt_secret_key
# Gmail OAuth2
EMAIL_USER=your_gmail_address@gmail.com
CLIENT_ID=your_google_client_id
CLIENT_SECRET=your_google_client_secret
REFRESH_TOKEN=your_google_refresh_tokenRun the setup script to bootstrap the system user and a corresponding system account (needed to seed initial funds to new users):
node setup-system-user.js- Development mode (with hot-reload):
npm run dev
- Production mode:
npm start
π‘ Interactive swagger documentation is served at
http://localhost:3000/api-docsonce the server starts.
| Method | Path | Description | Authorization | Payload Validation |
|---|---|---|---|---|
| POST | /register |
Sign up user & send welcome email | Public | Zod Schema |
| POST | /login |
Authorize session and acquire JWT | Public | Zod Schema |
| POST | /logout |
Invalidate token and clear cookies | JWT Protected | Session Token |
| Method | Path | Description | Authorization | Payload Validation |
|---|---|---|---|---|
| POST | /create |
Open a new bank account | JWT Protected | Zod Schema |
| GET | / |
Retrieve list of owned accounts | JWT Protected | Session Token |
| GET | /balance/:accountId |
Query balance (dynamic ledger aggregation) | JWT Protected | Path Param |
| Method | Path | Description | Authorization | Payload Validation |
|---|---|---|---|---|
| POST | / |
Execute P2P transfer (ACID Compliant) | JWT Protected | Zod Schema |
| POST | /system/intial-funds |
Seed funds into account | System User only | Zod Schema |
| Method | Path | Description |
|---|---|---|
| GET | /api-docs |
Interactive Swagger UI (includes auth persisting) |
- Language/Platform: Node.js & Javascript (CommonJS module system)
- HTTP Router: Express.js v5.0 (supporting modern middleware patterns)
- DBMS & ODM: MongoDB Atlas & Mongoose v9.x
- Validation Engine: Zod v4.x
- Crypto & Signatures: JWT (jsonwebtoken) & bcrypt
- Documentation: swagger-jsdoc & swagger-ui-express
Licensed under the ISC License.
Built with β€οΈ by devbyhimans