A full-stack personal finance app that helps you record transactions, organize spending, and see exactly where your money goes — built with ASP.NET Core 8 and React.
A practical layered backend paired with a responsive frontend — built for clarity, not complexity.
Registration and login with JWT authentication, and BCrypt password hashing — plaintext passwords are never stored.
Create, view, edit, and delete personal income and expense records, each scoped to the owning user.
Search by term, filter by type/category/date range, and page through results with server-side sorting.
Eight seeded global categories: Food, Transport, Shopping, Bills, Entertainment, Health, Salary, and Other.
Dashboard aggregates for income, expenses, balance, category totals, monthly trends, and recent activity.
FluentValidation request rules, centralized exception handling, and DTOs that never expose persistence entities.
The core release is complete — every item below is implemented, working, and part of the current codebase.
| Backend | ASP.NET Core 8Entity Framework Core 8FluentValidationSwagger / OpenAPI |
| Frontend | ReactViteTailwind CSSReact RouterRecharts |
| Database | SQL Server |
| Auth & Security | JWTBCrypt |
A modular layered monolith. Controllers handle HTTP, services hold the rules, and Entity Framework Core manages persistence. No microservices, no CQRS, no ceremony.
Works on Windows, macOS, or Linux. You'll need the .NET 8 SDK, Node.js with npm, SQL Server (or a compatible instance), and Git.
Pull the project down and move into the project directory.
Restore packages, apply migrations, and start the API from backend/ExpenseTracker.Api.
Install dependencies and start the Vite dev server from frontend.
# 1. clone
git clone https://github.com/here-is-leo/expense-tracker.git
cd expense-tracker
# 2. backend
cd backend/ExpenseTracker.Api
dotnet restore
dotnet ef database update
dotnet run
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=ExpenseTrackerDb;Trusted_Connection=True;TrustServerCertificate=True"
},
"Jwt": {
"Key": "replace-with-a-long-development-secret",
"Issuer": "ExpenseTracker.Api",
"Audience": "ExpenseTracker.Client"
}
}
cd ../../frontend
npm install
npm run dev
# .env (if required)
VITE_API_BASE_URL=https://localhost:5001/api
Never commit production secrets — use environment variables, .NET user secrets, or a dedicated secrets manager.
Full endpoint documentation lives in docs/API.md. Swagger UI is available at /swagger in development.
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/auth/register | Register a user |
| POST | /api/auth/login | Authenticate and receive a JWT |
| GET | /api/transactions | List, filter, sort, and paginate transactions |
| GET | /api/transactions/{id} | Retrieve one owned transaction |
| POST | /api/transactions | Create a transaction |
| PUT | /api/transactions/{id} | Update an owned transaction |
| DELETE | /api/transactions/{id} | Delete an owned transaction |
| GET | /api/categories | List global categories |
| GET | /api/dashboard | Retrieve financial aggregates and recent activity |
JWT-based authentication for every protected API operation
BCrypt password hashing — plaintext passwords are never stored
Ownership checks on user-scoped resources to prevent IDOR vulnerabilities
404 responses for inaccessible resources, so existence is never revealed
Server-side validation with FluentValidation on every request
Centralized exception handling with consistent error responses
DTOs prevent persistence entities from being exposed directly
Fixed-precision decimal / numeric(18,2) values for monetary data
The core release is feature-complete. Everything below in the current stage is shipped; future stages are exploratory.

"Reliable software begins with clear boundaries and thoughtful decisions."
@here-is-leo on GitHub →یک اپلیکیشن کامل مدیریت مالی شخصی که به شما کمک میکند تراکنشها را ثبت کنید، هزینهها را سازماندهی کنید و دقیقاً ببینید پولتان کجا میرود — ساختهشده با ASP.NET Core 8 و React.
یک بکاند لایهبندیشدهٔ کاربردی همراه با رابطی واکنشگرا — ساختهشده برای شفافیت، نه پیچیدگی.
ثبتنام و ورود با احراز هویت JWT و هش گذرواژه با BCrypt — گذرواژهٔ خام هرگز ذخیره نمیشود.
ایجاد، مشاهده، ویرایش و حذف تراکنشهای درآمد و هزینه، هرکدام متعلق به کاربر مالک.
جستوجو با عبارت، فیلتر بر اساس نوع/دسته/بازه زمانی، و صفحهبندی با مرتبسازی سمت سرور.
هشت دستهبندی عمومی اولیه: خوراک، حملونقل، خرید، قبوض، سرگرمی، سلامت، حقوق و سایر.
محاسبات داشبورد برای درآمد، هزینه، موجودی، جمع دستهبندیها، روند ماهانه و فعالیتهای اخیر.
اعتبارسنجی با FluentValidation، مدیریت متمرکز خطاها، و DTOهایی که هرگز موجودیتهای داده را افشا نمیکنند.
نسخهٔ اصلی کامل است — هر مورد زیر پیادهسازی شده، کار میکند و بخشی از کدبیس فعلی است.
| بکاند | ASP.NET Core 8Entity Framework Core 8FluentValidationSwagger / OpenAPI |
| فرانتاند | ReactViteTailwind CSSReact RouterRecharts |
| پایگاه داده | SQL Server |
| احراز هویت و امنیت | JWTBCrypt |
یک مونولیت ماژولار و لایهبندیشده. کنترلرها مسئول HTTP، سرویسها محل قوانین، و Entity Framework Core مسئول ذخیرهسازی است. بدون میکروسرویس، بدون CQRS، بدون تشریفات اضافه.
روی ویندوز، macOS و لینوکس قابل اجراست. به .NET 8 SDK، Node.js همراه npm، SQL Server (یا نمونهای سازگار) و Git نیاز دارید.
پروژه را کلون کنید و وارد پوشهٔ آن شوید.
وابستگیها را نصب کنید، مایگریشنها را اعمال کنید و API را از backend/ExpenseTracker.Api اجرا کنید.
وابستگیها را نصب کرده و سرور توسعهٔ Vite را از پوشهٔ frontend اجرا کنید.
# ۱. کلون پروژه
git clone https://github.com/here-is-leo/expense-tracker.git
cd expense-tracker
# ۲. بکاند
cd backend/ExpenseTracker.Api
dotnet restore
dotnet ef database update
dotnet run
{
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=ExpenseTrackerDb;Trusted_Connection=True;TrustServerCertificate=True"
},
"Jwt": {
"Key": "replace-with-a-long-development-secret",
"Issuer": "ExpenseTracker.Api",
"Audience": "ExpenseTracker.Client"
}
}
cd ../../frontend
npm install
npm run dev
# .env (در صورت نیاز)
VITE_API_BASE_URL=https://localhost:5001/api
اسرار محیط عملیاتی را هرگز در مخزن ثبت نکنید — از متغیرهای محیطی، User Secrets یا سامانهٔ مدیریت اسرار استفاده کنید.
مستندات کامل endpointها در docs/API.md است. رابط Swagger در محیط توسعه از مسیر /swagger در دسترس است.
| متد | مسیر | کاربرد |
|---|---|---|
| POST | /api/auth/register | ثبتنام کاربر |
| POST | /api/auth/login | ورود و دریافت JWT |
| GET | /api/transactions | دریافت، فیلتر، مرتبسازی و صفحهبندی |
| GET | /api/transactions/{id} | دریافت یک تراکنش متعلق به کاربر |
| POST | /api/transactions | ایجاد تراکنش |
| PUT | /api/transactions/{id} | ویرایش تراکنش متعلق به کاربر |
| DELETE | /api/transactions/{id} | حذف تراکنش متعلق به کاربر |
| GET | /api/categories | دریافت دستهبندیهای عمومی |
| GET | /api/dashboard | دریافت محاسبات مالی و فعالیتهای اخیر |
احراز هویت مبتنی بر JWT برای هر عملیات محافظتشدهٔ API
هش گذرواژه با BCrypt — گذرواژهٔ خام هرگز ذخیره نمیشود
کنترل مالکیت منابع کاربر برای جلوگیری از آسیبپذیری IDOR
پاسخ 404 برای منابع غیرقابلدسترسی، بدون افشای وجود آنها
اعتبارسنجی سمت سرور با FluentValidation روی هر درخواست
مدیریت متمرکز استثناها با پاسخ خطای یکپارچه
DTOها از افشای مستقیم موجودیتهای پایگاه داده جلوگیری میکنند
مقادیر مالی با دقت ثابت decimal / numeric(18,2)
نسخهٔ اصلی کاملاً تکمیل شده است. همهٔ موارد مرحلهٔ فعلی تحویل داده شدهاند؛ مراحل بعدی در حال بررسی هستند.

«نرمافزار قابلاعتماد از مرزبندی روشن و تصمیمهای سنجیده آغاز میشود.»
@here-is-leo در گیتهاب ←