## Summary - Replace `subMonths()` with `subMonthsNoOverflow()` across controllers, commands, and tests to prevent date overflow on months with 31 days - On Jan 31, `subMonths(2)` overflows: Nov 31 doesn't exist → Carbon rolls forward to Dec 1, producing wrong date ranges and off-by-one month counts ## Root cause Carbon's `subMonths()` allows day overflow. When the target month has fewer days than the source date, it rolls into the next month. For example: - `2026-01-31 subMonths(2)` → Nov 31 → **2025-12-01** (expected Nov 30) - `2026-01-31 subMonths(11)` → Feb 31 → **2025-03-03** (expected Feb 28) `subMonthsNoOverflow()` clamps to the last valid day of the target month instead. ## Files changed - `app/Http/Controllers/Api/CashflowAnalyticsController.php` — cashflow trend start date calculation - `app/Console/Commands/ResetDemoAccountCommand.php` — balance history date generation (was causing duplicate `balance_date` entries) - `tests/Feature/AccountControllerTest.php` — balance evolution `from` param - `tests/Feature/CashflowAnalyticsTest.php` — transaction date generation in loop - `tests/Feature/DashboardAnalyticsTest.php` — net worth evolution `from` param ## Test plan - [x] `account balance evolution returns data` — expects 3 months, was getting 2 - [x] `cashflow trend returns monthly data` — expects 3 months, was getting 2 - [x] `cashflow trend defaults to 12 months` — expects 12 months, was getting 11 - [x] `net worth evolution returns monthly data points` — expects 3 months, was getting 2 - [x] `demo:reset creates demo user` — was throwing UniqueConstraintViolation on duplicate balance dates |
||
|---|---|---|
| .. | ||
| Browser | ||
| Feature | ||
| Unit | ||
| Pest.php | ||
| TestCase.php | ||