2026-03-01 21:19:34 +00:00
Fix
2026-03-07 16:19:24 +00:00
2026-03-06 11:05:01 +00:00
2026-03-06 11:05:01 +00:00
2026-03-07 15:28:17 +00:00
2026-03-01 18:17:42 +00:00
Fix
2026-03-07 11:46:19 +00:00
2026-03-06 11:05:01 +00:00

💰 Budgeteer

Build and Test Docker Publish

A personal finance dashboard built with Blazor Server (.NET 10).

Status: beta — see the in-app badge.

Features

  • Multi-account support — current accounts, savings, credit cards, each with its own currency and colour
  • Transaction tracking — income & expenses with date, category, and account assignment
  • Recurring transactions — daily, weekly, monthly, or yearly recurrence with automatic materialisation up to one year ahead
  • Dashboard — balance trend chart (Chart.js), recent & upcoming transaction lists, account filter toggles, inline balance editing, and configurable time window
  • Reports — doughnut charts for expenses and income by category, monthly income vs expenses bar chart, and a category summary table with filterable date range and account selection
  • Categories — emoji-icon categories with sensible defaults and full CRUD
  • Transactions table — sortable columns, search, pagination, per-account filtering, time-window presets, bulk selection & delete, and responsive column hiding on mobile
  • Authentication — ASP.NET Identity with registration, login, password change, account deletion, and 5-attempt lockout
  • SSO providers — optional Google, Microsoft, and GitHub sign-in (configured via appsettings.json)
  • Settings — change password, reset all data (with confirmation), delete account
  • Toast notifications — inline validation feedback via a toast system
  • Help & About pages — in-app guides, tips, and project info
  • Responsive UI — Bootstrap 5, mobile-friendly layout with collapsible sidebar, responsive table columns, and scoped CSS
  • CI/CD — GitHub Actions for build/test and Docker Hub publishing
  • Docker — multi-stage Dockerfile with volume-mounted SQLite, OCI image labels, and automatic security patching

Tech Stack

Layer Technology
Framework .NET 10 / Blazor Server (InteractiveServer)
Database SQLite via EF Core
Auth ASP.NET Core Identity + optional Google / Microsoft / GitHub SSO
Charts Chart.js (CDN) with JS interop
CSS Bootstrap 5, scoped CSS
Tests xUnit
CI/CD GitHub Actions
Container Docker (multi-stage build)

Getting Started

Prerequisites

Run Locally

cd BudgetApp
dotnet run

The app will be available at https://localhost:5001 (or the port shown in the console). A budgetapp.db SQLite file is created automatically on first run.

Run Tests

dotnet test

Run with Docker

# Build
docker build -t budgeteer .

# Run (persists database in a named volume)
docker run -d -p 8080:8080 -v budgeteer-data:/app/data --name budgeteer budgeteer

Note: The SQLite database is stored at /app/data/budgetapp.db inside the container. Always mount a volume to /app/data so your data survives image updates and container replacements.

The app will be available at http://localhost:8080.

Project Structure

BudgetApp/
├── Components/
│   ├── Layout/
│   │   ├── MainLayout.razor
│   │   ├── MainLayout.razor.css
│   │   ├── AuthLayout.razor
│   │   ├── AuthLayout.razor.css
│   │   ├── NavMenu.razor
│   │   ├── NavMenu.razor.cs
│   │   └── NavMenu.razor.css
│   ├── Pages/
│   │   ├── Home.razor
│   │   ├── Home.razor.cs
│   │   ├── Home.razor.css
│   │   ├── Accounts.razor
│   │   ├── Accounts.razor.cs
│   │   ├── Transactions.razor
│   │   ├── Transactions.razor.cs
│   │   ├── Transactions.razor.css
│   │   ├── Categories.razor
│   │   ├── Categories.razor.cs
│   │   ├── Salary.razor
│   │   ├── Salary.razor.cs
│   │   ├── Salary.razor.css
│   │   ├── Reports.razor
│   │   ├── Reports.razor.cs
│   │   ├── About.razor
│   │   ├── About.razor.cs
│   │   ├── Settings.razor
│   │   ├── Settings.razor.cs
│   │   ├── Login.razor
│   │   ├── Login.razor.cs
│   │   ├── Register.razor
│   │   ├── Register.razor.cs
│   │   ├── Logout.razor
│   │   ├── Logout.razor.cs
│   │   ├── Help.razor
│   │   ├── NotFound.razor
│   │   ├── Error.razor
│   ├── ToastContainer.razor
│   ├── ToastContainer.razor.cs
│   ├── ToastContainer.razor.css
│   ├── ToastValidator.razor
│   ├── ToastValidator.razor.cs
│   └── _Imports.razor
├── Services/
│   ├── DashboardService.cs
│   ├── ToastService.cs
│   ├── AppState.cs
│   ├── Models/
│   │   ├── ChartData.cs
│   │   ├── ChartDataset.cs
│   │   └── DashboardData.cs
├── Program.cs
├── wwwroot/
│   ├── app.css
│   └── js/
│       └── chart-interop.js
├── appsettings.json
├── appsettings.Development.json
├── Dockerfile
├── .dockerignore
├── README.md
└── certs/
    └── .gitkeep

BudgetApp.Data/
├── Entities/
│   ├── Account.cs
│   ├── ApplicationUser.cs
│   ├── Category.cs
│   ├── RecurrenceType.cs
│   ├── Salary.cs
│   ├── Transaction.cs
│   ├── TransactionType.cs
├── Interfaces/
│   ├── IAccountRepository.cs
│   ├── ICategoryRepository.cs
│   ├── ISalaryRepository.cs
│   ├── ITransactionRepository.cs
├── Repositories/
│   ├── AccountRepository.cs
│   ├── CategoryRepository.cs
│   ├── SalaryRepository.cs
│   └── TransactionRepository.cs
├── ApplicationDbContext.cs
├── Migrations/
│   ├── AddCurrencyCodeAndCategoryIcon.cs
│   ├── AddCurrencyCodeAndCategoryIcon.Designer.cs
│   ├── AddIsDefaultToCategory.cs
│   ├── AddIsDefaultToCategory.Designer.cs
│   ├── AddIsPaidToTransaction.cs
│   ├── AddIsPaidToTransaction.Designer.cs
│   ├── AddRecurringTransactions.cs
│   ├── AddRecurringTransactions.Designer.cs
│   ├── AddSalary.cs
│   ├── AddSalary.Designer.cs
│   ├── InitialCreate.cs
│   ├── InitialCreate.Designer.cs
│   └── ApplicationDbContextModelSnapshot.cs

BudgetApp.Tests/
├── Helpers/
│   └── TestDbContextFactory.cs
├── Models/
│   └── AccountModelTests.cs
├── Services/
│   ├── AccountServiceTests.cs
│   ├── CategoryServiceTests.cs
│   ├── DashboardServiceTests.cs
│   └── TransactionServiceTests.cs

Configuration

Default connection string in appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=budgetapp.db"
  }
}

Override at runtime via environment variable:

export ConnectionStrings__DefaultConnection="Data Source=/path/to/budgeteer.db"

SSO Providers (optional)

Add client credentials to appsettings.json (or via environment / user-secrets). Each provider is only registered when both ClientId and ClientSecret are non-empty.

{
  "Authentication": {
    "Google": {
      "ClientId": "",
      "ClientSecret": ""
    },
    "Microsoft": {
      "ClientId": "",
      "ClientSecret": ""
    },
    "GitHub": {
      "ClientId": "",
      "ClientSecret": ""
    }
  }
}

Licence

This project is provided as-is for personal use.

Using Custom SSL Certificates

To enable HTTPS with custom SSL certificates in your Blazor application, follow these steps:

  1. Prepare PEM Files Place your certificate and private key files in PEM format in a directory accessible by your app. Example paths:

    • /app/data/certs/cert.pem
    • /app/data/certs/key.pem
  2. Configure Certificate Paths The application will look for certificate files in the following order:

    • Environment variables: PEM_CERT_FILE and PEM_KEY_FILE
    • Configuration values: PemCertFile and PemKeyFile in appsettings.json
    • Default: /app/data/certs/cert.pem and /app/data/certs/key.pem

    You can set environment variables before running the app:

    export PEM_CERT_FILE=/path/to/cert.pem
    export PEM_KEY_FILE=/path/to/key.pem
    

    Or add to your appsettings.json:

    {
      "PemCertFile": "/path/to/cert.pem",
      "PemKeyFile": "/path/to/key.pem"
    }
    
  3. Fallback Behavior If the certificate files are not found, the app will use the default development certificate.

  4. No Code Changes Needed The certificate loading logic is already implemented in Program.cs. Simply provide the files and configuration as described above.


Note:

  • Certificates must be in PEM format (.pem).
  • Ensure file permissions allow the app to read the certificate and key files.
  • For production, use certificates issued by a trusted Certificate Authority.
S
Description
A simple budgeting and forecasting app built on Blazor (SSR) and Entity Framework
Readme
1 MiB
0 Stars 1 Watchers 0 Forks
Languages
C# 58.1%
HTML 31.4%
CSS 6%
JavaScript 3.9%
Dockerfile 0.6%