A Node.js + TypeScript RESTful banking system with in-memory storage, JWT authentication, OpenAPI docs, and full test coverage.
bankingSystemMock/
├── src/
│ ├── app.ts # Express app and middleware
│ ├── server.ts # Server entry point
│ ├── models/
│ │ └── Account.ts # Type definitions
│ ├── routes/
│ │ └── bankingRoutes.ts # All API routes
│ └── services/
│ └── BankingService.ts # Business logic (atomic operations)
├── tests/
│ └── banking.test.ts # Jest unit and integration tests
├── postman/
│ └── Banking System Mock API.postman_collection.json # Postman collection
├── openapi.yaml # OpenAPI 3.1 spec
├── Dockerfile # Docker build config
├── .dockerignore
├── package.json
└── README.md
-
Account Management
- Create account (unique name, non-negative balance)
- List all accounts
- Get account by ID
-
Transactions
- Deposit (positive amount only)
- Withdraw (cannot overdraw)
- Transfer (atomic, cannot transfer to self, cannot overdraw)
-
Transaction Logs
- Get all transactions for an account
- Get all transactions
-
API Documentation
- Swagger UI (JWT support)
-
Security
- JWT authentication (all
/apiroutes require Bearer Token) - Helmet, rate-limit, unified error format
- JWT authentication (all
-
Testing
- Jest unit and integration tests, covers all edge cases
-
Docker Support
- One-command build/run, no need for local Node/npm
npm installCreate a .env file (or use environment variables):
JWT_SECRET=6b2e1f9c-8a3d-4d7e-9c2a-7f1b2e3c4d5e
Note: This secret is for testing/demo only. In production, use a secure secret managed by your cloud platform or a Secret Manager.
npm run devnpm test
npm run test:coveragedocker build -t banking-system-mock .
docker run -p 9999:9999 --env JWT_SECRET=6b2e1f9c-8a3d-4d7e-9c2a-7f1b2e3c4d5e banking-system-mockNote: This secret is for testing/demo only. In production, use environment variables or a Secret Manager.
version: '3'
services:
api:
build: .
ports:
- "9999:9999"
environment:
- JWT_SECRET=your_secretdocker-compose up --build- Swagger UI: http://localhost:9999/docs
- OpenAPI YAML:
openapi.yaml
- All
/apiroutes require Bearer Token (JWT). UseAuthorization: Bearer <token>in the header. - Invalid or missing JWT returns 401 Unauthorized.
- The default JWT_SECRET is for testing only. Always use a secure secret in production.
- Max 100 requests per minute (shared across all APIs). Exceeding this returns 429 Too Many Requests.
- See
openapi.yamland Swagger UI for 429 error examples.
- All amounts must be positive; account balances cannot be negative.
- Account names must be unique.
- Transfers cannot be to self (
fromId ≠ toId), and source account must have sufficient balance. - Request body only allows specified fields; extra fields will be rejected.
- All API responses follow
{ success, data, error, message } - On failure,
success: false,errorcontains the error message, anddatais null.
- All accounts and transactions are stored in memory; data is lost on server restart.
- No data persistence or multi-threaded deployment.
- No multi-currency, advanced permissions, or pagination (can be extended if needed).
- Import
postman/Banking System Mock API.postman_collection.json - Set the
baseUrlvariable tohttp://localhost:9999 - Set the Bearer Token (the collection includes a demo token)
POST /api/accountsCreate accountGET /api/accountsList all accountsGET /api/accounts/:idGet account by IDPOST /api/accounts/:id/depositDepositPOST /api/accounts/:id/withdrawWithdrawPOST /api/accounts/transferTransferGET /api/accounts/:id/transactionsGet account transaction logsGET /api/transactionsGet all transactions
- All data is in-memory and will be cleared on server restart.
- All API responses follow
{ success, data, error, message }