Enterprise-inspired banking backend built to learn backend engineering from first principles.
CSBank is a long-term educational project designed to understand how modern backend systems are built by implementing each layer manually before relying on higher-level abstractions.
The goal is not simply to build a banking application, but to understand why every abstraction exists and how it works underneath.
Current Phase
π§ Phase 8 β Security Engineering
Current feature status:
Customer Registration β
Customer Profile β
Create Account (Checking/Savings) β
Deposit β
Transfer β
Transaction History β
Audit Logging β
Relational DB Design (3NF) β
Dapper / PostgreSQL Persistence β
Entity Framework Core β
JWT Authentication β
Login β
Refresh Tokens β
Refresh Token Hashing β
Refresh Token Expiration β
Refresh Token Rotation β
Logout / Refresh Token Revocation β
Authorization π§
API Security π§
Security Hardening π§
Security Testing π§
Architecture status:
β Stable
Current persistence preference:
Writes β EF Core where appropriate
Reads β Dapper / Handwritten SQL
Preferred approach for CSBank:
Dapper + PostgreSQL
EF Core has been learned and integrated successfully, but it is not currently the primary persistence abstraction for the project. Dapper and handwritten PostgreSQL remain preferred where they provide the level of SQL control desired by the project.
CSBank follows one core principle:
Understand the abstraction before using the abstraction.
Every framework introduced in this project should explain a concept that has already been implemented manually.
The preferred learning process is:
Problem
β
Concept
β
Pattern
β
Manual Understanding
β
Abstraction
β
Implementation
β
Verification
AI is primarily used as a conceptual reviewer rather than a code generator.
The goal is to develop the ability to independently reason about:
Application Behavior
β
Persistence
β
Database State
β
Transactions
β
Concurrency
β
Security
flowchart LR
subgraph Core
Application --> Domain
end
Infrastructure --> Application
Api --> Application
Api --> Infrastructure
Dependency direction:
API
βββ Application
βββ Infrastructure
Application
βββ Domain
Infrastructure
βββ Application
Domain
βββ nothing
CSBank follows these design principles throughout the project.
- Domain owns business rules.
- Application orchestrates use cases.
- Infrastructure implements persistence.
- API handles HTTP and dependency injection.
- The Domain remains persistence-agnostic.
Repositories should:
- Execute SQL / queries through the appropriate persistence abstraction
- Supply parameters
- Return results
Infrastructure owns:
- Connection lifecycle
- Transactions
- Commit / rollback
- Database-specific implementation details
CSBank intentionally uses a hybrid persistence strategy:
Persistence
β
βββββββββββββ΄ββββββββββββ
β β
Dapper EF Core
β β
Handwritten SQL Change Tracking
Precise Reads Unit of Work
β β
βββββββββββββ¬ββββββββββββ
β
PostgreSQL
Dapper is preferred when explicit SQL control, PostgreSQL features, and predictable query behavior are important.
EF Core is used as a learned persistence abstraction and remains available when its change tracking and unit-of-work capabilities provide value.
Whenever appropriate:
One Business Operation
β
One Transaction
β
One SQL Statement
β
Multiple CTEs
β
One Database Round Trip
The goal is to let PostgreSQL perform relational work efficiently while keeping transaction boundaries explicit.
Current balance is mutable.
Transaction history is immutable.
Financial operations are modeled around transactional consistency and an auditable transaction history.
CSBank explicitly considers concurrency during financial operations.
Where appropriate:
Transaction
β
Row Lock
β
Business Validation
β
State Change
β
Transaction History
β
Audit
PostgreSQL mechanisms such as:
FOR UPDATE- Transactions
- Constraints
- Atomic SQL statements
- Writable CTEs
are used to maintain consistency.
Current stack:
- C#
- ASP.NET Core Web API
- PostgreSQL
- Dapper
- Entity Framework Core
- Npgsql
- JWT Authentication
Planned / future:
- CancellationToken / request cancellation
- Authorization policies
- Rate limiting
- CORS configuration
- Security hardening
- Security testing
- xUnit
- NSubstitute
- Redis
- Docker
- Payment gateway sandbox integration
- Angular client
- Clean Architecture
- Dependency Injection
- Repository Pattern
- Domain Services
- Manual Mapping
- Application Services
- Composition Root
- Separation of concerns
- PostgreSQL
- Transactions
- Constraints
- Relationships
- JOINs
- CTEs
- Writable CTEs
RETURNINGFOR UPDATE- Referential Integrity
- Indexes
EXPLAINEXPLAIN ANALYZE- Query plan interpretation
- Dapper
- Npgsql
- Connection Factory
- Repository Executor
- Higher-Order Functions
- Parameterized SQL
- Transaction Management
- EF Core
DbContextDbSet- Fluent API
- Entity Configurations
- Navigation Properties
- Change Tracking
- Entity States
SaveChanges- Tracking vs.
AsNoTracking - Generated SQL inspection
- EF Core vs. Dapper trade-offs
- Business workflow modeling
- Atomic operations
- Row-level locking
- Race condition prevention
- Ledger design
- Transaction history
- Audit logging
- Financial state transitions
Implemented financial operations include:
Deposit
Transfer
Account Creation
Transaction History
- JWT access tokens
- Authentication middleware
- Login
- Password verification
- Refresh tokens
- Refresh-token hashing
- Refresh-token expiration
- Refresh-token rotation
- Refresh-token revocation
- Logout
- Claims
- Roles
Current authentication lifecycle:
Login
β
Access Token + Refresh Token
β
Authenticated API Requests
β
Access Token Expiration
β
Refresh Token
β
New Access Token
Logout:
Logout
β
Refresh Token Revoked
β
Existing Access Token
β
Remains valid until JWT expiration
The current access-token lifetime is intentionally short-lived, while refresh tokens provide session continuity.
Currently being expanded toward:
[Authorize]- Roles
- Claims
- Policies
- Resource ownership
- Endpoint protection
Currently exploring:
The current focus is expanding CSBank from an authenticated backend into a properly authorized and security-hardened backend.
Current topics:
- Authentication lifecycle verification
- CancellationToken
- Request cancellation
- Authorization
- Roles
- Claims
- Policies
- Resource ownership
- CORS
- Rate limiting
- Request validation
- Security headers
- Secrets management
- Database least privilege
- Security testing
Payment integration is planned as a future extension of CSBank.
The initial objective is payment-gateway sandbox integration, not handling real customer funds.
The learning focus will be:
Payment Creation
β
Payment Provider
β
Payment Status
β
Webhook
β
Webhook Verification
β
Idempotency
β
Payment State Machine
β
Database Transaction
β
Transaction History
β
Audit
The purpose is to learn distributed payment workflows, asynchronous events, idempotency, retries, and failure handling without prematurely introducing real-money operational requirements.
Project documentation is located in /docs.
| Document | Purpose |
|---|---|
Project.md |
Long-term project blueprint |
Path.md |
Learning roadmap |
TaskNow.md |
Current implementation status |
CSBank
βββ docs
β βββ Project.md
β βββ Path.md
β βββ TaskNow.md
β βββ ADR.md
β
βββ src
β βββ csbank.Api
β βββ csbank.Application
β βββ csbank.Domain
β βββ csbank.Infrastructure
Build a production-quality banking backend while understanding every abstraction beneath the backend stack.
By the completion of CSBank, this project aims to demonstrate practical knowledge of:
- Clean Architecture
- Software Engineering
- Database Engineering
- Persistence Engineering
- Business Operations Engineering
- Entity Framework Core
- Performance Engineering
- Networking
- Concurrency
- Security
- Distributed Systems
- Caching
- Testing
- Payment Integration
- Deployment
Rather than treating frameworks as black boxes, CSBank builds an understanding of the underlying concepts before adopting higher-level tooling.
The ultimate goal is not simply:
Build a banking API.
It is:
Become capable of designing and implementing backend systems while understanding what the abstractions are actually doing.