whisper-money/app/Http/Controllers
Víctor Falcón bb65bdc16e
feat(accounts): add loan amortization projections for loan accounts (#246)
## Summary

- Adds loan detail tracking (interest rate, term, start date, original
amount) to loan-type accounts, following the existing
`real_estate_details` pattern
- Implements `LoanAmortizationService` with standard amortization math
to automatically project month-to-month balance evolution
- Shows projected future balances as a dashed line on the account
balance chart, visually distinct from historical data
- Adds a scheduled command (`loans:generate-balances`) to auto-generate
monthly balance entries for loan accounts
- Includes 36 tests (10 unit for pure math, 26 feature for CRUD, API
projections, command, and authorization)

## Changes

### Backend
- **Migration**: `loan_details` table (UUID PK, unique `account_id` FK,
interest rate, term, start date, original amount)
- **LoanDetail model** + factory with `Account::loanDetail()` HasOne
relationship
- **LoanAmortizationService**: `calculateMonthlyPayment`,
`calculateRemainingBalance`, `generateProjection`, `projectFromBalance`,
`calculateRemainingMonths`, `getBalanceAtDate`
- **GenerateMonthlyLoanBalances** command: runs monthly on 1st, skips
existing entries
- **LoanDetailController**: PATCH endpoint for editing loan details from
show page
- **Settings\AccountController**: creates/updates `LoanDetail` on
store/update
- **DashboardAnalyticsController**: appends projected data points with
`projected: true` flag
- **Validation**: loan-specific rules in StoreAccountRequest and
UpdateAccountRequest

### Frontend
- **AccountForm**: loan fields (rate, term, start date, original amount)
shown when `type === 'loan'`
- **Create/Edit dialogs**: pass loan data fields in POST/PATCH payloads
- **Show page**: `LoanDetailsCard` component with edit/read modes,
computed monthly payment and remaining months
- **Balance chart**: new `ComposedChart` branch with dashed `Line`
overlay for projected data points
- **Types**: `LoanDetail` interface in `account.ts`
2026-03-26 15:06:09 +01:00
..
Api feat(accounts): add loan amortization projections for loan accounts (#246) 2026-03-26 15:06:09 +01:00
OpenBanking fix(banking): update external_account_id on reconnect and store IBAN (#220) 2026-03-12 10:28:23 +00:00
Settings feat(accounts): add loan amortization projections for loan accounts (#246) 2026-03-26 15:06:09 +01:00
Sync refactor: Simplify transaction endpoints architecture (#76) 2026-01-25 16:15:17 +01:00
AccountBalanceController.php feat: investment benefits — show gains/losses on investment accounts (#140) 2026-02-23 13:59:10 +01:00
AccountController.php feat(accounts): add loan amortization projections for loan accounts (#246) 2026-03-26 15:06:09 +01:00
BudgetController.php chore: upgrade Laravel 12 to 13 (#242) 2026-03-25 12:56:33 +00:00
CashflowController.php feat(cashflow): track transfer categories in trends (#236) 2026-03-18 14:02:47 +00:00
Controller.php Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
DashboardController.php refactor: extract AccountMetricsService to deduplicate balance computation logic (#147) 2026-02-24 09:07:42 +01:00
EncryptionController.php Remove unused controllers and routes (#11) 2025-12-04 08:48:17 +01:00
LoanDetailController.php feat(accounts): add loan amortization projections for loan accounts (#246) 2026-03-26 15:06:09 +01:00
OnboardingController.php feat: (Onboarding) add categorization intro screen with benefit cards (#201) 2026-03-05 11:47:12 +01:00
ReEvaluateTransactionRulesController.php feat(transactions): re-add select all matching filters to bulk actions bar (#169) 2026-03-01 10:27:43 +00:00
RealEstateDetailController.php feat(accounts): add real estate asset tracking (#241) 2026-03-24 10:21:32 +00:00
RobotsController.php User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
SitemapController.php SEO landing page 2025-11-25 11:33:11 +01:00
SubscriptionController.php fix(billing): create Stripe customer before redirecting to billing portal (#206) 2026-03-05 11:58:04 +00:00
TransactionController.php fix(categorizer): fetch uncategorized transactions from backend instead of IndexedDB (#165) 2026-02-28 16:30:54 +00:00
UserLeadController.php feat(waitlist): waiting list with referral system (#199) 2026-03-04 12:36:47 +01:00