feat(dashboard): peak-time timestamps on daily extremes#166
Merged
Conversation
Each daily extreme (wind peak, rain rate peak, temperature/humidity/ barometer hi & lo) now carries an ``at`` ISO-8601 timestamp marking when today's high or low was first reached. The dashboard renders the time underneath the extreme value so a user can tell whether "Peak 38 mph" happened at 3 AM during a storm or five minutes ago. * ``get_daily_extremes`` adds ``at`` to each returned dict via small follow-up ``MIN(timestamp)`` queries against the same column = value the aggregate returned (tied extrema resolve to the earliest). * Each gauge accepts optional ``highAt``/``lowAt``/``peakAt`` props; desktop tiles render ``H 2:45 PM · L 11:30 PM`` (or "at HH:MM AM/PM" for single-extreme tiles). Mobile ``CompactCard`` paths unchanged. * Solar/UV has no daily extreme today; out of scope. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
cnighswonger
approved these changes
May 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
atISO-8601 UTC timestamp; the dashboard renders the time underneath the value so a user can tell whether "Peak 38 mph" happened at 3 AM in a storm or five minutes ago.CompactCardrendering deliberately unchanged — secondary line already shows H/L values.Implementation
backend/app/services/daily_extremes.py: keep the single aggregate query for the 12 extremum values; add oneMIN(timestamp)follow-up per non-null extreme, filteredcolumn == raw_value AND timestamp >= midnight_utc. Earliest occurrence wins for ties._val()now emits{"value", "unit", "at"}; naive SQLite UTC datetimes are re-stamped to UTC and serialised with aZsuffix sonew Date(iso)on the frontend parses correctly.frontend/src/api/types.ts: newExtremeReadingtype ({ value, unit, at: string | null });DailyExtremesfields swap fromValueWithUnit | nulltoExtremeReading | null.TileRendererplumbshighAt/lowAt/peakAt/peakRateAtinto each gauge. Each gauge calls the existingformatTimestamphelper to render either "at HH:MM AM/PM" (wind peak, rain peak) or "H 2:45 PM · L 11:30 PM" (Temp / Humidity / Barometer).Review
_atscans (timestamp index alone bounds them to today's ~8.6K rows, ~12 scans per request), and tests cover tied maxima but not tied minima symmetrically.Test plan
cd backend && python -m pytest ../tests/backend/ -q— 426 pass (was 421; +5 from newtest_daily_extremes.py)cd frontend && npx tsc --noEmit— cleancd frontend && npm run build— cleanpy_compileon changed Python files — clean🤖 Generated with Claude Code