unbridled-41 opened a new pull request, #4175:
URL: https://github.com/apache/rocketmq-dashboard/pull/4175

   Fixes #4174.
   
   ## Problem / Evidence
   
   On `/ops/alerts` (and `/ops/business-alerts`) the **最近触发时间** column renders 
`lastTriggered` with `formatDateTime`, which parses offset-less ISO strings as 
**browser-local** time. The backend stamps this value as UTC without a suffix:
   
   - `NativeAlertProcessor.java:143` — `LocalDateTime eventTime = 
LocalDateTime.ofInstant(collectedAt, ZoneOffset.UTC);`
   - `NativeAlertProcessor.java:165` → `markRuleTriggered(rule.getId(), 
eventTime.toString())` → `2026-08-23T23:30:00` in 
`rmq_alert_rule.last_triggered` (`NativeAlertEvaluationService.java:92` same).
   
   So a rule that fired at 23:30 UTC displays "23:30" in every timezone; a 
UTC+8 browser shows a trigger time up to 8 hours in the future. The header 
counter `近24小时触发` (`alerts.tsx:406-408`, `new Date(r.lastTriggered).getTime() > 
dayAgo`) mixes the same naive parse with an epoch `dayAgo`, shifting the 24h 
window.
   
   The sibling system alerts page already established the correct contract for 
these offset-less UTC values: `systemAlerts.tsx` renders `alert.time` / 
`alert.acknowledgedAt` via `formatUtcDateTime`, whose doc comment states the 
exact failure mode ("Alert APIs serialize UTC LocalDateTime values without an 
offset, so normal Date parsing would incorrectly treat them as browser-local 
timestamps").
   
   ## Root cause / Fix
   
   `alerts.tsx` used the local-time formatter for an offset-less UTC timestamp. 
Switch the column to `formatUtcDateTime` (one-line change plus comment). The 
"24h triggered" filter already compares against `Date.now()`; once the value is 
interpreted as UTC it is consistent with epoch math, and existing null-sort 
semantics are untouched.
   
   ## Priority & scoring
   
   PRIORITY = 84 (影响 34: wrong wall-clock time on every non-UTC browser on a 
core ops page + skewed 24h counter; 波及范围 16: both alert domains, every viewer 
east of UTC; 可复现性 20: any fired rule renders wrong in a non-UTC browser; 维护价值 
14: aligns the page with the existing documented UTC contract). FIX_CONFIDENCE 
= 92 (single formatter swap with in-repo precedent and TZ-independent tests).
   
   ## Tests
   
   Red (before fix, `fix/alerts-last-triggered-utc` @ abef8546^, branch 
`rocketmq-studio` @ 0a596661):
   
   ```
   npx vitest run src/pages/ops/__tests__/AlertsPage.test.tsx
    ❯ src/pages/ops/__tests__/AlertsPage.test.tsx (24 tests | 2 failed)
      × formats the last triggered timestamp instead of rendering the raw ISO 
value
      × interprets the last triggered timestamp as UTC, not the browser zone
   ```
   
   Green (after fix):
   
   ```
   npx vitest run src/pages/ops/__tests__/AlertsPage.test.tsx
    Test Files  1 passed (1)
         Tests  24 passed (24)
   ```
   
   The existing "formats the last triggered timestamp" test asserted 
`formatDateTime(...)` (the local-time renderer) — i.e. it pinned the buggy 
behavior; it now expects `formatUtcDateTime(...)`. The new second test uses 
`2026-08-23T23:30:00`, where the local-time parse and the UTC parse differ by 
more than a date boundary in the reference TZ.
   
   Full web suite (`npx vitest run`): **945 tests, 944 passed, 1 failed** — 
`ConsumerPage > shows group health diagnostics from subscriptions, progress and 
clients` (unrelated file). Verified flaky-under-load both ways: pristine 
`rocketmq-studio` isolated run passes, isolated run with this change applied 
also passes (31 tests file-level, target test green).
   
   `tsc --noEmit` clean; `eslint` on both changed files: 0 errors (5 warnings, 
all pre-existing at the same positions); `npm run build` ✓ (8.25s).
   
   ## Risk
   
   Low. Display-only change on one column; no API/payload change. In a 
UTC-configured browser the rendered string additionally gains a timezone suffix 
(e.g. ` UTC`), consistent with the system alerts page. The `localeCompare` 
sorter and null handling are unchanged.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to