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

   ## Problem / Evidence
   
   The header stat "Triggered in 24h on page" (本页 24h 触发) on the alerts page 
compares `new Date(r.lastTriggered).getTime()` against the wall clock 
(`web/src/pages/ops/alerts.tsx`):
   
   ```ts
   const triggered24h = rules.filter(
     (r) => r.lastTriggered && new Date(r.lastTriggered).getTime() > dayAgo,
   ).length;
   ```
   
   `lastTriggered` is a UTC `LocalDateTime` serialized **without an offset 
suffix** (server: `NativeAlertProcessor` stamps 
`LocalDateTime.ofInstant(collectedAt, ZoneOffset.UTC)` and persists it into 
`last_triggered VARCHAR(64)`). The Last-Triggered column on the very same page 
deliberately parses this value as UTC via `formatUtcDateTime` — with a comment 
stating the convention — so the two displays of the same field disagree:
   
   - Browser in UTC+8 (e.g. Asia/Shanghai, the dashboard's primary audience): a 
rule that fired 23h ago UTC parses as 31h ago → **the stat undercounts**. The 
column shows "fired 23h ago" while the stat excludes the rule.
   - Browser in UTC−8: the same firing reads as 15h ago → the stat 
**overcounts** (a firing 31h ago UTC is counted).
   - Only a browser set to exactly UTC shows the right count.
   
   The same fixture renders both wrong and right numbers on screen 
simultaneously, so the defect is directly observable without any tooling.
   
   ## Root cause / Fix
   
   The stat predates the UTC-parsing convention introduced for the column and 
never adopted it.
   
   Minimal fix:
   
   - `web/src/utils/format.ts`: extract the parse rule into a new exported 
`parseAlertTimestamp()` — an offset-less string is UTC (append `Z`), an 
explicit offset is honored, unparseable values return `NaN`; 
`formatUtcDateTime` now routes through it so the two call sites cannot drift 
again.
   - `web/src/pages/ops/alerts.tsx`: the stat filters on 
`parseAlertTimestamp(r.lastTriggered) > dayAgo`.
   
   ## Priority / scoring
   
   - Impact 24/40: a headline ops statistic silently miscounts by the viewer's 
UTC offset, contradicting the adjacent column for the same data — misleads 
on-call triage.
   - Reach 14/20: the alerts page is the primary ops workflow; every visitor 
outside UTC is affected.
   - Reproducibility 18/20: fully deterministic under a fixed clock and TZ; 
verified that the old code renders `0` and the fixed code `1` for the fixture 
below under TZ=Asia/Shanghai.
   - Maintenance value 8/20: collapses the parse convention into one helper, 
preventing future drift.
   - **PRIORITY 64/100**, **FIX_CONFIDENCE 95/100**.
   
   ## Tests
   
   - `web/src/utils/format.test.ts`: four unit tests for `parseAlertTimestamp` 
(offset-less ⇒ UTC, explicit `Z`/±hh:mm honored, blank/invalid ⇒ NaN, `Date` 
passthrough).
   - `web/src/pages/ops/__tests__/AlertsPage.test.tsx`: page-level regression 
"counts the 24h-triggered stat against the UTC timestamp, not the browser zone" 
— pins `Date.now` at 2026-08-24T12:00:00Z and `TZ=Asia/Shanghai`, feeds a rule 
with `lastTriggered = '2026-08-23T13:00:00'` (23h old in UTC), asserts the stat 
renders **1**. Verified against the pre-fix code: it rendered **0** under the 
same conditions, so the test fails without the fix.
   - `npx vitest run src/pages/ops/__tests__/AlertsPage.test.tsx 
src/utils/format.test.ts` → 42 passed (42).
   - `npx tsc --noEmit -p tsconfig.app.json` → clean; `npx eslint` on touched 
files → no new findings (5 pre-existing warnings in alerts.tsx, present on the 
clean tree).
   
   ## Risk
   
   Low. `formatUtcDateTime` behavior is unchanged (its existing tests, 
including explicit-offset and invalid-input cases, pass); the only behavior 
change is the stat's parse convention, which now matches the column and the 
system-alerts page.
   


-- 
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