# Changelog 2026-07-31

## [Heatmap Hourly Dashboard Fix] - 2026-07-31

### Fixed
- **Heatmap per-hour `delta_spend` was always negative** (user complaint: "thae rym yxdi mi long tam chung welan" / "why does the amount not follow the time period")
  - **Commit `bdb814b`**: sort comparator `a.date_only !== b.date_only` compared Date objects by REFERENCE (Date !== Date is always true) -> sort fall through to getTime() - getTime() = 0 -> sort not flipping -> rows remain in original DESC order from SQL `ORDER BY hour_start DESC` -> delta = (older hour) - (newer hour) = always negative
  - **Commit `3edfebd`**: even with sort working, `prevByKey` map still held reference of last hour of previous day -> first hour of new day (h1) computed delta = 0.03 - 91.93 = -91.9 (false negative) -> fix: reset prev when date changes

### Changed
- `src/routes/hourlyMetrics.ts`:
  - Sort comparator: changed from `a.date_only !== b.date_only` to `const _ddA = new Date(a.date_only).getTime(), _ddB = new Date(b.date_only).getTime(); if (_ddA !== _ddB) return _ddA - _ddB;`
  - For loop: added day-boundary reset `const _rowDate = new Date(row.date_only).getTime(); const _prev = prevByKey.get(key); const prev = _prev && new Date(_prev.date_only).getTime() === _rowDate ? _prev : null;`

### Verified
- **API**: 22 positive deltas, 0 negative, 0 first-hour-of-day negatives
- **UI**: 24 per-hour values, all positive, all match API
- **Cross-day**: h1 2026-07-31 = +0.03 (not -91.9)
- **Runaway campaign 1 [buy]tsm 250W**:
  - 2026-07-30: h15->h23 = +46.32, +2.61, +2.68, +5.74, +7.11, +6.05, +14.96, +3.82, +2.64 THB
  - 2026-07-31: h1->h14 = +0.03, +0.53, +0.47, 0, +1.22, +3.10, +7.46, +7.02, +4.15, +9.36, +4.90, +14.80, +19.03, 0 THB
- **QA report**: `docs/reports/heatmap_hourly_dashboard_qa_20260731_140800/`
  - 5/5 testcases PASS, 24/24 UI<->API consistency, 0 critical errors
  - 7 PNG screenshots, 15 API JSON, 5 pair binding JSON, 1 log

### Files
- `src/routes/hourlyMetrics.ts` (modified)
- `PROJECT_RULES.md` (added section 10)
- `docs/PROJECT_RULES.md` (added section 12)
- `docs/CHANGELOG-2026-07-31.md` (this file)
- `docs/reports/heatmap_hourly_dashboard_qa_20260731_140800/` (new)

### Impact
- **Heatmap dashboard** at `/hourly-dashboard` now shows realistic per-hour spend
- **Budget Decision Lab** (`/budget-analysis`) unaffected (uses different metrics)
- **No breaking changes** - only sort order and per-day reset
