Feature: Add budget tracking with period-based spending limits
- Budget model with Weekly/Monthly/Yearly periods - BudgetService for CRUD and spending calculations - New /Budgets page for managing budgets - Dashboard integration with progress bars - Support for category-specific or total spending budgets - Period boundaries calculated from budget start date 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
145
ARCHITECTURE.md
145
ARCHITECTURE.md
@@ -55,7 +55,7 @@ MoneyMap follows a clean, service-oriented architecture:
|
||||
│ SQL Server Database │
|
||||
│ Cards, Accounts, Transactions, Receipts, │
|
||||
│ ReceiptLineItems, ReceiptParseLogs, │
|
||||
│ CategoryMappings, Merchants │
|
||||
│ CategoryMappings, Merchants, Budgets │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
@@ -183,6 +183,29 @@ Pattern-based rules for auto-categorization with merchant linking.
|
||||
- `MerchantId` (int?) - Foreign key to Merchant (optional)
|
||||
- `Priority` (int) - Higher priority checked first (default 0)
|
||||
|
||||
### Budget (Models/Budget.cs)
|
||||
Represents a spending budget for a category or total spending.
|
||||
|
||||
**Properties:**
|
||||
- `Id` (int) - Primary key
|
||||
- `Category` (string?, 100) - Category name (null = total spending budget)
|
||||
- `Amount` (decimal) - Budget limit amount
|
||||
- `Period` (BudgetPeriod) - Weekly, Monthly, or Yearly
|
||||
- `StartDate` (DateTime) - When budget becomes effective (used for period boundaries)
|
||||
- `IsActive` (bool) - Whether budget is currently active
|
||||
- `Notes` (string?, 500) - Optional notes
|
||||
|
||||
**Computed Properties:**
|
||||
- `IsTotalBudget` - Returns true if Category is null
|
||||
- `DisplayName` - Returns Category or "Total Spending"
|
||||
|
||||
**Unique Index:** Category + Period (filtered WHERE IsActive = 1, prevents duplicate active budgets)
|
||||
|
||||
**BudgetPeriod Enum:**
|
||||
- `Weekly` (0) - 7-day periods from StartDate
|
||||
- `Monthly` (1) - Monthly periods based on StartDate day-of-month
|
||||
- `Yearly` (2) - Annual periods from StartDate anniversary
|
||||
|
||||
## Service Layer
|
||||
|
||||
### TransactionImporter (Pages/Upload.cshtml.cs)
|
||||
@@ -451,6 +474,48 @@ Pattern-based rules for auto-categorization with merchant linking.
|
||||
|
||||
**Location:** Services/MerchantService.cs
|
||||
|
||||
### BudgetService (Services/BudgetService.cs)
|
||||
**Interface:** `IBudgetService`
|
||||
|
||||
**Responsibility:** Budget management including CRUD operations and spending calculations.
|
||||
|
||||
**Key Methods:**
|
||||
- `GetAllBudgetsAsync(bool activeOnly = true)` - Get all budgets, optionally filtered to active only
|
||||
- `GetBudgetByIdAsync(int id)` - Get budget by ID
|
||||
- `CreateBudgetAsync(Budget budget)` - Create new budget with duplicate validation
|
||||
- `UpdateBudgetAsync(Budget budget)` - Update existing budget
|
||||
- `DeleteBudgetAsync(int id)` - Delete budget
|
||||
|
||||
- `GetAllBudgetStatusesAsync(DateTime? asOfDate = null)` - Get spending status for all active budgets
|
||||
- `GetBudgetStatusAsync(int budgetId, DateTime? asOfDate = null)` - Get spending status for specific budget
|
||||
|
||||
- `GetAvailableCategoriesAsync()` - Get list of categories for budget creation
|
||||
- `GetPeriodBoundaries(BudgetPeriod period, DateTime startDate, DateTime asOfDate)` - Calculate period start/end dates
|
||||
|
||||
**Period Boundary Logic:**
|
||||
- **Weekly:** 7-day periods starting from StartDate
|
||||
- **Monthly:** Periods run from StartDate's day-of-month (e.g., 15th to 14th)
|
||||
- **Yearly:** Annual periods from StartDate anniversary
|
||||
|
||||
**DTOs:**
|
||||
- `BudgetOperationResult` - CRUD operation result with success/message
|
||||
- `BudgetStatus` - Budget with calculated spending data:
|
||||
- `Budget` - The budget entity
|
||||
- `PeriodStart`, `PeriodEnd` - Current period boundaries
|
||||
- `Spent` - Total spending in period
|
||||
- `Remaining` - Budget amount minus spent
|
||||
- `PercentUsed` - Percentage of budget consumed
|
||||
- `IsOverBudget` - Whether spending exceeds budget
|
||||
- `StatusClass` - CSS class (success/warning/danger)
|
||||
|
||||
**Design Pattern:**
|
||||
- Follows service layer pattern with interface
|
||||
- Uses DTOs for complex return types
|
||||
- Calculates spending by querying transactions within period boundaries
|
||||
- Excludes transfers from spending calculations
|
||||
|
||||
**Location:** Services/BudgetService.cs
|
||||
|
||||
### TransactionStatisticsService (Services/TransactionStatisticsService.cs)
|
||||
**Interface:** `ITransactionStatisticsService`
|
||||
|
||||
@@ -913,6 +978,34 @@ EF Core DbContext managing all database entities.
|
||||
|
||||
**Location:** Pages/Merchants.cshtml.cs
|
||||
|
||||
### Budgets.cshtml / BudgetsModel
|
||||
**Route:** `/Budgets`
|
||||
|
||||
**Purpose:** Manage spending budgets and track budget status.
|
||||
|
||||
**Features:**
|
||||
- Create budgets for specific categories or total spending
|
||||
- Support for Weekly, Monthly, and Yearly periods
|
||||
- Real-time spending vs budget tracking with progress bars
|
||||
- Color-coded status (green/yellow/red based on % used)
|
||||
- Pause/resume budgets without deleting
|
||||
- Edit budget amounts and periods
|
||||
- View active and inactive budgets separately
|
||||
|
||||
**Budget Types:**
|
||||
- **Category Budget:** Track spending for a specific category (e.g., "Dining Out")
|
||||
- **Total Budget:** Track all spending combined (Category = null)
|
||||
|
||||
**Period Boundaries:**
|
||||
- Periods are calculated relative to the budget's StartDate
|
||||
- Monthly budgets run from the StartDate's day (e.g., if StartDate is Jan 15, periods run 15th to 14th)
|
||||
- Weekly budgets run in 7-day increments from StartDate
|
||||
- Yearly budgets run from the StartDate anniversary
|
||||
|
||||
**Dependencies:** `IBudgetService`
|
||||
|
||||
**Location:** Pages/Budgets.cshtml.cs
|
||||
|
||||
### Recategorize.cshtml / RecategorizeModel
|
||||
**Route:** `/Recategorize`
|
||||
|
||||
@@ -1111,6 +1204,18 @@ CreatedBy (nvarchar(max), NULL) -- "AI" or "User"
|
||||
CreatedAt (datetime2, NULL) -- Rule creation timestamp
|
||||
```
|
||||
|
||||
### Budgets Table
|
||||
```sql
|
||||
Id (int, PK)
|
||||
Category (nvarchar(100), NULL) -- NULL = total spending budget
|
||||
Amount (decimal(18,2), NOT NULL)
|
||||
Period (int, NOT NULL) -- 0=Weekly, 1=Monthly, 2=Yearly
|
||||
StartDate (datetime2, NOT NULL)
|
||||
IsActive (bit, NOT NULL)
|
||||
Notes (nvarchar(500), NULL)
|
||||
UNIQUE INDEX: (Category, Period) WHERE IsActive = 1
|
||||
```
|
||||
|
||||
## Key Workflows
|
||||
|
||||
### 1. Import Transactions from CSV
|
||||
@@ -1424,15 +1529,14 @@ var importer = new TransactionImporter(mockDb.Object, mockCardResolver.Object);
|
||||
|
||||
### Potential Features
|
||||
1. **Multi-user support**: Add authentication/authorization
|
||||
2. **Budget tracking**: Monthly budget limits per category
|
||||
3. **Recurring transactions**: Auto-detect and predict recurring expenses
|
||||
4. **Data export**: Export transactions to Excel/CSV
|
||||
5. **Charts/graphs**: Spending trends over time
|
||||
6. **Mobile app**: React Native or .NET MAUI
|
||||
7. **Bank API integration**: Direct import from bank APIs (Plaid, Yodlee)
|
||||
8. **Receipt search**: Full-text search on parsed line items
|
||||
9. **Split transactions**: Divide single transaction across categories
|
||||
10. **Tags**: Tag transactions with multiple labels
|
||||
2. **Recurring transactions**: Auto-detect and predict recurring expenses
|
||||
3. **Data export**: Export transactions to Excel/CSV
|
||||
4. **Charts/graphs**: Spending trends over time
|
||||
5. **Mobile app**: React Native or .NET MAUI
|
||||
6. **Bank API integration**: Direct import from bank APIs (Plaid, Yodlee)
|
||||
7. **Receipt search**: Full-text search on parsed line items
|
||||
8. **Split transactions**: Divide single transaction across categories
|
||||
9. **Tags**: Tag transactions with multiple labels
|
||||
|
||||
### Technical Debt
|
||||
1. Move inline service implementations to separate files (Upload.cshtml.cs is 333 lines)
|
||||
@@ -1498,10 +1602,27 @@ MoneyMap demonstrates a well-architected ASP.NET Core application with clear sep
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** 2025-10-12
|
||||
**Version:** 1.2
|
||||
**Last Updated:** 2025-12-11
|
||||
**Version:** 1.3
|
||||
**Framework:** ASP.NET Core 8.0 / EF Core 9.0
|
||||
|
||||
## Recent Changes (v1.3)
|
||||
|
||||
### Budget Tracking Feature
|
||||
- **Budget Model**: New `Budget` entity with support for Weekly, Monthly, and Yearly periods
|
||||
- **Category & Total Budgets**: Create budgets for specific categories or track total spending
|
||||
- **Period Boundaries**: Smart calculation of period start/end dates based on budget start date
|
||||
- **Budget Service**: Full CRUD operations plus spending calculations via `IBudgetService`
|
||||
- **Budgets Page**: New `/Budgets` page for managing budgets with progress bars
|
||||
- **Dashboard Integration**: Budget status displayed on dashboard with color-coded progress
|
||||
- **Pause/Resume**: Deactivate budgets without deleting them
|
||||
|
||||
### Technical Details
|
||||
- Added `Budgets` table with filtered unique index on (Category, Period) WHERE IsActive = 1
|
||||
- `BudgetPeriod` enum: Weekly (0), Monthly (1), Yearly (2)
|
||||
- Period boundary calculations handle edge cases (month boundaries, leap years)
|
||||
- Spending calculated by summing debits within period, excluding transfers
|
||||
|
||||
## Recent Changes (v1.2)
|
||||
|
||||
### Receipt Management Enhancements
|
||||
|
||||
Reference in New Issue
Block a user