FinTrack API is a personal finance management REST API built with C#, ASP.NET Core, Entity Framework Core, PostgreSQL, JWT Authentication, FluentValidation, xUnit and a simplified Clean Architecture approach.
The goal of this project is to provide a clean, scalable and testable backend for managing accounts, categories, transactions and monthly financial summaries. It is designed as a portfolio project with real-world backend practices, clear architecture boundaries and professional documentation.
Status: Work in progress. The project is being developed step by step, with the MVP features listed below.
- About the Project
- Features
- Tech Stack
- Architecture
- Project Structure
- Getting Started
- Running Locally
- Running with Docker
- Database Configuration
- Migrations
- Running Tests
- API Documentation
- Main Endpoints
- Example Requests
- Security Notes
- Roadmap
- Git Workflow
FinTrack API helps users track their personal finances through a secure REST API.
Each authenticated user can manage:
- Financial accounts
- Income and expense categories
- Transactions
- Monthly summaries
The API is designed around a key security principle:
A user can only access financial data that belongs to their own account.
This makes the project a strong portfolio piece because it demonstrates:
- REST API design
- Authentication and authorization with JWT
- Layered architecture
- Entity Framework Core persistence
- Validation with FluentValidation
- Unit testing
- Docker-based local environment
- Professional documentation
- User registration
- Login with JWT
- Financial account CRUD
- Category CRUD
- Transaction CRUD
- Transaction filters by month, year, type and category
- Monthly summary with:
- Total income
- Total expenses
- Final balance
- Swagger documentation
- Unit tests
- Docker support
- Refresh tokens
- Pagination for transaction lists
- Search transactions by description
- Annual reports
- Reports by category
- CSV import
- CSV export
- Integration tests
- GitHub Actions CI
- Cloud deployment
- C#
- ASP.NET Core Web API
- Entity Framework Core
- PostgreSQL
- JWT Bearer Authentication
- Swagger / OpenAPI
- FluentValidation
- xUnit
- Moq
- FluentAssertions
- Docker
- Clean Architecture
This project follows a simplified Clean Architecture structure.
FinTrack.Api
FinTrack.Application
FinTrack.Domain
FinTrack.Infrastructure
FinTrack.Tests
| Layer | Responsibility |
|---|---|
FinTrack.Domain |
Core business entities and enums |
FinTrack.Application |
DTOs, validators, interfaces and use cases |
FinTrack.Infrastructure |
Database, repositories, EF Core, JWT and technical implementations |
FinTrack.Api |
Controllers, middlewares, Swagger and dependency injection |
FinTrack.Tests |
Unit tests for application rules and validators |
Api -> Application -> Domain
Api -> Infrastructure -> Application -> Domain
Infrastructure -> Domain
Tests -> Application
Tests -> Domain
The Domain layer does not depend on any other project.
fintrack-api/
|
├── src/
| ├── FinTrack.Api/
| | ├── Controllers/
| | ├── Extensions/
| | ├── Middlewares/
| | ├── Program.cs
| | ├── appsettings.json
| | └── appsettings.Development.json
| |
| ├── FinTrack.Application/
| | ├── Common/
| | ├── DTOs/
| | ├── Interfaces/
| | ├── Services/
| | └── Validators/
| |
| ├── FinTrack.Domain/
| | ├── Common/
| | ├── Entities/
| | └── Enums/
| |
| └── FinTrack.Infrastructure/
| ├── Authentication/
| ├── Data/
| ├── Extensions/
| └── Repositories/
|
├── tests/
| └── FinTrack.Tests/
|
├── .dockerignore
├── .env.example
├── Dockerfile
├── docker-compose.yml
├── FinTrack.slnx
├── .gitignore
└── README.md
Install the following tools:
- .NET SDK 10 or newer
- PostgreSQL or Docker
- Git
- VS Code
Optional:
- GitHub CLI
- Docker Desktop
- Postman or Insomnia
Check your .NET version:
dotnet --versionClone the repository:
git clone https://github.com/Padokazzz/FinTrack.git
cd FinTrackRestore dependencies:
dotnet restoreBuild the projects:
dotnet build src/FinTrack.Domain/FinTrack.Domain.csproj
dotnet build src/FinTrack.Application/FinTrack.Application.csproj
dotnet build src/FinTrack.Infrastructure/FinTrack.Infrastructure.csproj
dotnet build src/FinTrack.Api/FinTrack.Api.csproj
dotnet build tests/FinTrack.Tests/FinTrack.Tests.csprojRun the API:
dotnet run --project src/FinTrack.Api/FinTrack.Api.csprojOpen Swagger in your browser:
https://localhost:{PORT}/swagger
or:
http://localhost:{PORT}/swagger
The exact port is displayed in the terminal when the API starts.
The project can run with Docker using:
- API container
- PostgreSQL container
Start the application:
cp .env.example .env
docker compose up --buildThe .env file is ignored by Git and should contain your local Docker credentials and JWT secret. The repository includes .env.example with safe placeholder values.
Open Swagger:
http://localhost:8080/swagger
The Docker environment applies EF Core migrations automatically on startup through:
Database__ApplyMigrationsOnStartup=true
Stop containers:
docker compose downStop containers and remove volumes:
docker compose down -vRebuild only the API image:
docker compose build apiFor local development, create your local settings file from the example:
cp src/FinTrack.Api/appsettings.Development.example.json src/FinTrack.Api/appsettings.Development.jsonThen configure the connection string in:
src/FinTrack.Api/appsettings.Development.json
Example for PostgreSQL:
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=fintrack_db;Username=YOUR_DATABASE_USER;Password=YOUR_DATABASE_PASSWORD"
}
}JWT settings example:
{
"Jwt": {
"Issuer": "FinTrack.Api",
"Audience": "FinTrack.Client",
"Secret": "CHANGE_THIS_TO_A_LONG_SECURE_SECRET_KEY_WITH_AT_LEAST_32_CHARS",
"ExpirationMinutes": 60
}
}appsettings.Development.json is intentionally ignored by Git because it can contain local credentials. For production, do not store secrets directly in appsettings.json. Use environment variables or a secret manager.
Install the Entity Framework CLI if needed:
dotnet tool install --global dotnet-efCreate a migration:
dotnet ef migrations add InitialCreate \
--project src/FinTrack.Infrastructure \
--startup-project src/FinTrack.Api \
--output-dir Data/MigrationsApply migrations:
dotnet ef database update \
--project src/FinTrack.Infrastructure \
--startup-project src/FinTrack.ApiRun all tests:
dotnet testRun only the test project:
dotnet test tests/FinTrack.Tests/FinTrack.Tests.csprojTest coverage focus:
- Application services
- Validators
- Monthly summary calculations
- Transaction balance rules
- Authentication rules
Swagger is available when running the API in development mode:
/swagger
Swagger allows you to:
- Explore endpoints
- Test requests from the browser
- Authenticate using JWT
- Validate request and response formats
POST /api/auth/register
POST /api/auth/loginGET /api/accounts
GET /api/accounts/{id}
POST /api/accounts
PUT /api/accounts/{id}
DELETE /api/accounts/{id}GET /api/categories
GET /api/categories/{id}
POST /api/categories
PUT /api/categories/{id}
DELETE /api/categories/{id}GET /api/transactions
GET /api/transactions/{id}
POST /api/transactions
PUT /api/transactions/{id}
DELETE /api/transactions/{id}Transaction filters:
GET /api/transactions?month=6&year=2026&type=Expense&categoryId={categoryId}GET /api/summaries/monthly?month=6&year=2026POST /api/auth/register
Content-Type: application/json{
"name": "Jane Doe",
"email": "jane@example.com",
"password": "123456"
}POST /api/auth/login
Content-Type: application/json{
"email": "jane@example.com",
"password": "123456"
}Expected response:
{
"userId": "00000000-0000-0000-0000-000000000000",
"name": "Jane Doe",
"email": "jane@example.com",
"token": "jwt-token-here"
}Use the token in protected requests:
Authorization: Bearer jwt-token-herePOST /api/accounts
Authorization: Bearer jwt-token-here
Content-Type: application/json{
"name": "Main Checking Account",
"type": "Checking",
"initialBalance": 1000
}POST /api/categories
Authorization: Bearer jwt-token-here
Content-Type: application/json{
"name": "Salary",
"type": "Income"
}POST /api/transactions
Authorization: Bearer jwt-token-here
Content-Type: application/json{
"description": "June salary",
"amount": 5000,
"date": "2026-06-05T00:00:00Z",
"type": "Income",
"accountId": "account-guid-here",
"categoryId": "category-guid-here"
}{
"month": 6,
"year": 2026,
"totalIncome": 5000,
"totalExpense": 1800,
"finalBalance": 3200
}- Passwords must be stored as hashes, never as plain text.
- JWT tokens are required for financial endpoints.
UserIdmust come from the authenticated token, not from the request body.- Repository queries must filter financial data by authenticated user.
- Secrets should be stored in environment variables outside local development.
- Create solution structure
- Configure project references
- Add base NuGet packages
- Add domain entities
- Add application DTOs
- Add FluentValidation validators
- Configure Entity Framework Core
- Configure PostgreSQL
- Implement repositories
- Implement services/use cases
- Configure JWT authentication
- Add controllers
- Protect endpoints by authenticated user
- Add migrations
- Add unit tests
- Add Docker support
- Add GitHub Actions CI
Recommended commit style:
chore: create solution structure
feat: add domain entities
feat: add application dtos
feat: add request validators
chore: configure ef core
feat: add user registration
feat: add jwt login
feat: add account crud
feat: add category crud
feat: add transaction crud
feat: add monthly summary
test: add application unit tests
chore: add docker support
docs: update readme
Developed as a backend portfolio project focused on clean architecture, API design, authentication, persistence and testing with the .NET ecosystem.