A personal finance projection and tracking application that lets you define recurring income and expenses, manage one-time transactions, and project future account balances. Supports multiple deployment modes: web application or full-stack development with .NET Aspire orchestration.
- π° Savings Projection β Project future account balances based on recurrent and fixed transactions
- π Recurrent Items β Manage recurring income and expenses with parent-child relationships
- π Fixed Items β Track one-time transactions with category filtering
- π History β View materialized transactions and compare actuals vs. projections
- π Reports β Category-level spending summaries grouped by month or year
- π¨ Theme Support β Light and dark themes
- π₯οΈ Multiple Deployment Options β Web app or development with Aspire
| Goal | Command |
|---|---|
| Full-stack development | cd src/Savings.AppHost && dotnet run |
| Run API only | cd src/Savings.API && dotnet run |
| Run SPA only | cd src/Savings.SPA && dotnet run |
| Debug API in VS Code | Press F5 β "C#: Savings.API Debug" |
| Debug SPA in VS Code | Press F5 β "C#: Savings.SPA Debug" |
| Layer | Technology |
|---|---|
| Frontend | Blazor WebAssembly, Radzen Blazor |
| Backend | ASP.NET Core, Entity Framework Core |
| Database | SQLite |
| Orchestration | .NET Aspire 9.0.0 |
- .NET SDK 10
Recommended for full-stack development
The application includes .NET Aspire 9.0.0 orchestration providing:
- Unified orchestration of API and SPA
- Built-in service discovery
- Observability with OpenTelemetry
- Health checks and resilience
- Dashboard for monitoring all services
Run:
cd src/Savings.AppHost
dotnet runServices started:
- Savings.API β ASP.NET Core Web API (dynamic port)
- Savings.SPA β Blazor WebAssembly (dynamic port)
- Aspire Dashboard β available at the URL shown in terminal output
Recommended for debugging individual components
Pre-configured launch configurations in .vscode/launch.json:
| Configuration | Description |
|---|---|
C#: Savings.API Debug |
Debug backend API with .NET debugger |
C#: Savings.SPA Debug |
Debug Blazor frontend with .NET debugger |
How to use:
- Open Run and Debug (Ctrl+Shift+D)
- Select configuration from dropdown
- Press F5
Ports: API runs on
https://localhost:7563, SPA runs onhttps://localhost:7026
Recommended for production hosting
# API
cd src/Savings.API
dotnet publish -c Release -o ./publish
# SPA
cd src/Savings.SPA
dotnet publish -c Release -o ./publish| Component | Target |
|---|---|
| API | IIS, Azure App Service, Linux/Kestrel, Containers |
| SPA | Azure Static Web Apps, any static host, or served by API |
Configuration: Update
appsettings.Production.jsonfor both API and SPA with production URLs and settings.
The application supports two authentication modes:
| Mode | Use Case |
|---|---|
| API Key | Simple shared-secret authentication |
| Azure AD | Enterprise identity with OAuth 2.0 / JWT |
Add the following to both Savings.API/appsettings.json and Savings.SPA/appsettings.json:
{
"AuthenticationToUse": "ApiKey",
"ApiKeys": "keyToUse"
}Configure two app registrations in Azure AD β one for the API (exposing a scope SavingProjection.All) and one for the SPA (with API permission for that scope).
API (Savings.API/appsettings.json):
{
"AuthenticationToUse": "AzureAD",
"IdentityProvider": {
"Authority": "https://login.microsoftonline.com/{tenantID}/",
"Audience": "api://{apiClientID}"
}
}SPA (Savings.SPA/appsettings.json):
{
"AuthenticationToUse": "AzureAD",
"AzureAd": {
"Authority": "https://login.microsoftonline.com/{tenantID}/",
"ClientId": "{spaClientID}",
"ValidateAuthority": true,
"DefaultScope": "api://{apiClientID}/SavingProjection.All"
}
}Project your future account balances based on recurring and fixed transactions:











