A secure full-stack banking backend system built using Python, Flask, SQLite, and JavaScript.
This project demonstrates production-style backend architecture, including authentication, layered design, security hardening, and REST API integration with a frontend dashboard.
The Banking Core System simulates real-world banking operations while applying professional backend engineering practices.
The system supports:
- Account creation
- Deposit funds
- Withdraw funds
- Money transfer
- Transaction history
- Authentication
- Account locking
- Admin account unlock
Unlike basic CRUD projects, this system implements:
✔ Layered Architecture
✔ Repository Pattern
✔ Domain Entity Modeling
✔ JWT Authentication
✔ Token Refresh & Blacklisting
✔ Rate Limiting
✔ Security Headers
✔ SQLite Persistence
✔ Transaction Logging
Frontend (HTML / JS)
↓
Flask REST API
↓
Service Layer (Business Logic)
↓
Repository Layer (Database Access)
↓
SQLite Database
This structure ensures:
- clean separation of responsibilities
- scalable architecture
- maintainable codebase
- Python
- Flask
- SQLite
- PyJWT
- Flask-Limiter
- Flask-Talisman
- python-dotenv
- HTML
- TailwindCSS
- Vanilla JavaScript
- Fetch API
This project implements multiple backend security mechanisms.
Two token system:
Access Token
Expires in 15 minutes
Refresh Token
Expires in 7 days
Refresh tokens include JTI identifiers.
Revoked tokens are stored in:
token_blacklist table
Used for:
- logout
- token revocation
- refresh security
Implemented using Flask-Limiter.
Examples:
Login → 5 requests/minute
Transfer → 5 requests/minute
Deposit → 20 requests/minute
Withdraw → 20 requests/minute
Prevents brute-force and abuse attacks.
Security mechanism for authentication.
3 incorrect PIN attempts → account locked
Unlock requires:
ADMIN_KEY
Implemented using Flask-Talisman
Includes:
- HSTS
- X-Frame-Options
- X-Content-Type-Options
- Content Security Policy
- Name validation
- PIN hashing
- Unique account generation
- Initial transaction logging
- Validates account
- Ensures positive amount
- Updates balance atomically
- Logs transaction
- Validates account
- Prevents overdraft
- Logs withdrawal
- Atomic transfer operation
- Logs sender and receiver transactions
Returns full transaction audit trail including:
- transaction type
- amount
- balance after transaction
- timestamp
| Method | Endpoint | Description |
|---|---|---|
| POST | /auth/login |
User login |
| POST | /auth/refresh |
Refresh tokens |
| POST | /auth/logout |
Logout |
| Method | Endpoint | Description |
|---|---|---|
| POST | /accounts |
Create account |
| GET | /accounts/<id> |
View balance |
| POST | /accounts/<id>/deposit |
Deposit money |
| POST | /accounts/<id>/withdraw |
Withdraw money |
| POST | /accounts/<id>/transfer |
Transfer money |
| GET | /accounts/<id>/transactions |
Transaction history |
| Method | Endpoint | Description |
|---|---|---|
| POST | /accounts/<id>/unlock |
Unlock locked account |
| Column | Description |
|---|---|
| account_number | Unique account identifier |
| account_holder_name | Owner name |
| pin_hash | Hashed PIN |
| balance | Current balance |
| created_at | Creation timestamp |
| failed_attempts | Failed login attempts |
| is_locked | Account lock state |
| role | user / admin |
| Column | Description |
|---|---|
| account_number | Related account |
| transaction_type | Deposit / Withdraw / Transfer |
| amount | Transaction amount |
| balance_after | Balance after operation |
| timestamp | Transaction time |
| Column | Description |
|---|---|
| jti | Token identifier |
| revoked_at | Revocation time |
The project includes a simple banking dashboard.
Login
Register
Dashboard
Transfer
Transactions
Frontend communicates with backend using:
Fetch API
banking-core/
│
├── app/
│ │
│ ├── __init__.py
│ ├── routes.py
│ ├── auth.py
│ ├── config.py
│ ├── errors.py
│ └── extensions.py
│
├── entities/
│ ├── account.py
│ └── transaction.py
│
├── repository/
│ └── account_repository.py
│
├── services/
│ └── banking_services.py
│
├── exceptions/
│ ├── base_exception.py
│ ├── account_not_found_exception.py
│ ├── invalid_amount_exception.py
│ └── ...
│
├── database/
│ └── accounts.db
│
├── frontend/
│ │
│ ├── src/
│ │ │
│ │ ├── css/
│ │ │ ├── input.css
│ │ │ └── output.css
│ │ │
│ │ ├── js/
│ │ │ ├── api.js
│ │ │ ├── login.js
│ │ │ ├── dashboard.js
│ │ │ ├── transfer.js
│ │ │ ├── transactions.js
│ │ │ ├── register.js
│ │ │ ├── admin.js
│ │ │ └── admin_dashboard.js
│ │ │
│ │ ├── index.html
│ │ ├── dashboard.html
│ │ ├── transfer.html
│ │ ├── transactions.html
│ │ ├── register.html
│ │ ├── admin.html
│ │ ├── admin_dashboard.html
│ │ └── admin_unlock_account.html
│ │
│ └── package.json
│
├── logs/
│ └── banking_core.log
│
├── tests/
│ └── test_api.py
│
├── docs/
│ └── development_log.md
│
├── .env
├── requirements.txt
├── run.py
└── README.md
pip install -r requirements.txt
Create .env
SECRET_KEY=your_secret_key
ADMIN_KEY=your_admin_key
FLASK_DEBUG=true
python run.py
Server runs at:
http://127.0.0.1:5000
- Layered Architecture
- Repository Pattern
- Dependency Injection
- Domain Modeling
- RESTful Design
- JWT Authentication
- Security Hardening
- Atomic Transactions
- Centralized Error Handling
- Separation of Concerns
Possible improvements:
- Docker containerization
- CI/CD pipeline
- API documentation (Swagger)
- PostgreSQL migration
- Automated testing
- Role-based admin dashboard
- Request validation (Pydantic)
Full architectural evolution:
development_log.md
Start simple.
Refactor intentionally.
Separate responsibilities.
Design for scale.
🏦 Built as a structured backend architecture project demonstrating real-world engineering practices.