diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 48d598a..06d8a68 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -27,14 +27,23 @@ MoneyMap follows a clean, service-oriented architecture: │ ┌────────────────┴────────────────────────────┐ │ Service Layer (Business Logic) │ -│ - TransactionImporter │ -│ - CardResolver │ -│ - TransactionCategorizer │ -│ - TransactionService (NEW) │ -│ - ReceiptMatchingService (NEW) │ -│ - DashboardService │ -│ - ReceiptManager │ -│ - OpenAIReceiptParser │ +│ Core Transaction Services: │ +│ - TransactionImporter │ +│ - CardResolver │ +│ - TransactionCategorizer │ +│ - TransactionService (NEW) │ +│ - TransactionStatisticsService (NEW) │ +│ Entity Management Services: │ +│ - AccountService (NEW) │ +│ - CardService (NEW) │ +│ - MerchantService (EXPANDED) │ +│ Receipt Services: │ +│ - ReceiptMatchingService (NEW) │ +│ - ReceiptManager │ +│ - AIReceiptParser │ +│ Reference & Dashboard: │ +│ - ReferenceDataService (NEW) │ +│ - DashboardService │ └────────────────┬────────────────────────────┘ │ ┌────────────────┴────────────────────────────┐ @@ -330,6 +339,180 @@ Pattern-based rules for auto-categorization with merchant linking. **Location:** Services/ReceiptMatchingService.cs +### AccountService (Services/AccountService.cs) +**Interface:** `IAccountService` + +**Responsibility:** Account management including retrieval, validation, and deletion. + +**Key Methods:** +- `GetAccountByIdAsync(int id, bool includeRelated = false)` + - Retrieves account by ID with optional related data (cards, transactions) + - Returns Account entity or null + +- `GetAllAccountsWithStatsAsync()` + - Gets all accounts with transaction counts + - Returns list of `AccountWithStats` DTOs + - Sorted by owner, institution, last4 + +- `GetAccountDetailsAsync(int id)` + - Gets comprehensive account details including linked cards and stats + - Returns `AccountDetails` DTO with cards and transaction counts + +- `CanDeleteAccountAsync(int id)` + - Validates if account can be deleted (no transactions) + - Returns `DeleteValidationResult` + +- `DeleteAccountAsync(int id)` + - Deletes account after validation + - Returns `DeleteResult` with success/failure message + +**DTOs:** +- `AccountWithStats` - Account with transaction count +- `AccountDetails` - Full account details with cards and statistics +- `DeleteValidationResult` - Validation result with reason if cannot delete +- `DeleteResult` - Operation result with success status and message + +**Design Pattern:** +- Consolidates account deletion validation logic from multiple PageModels +- Provides single source of truth for account operations +- Improves testability + +**Location:** Services/AccountService.cs + +### CardService (Services/CardService.cs) +**Interface:** `ICardService` + +**Responsibility:** Card management including retrieval, validation, and deletion. + +**Key Methods:** +- `GetCardByIdAsync(int id, bool includeRelated = false)` + - Retrieves card by ID with optional related data (account, transactions) + - Returns Card entity or null + +- `GetAllCardsWithStatsAsync()` + - Gets all cards with transaction counts + - Returns list of `CardWithStats` DTOs + - Sorted by owner, last4 + +- `CanDeleteCardAsync(int id)` + - Validates if card can be deleted (no transactions) + - Returns `DeleteValidationResult` + +- `DeleteCardAsync(int id)` + - Deletes card after validation + - Returns `DeleteResult` with success/failure message + +**DTOs:** +- `CardWithStats` - Card with transaction count + +**Design Pattern:** +- Consolidates card deletion validation logic from Cards and AccountDetails pages +- Mirrors AccountService for consistency +- Enables reusable card management operations + +**Location:** Services/CardService.cs + +### MerchantService (Services/MerchantService.cs) - EXPANDED +**Interface:** `IMerchantService` + +**Responsibility:** Merchant management including creation, retrieval, update, and deletion. + +**Existing Methods:** +- `FindByNameAsync(string name)` - Find merchant by exact name match +- `GetOrCreateAsync(string name)` - Get existing or create new merchant +- `GetOrCreateIdAsync(string? name)` - Get or create merchant and return ID + +**New Methods:** +- `GetMerchantByIdAsync(int id, bool includeRelated = false)` + - Retrieves merchant by ID with optional related data (transactions, category mappings) + +- `GetAllMerchantsWithStatsAsync()` + - Gets all merchants with transaction and mapping counts + - Returns list of `MerchantWithStats` DTOs + - Sorted alphabetically by name + +- `UpdateMerchantAsync(int id, string newName)` + - Updates merchant name with duplicate checking + - Returns `MerchantUpdateResult` + +- `DeleteMerchantAsync(int id)` + - Deletes merchant and reports unlinked transactions/mappings + - Returns `MerchantDeleteResult` with counts + +**DTOs:** +- `MerchantWithStats` - Merchant with transaction and mapping counts +- `MerchantUpdateResult` - Update operation result +- `MerchantDeleteResult` - Delete operation result with impact statistics + +**Design Pattern:** +- Expands existing service with full CRUD operations +- Used by EditTransaction for merchant creation +- Used by Merchants page for management UI + +**Location:** Services/MerchantService.cs + +### TransactionStatisticsService (Services/TransactionStatisticsService.cs) +**Interface:** `ITransactionStatisticsService` + +**Responsibility:** Calculate transaction statistics and aggregates. + +**Key Methods:** +- `CalculateStatsAsync(IQueryable query)` + - Calculates statistics for any filtered set of transactions + - Returns `TransactionStats` DTO with counts and totals + - Computes: total count, total debits, total credits, net amount + +- `GetCategorizationStatsAsync()` + - Gets categorization statistics for entire database + - Returns `CategorizationStats` with categorized/uncategorized counts + +- `GetCardStatsForAccountAsync(int accountId)` + - Gets transaction counts for all cards linked to an account + - Returns list of `CardStats` DTOs + +**DTOs:** +- `TransactionStats` - Aggregate statistics (count, debits, credits, net) +- `CategorizationStats` - Categorization summary +- `CardStats` - Card with transaction count + +**Design Pattern:** +- Consolidates statistics calculation from Transactions, Recategorize, and AccountDetails pages +- Enables consistent statistics across the application +- Improves performance by centralizing query logic + +**Location:** Services/TransactionStatisticsService.cs + +### ReferenceDataService (Services/ReferenceDataService.cs) +**Interface:** `IReferenceDataService` + +**Responsibility:** Provide reference/lookup data for dropdowns and filters. + +**Key Methods:** +- `GetAvailableCategoriesAsync()` + - Gets all distinct categories from transactions + - Returns sorted list of category names + - Excludes empty/whitespace categories + +- `GetAvailableMerchantsAsync()` + - Gets all merchants sorted by name + - Returns list of Merchant entities + +- `GetAvailableCardsAsync(bool includeAccount = true)` + - Gets all cards with optional account information + - Returns sorted list of Card entities + - Sorted by owner, last4 + +- `GetAvailableAccountsAsync()` + - Gets all accounts sorted by institution and last4 + - Returns list of Account entities + +**Design Pattern:** +- Centralizes repetitive reference data queries used across multiple pages +- Reduces code duplication in Transactions, EditTransaction, Upload pages +- Provides consistent sorting and filtering + +**Location:** Services/ReferenceDataService.cs + ### DashboardService (Pages/Index.cshtml.cs) **Interface:** `IDashboardService`