Skip to content

fix: improve performance for history charts - #169

Merged
erikarenhill merged 3 commits into
masterfrom
feat/history-perf-and-dev-backfill
Apr 21, 2026
Merged

erikarenhill merged 3 commits into
masterfrom
feat/history-perf-and-dev-backfill

Conversation

@erikarenhill

Copy link
Copy Markdown
Collaborator

No description provided.

erikarenhill and others added 2 commits April 21, 2026 15:34
- api: memoize past-day energy totals on the Server; only today is
  recomputed per request. Past days are immutable once the day ends.
- state: new DailyEnergy() integrates grid/pv/bat/load via a SQL LAG()
  window — one row returned per day instead of shipping ~17k hot-tier
  samples to Go. Weekly/monthly dashboards go from seconds to tens of ms.
- state: BulkRecordHistory() wraps many inserts in one transaction;
  CountNonSyntheticHistory() counts rows missing the backfill JSON
  marker — the safety gate for the dev seeder.
- cli: -backfill N / -backfill-step / -backfill-seed / -backfill-force
  on the main forty-two-watts binary. Seeds N days of diurnal synthetic
  history into state.db then exits. Refuses if the DB already holds
  non-synthetic rows (production-safety gate).
- devtools: reusable generator with per-day weather + household profiles
  keyed on date^seed, AR(1) coloured noise on PV/load, rare appliance
  and cloud-shadow events. Stamps every row with {"source":"backfill"}
  so the safety gate can recognise its own output.
- skill: .claude/skills/dev-backfill documents invocation + the
  safety-gate semantics for future sessions.
- .gitignore: dev-data/ playground + per-user settings.local.json.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ellow toggle

- ftw-energy-flow: migrate from the 5-box hero to the planet/sun layout
  (HOUSE at centre, 45° corners with clustering). Dynamic SVG height
  grows with the largest cluster, desktop defaults bumped ~20% so the
  hero reads as the focal point on large screens.
- theme.css: new --fg-label token (dark: oklch(0.86); light: mirrors
  --fg-dim). Hero bubble labels pulled up to the same brightness so the
  gray "SOLAR / BATTERY / GRID / EV CHARGER" text stops feeling dim.
- next.css: every .card-label (summary, fuse, history, energy, control)
  adopts --fg-label. Desktop (≥901 px) bumps label size 10 → 12 px.
  history-toggle Week/Month pill — active state now --amber on --ink
  (our yellow); deselected --fg-label so inactive text matches the
  other labels instead of being dimmer.
- next-app.js, index.html: wiring / markup updates that accompany the
  hero redesign and the per-EV planet popups (daily kWh stats cards).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the /next dashboard’s perceived performance and UX by replacing heavy history-chart rendering with lightweight daily “history cards”, and by pushing daily energy aggregation into SQLite with caching and dev tooling to backfill data.

Changes:

  • Add /api/energy/daily backed by SQL-side integration (Store.DailyEnergy) plus per-day server caching.
  • Update /next UI to render daily history cards and refactor the hero energy-flow into a generic “planets” model (including EV modal opened from the hero).
  • Add a dev-only -backfill CLI path to seed synthetic history into state.db for local UI/perf work.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
web/next.css Adds layout/typography updates and styling for new history cards + fuse layout.
web/next-app.js Builds hero “planets”, moves EV modal trigger to hero, and adds history-cards fetching/rendering.
web/index.html Reworks the /next card layout (history cards + fuse row; removes SoC/EV tiles).
web/components/theme.css Introduces --fg-label and brightens hero label/sub text tokens.
web/components/ftw-energy-flow.js Refactors hero diagram to accept a planet list, adds dynamic sizing + clickable planets.
go/internal/state/store.go Adds bulk insert for backfill + SQL-integrated daily energy aggregation + safety-gate query.
go/internal/devtools/backfill.go Adds synthetic history backfill utility (flag-invoked).
go/internal/api/api.go Adds /api/energy/daily endpoint and a process-lifetime cache for past days.
go/cmd/forty-two-watts/main.go Wires -backfill* flags to run the dev backfill and exit.
.gitignore Ignores dev-data/ and local Claude settings file.
.claude/skills/dev-backfill/SKILL.md Documents the new dev backfill workflow and safety gate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread go/internal/api/api.go Outdated
Comment thread web/next-app.js Outdated
Comment thread web/next-app.js Outdated
Comment thread web/next-app.js Outdated
Comment thread web/index.html Outdated
Comment on lines +135 to +139
<div class="history-toggle" role="tablist">
<button data-range="week" class="active" role="tab">Week</button>
<button data-range="month" role="tab">Month</button>
</div>
</div>

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The history range toggle uses role="tablist"/role="tab" but doesn’t implement required tab semantics (aria-selected, roving tabindex, arrow-key navigation, associated tabpanels). This is misleading for assistive tech. Either implement full tabs behavior or simplify to regular buttons (e.g., remove the tab roles and use aria-pressed / visually-active state).

Copilot uses AI. Check for mistakes.
Comment thread web/components/ftw-energy-flow.js Outdated
return `
<div class="title">Energy balance</div>
<svg viewBox="${P.vbX} 0 ${P.vbW} ${H}" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
<svg viewBox="${P.vbX} 0 ${P.vbW} ${P.H}" preserveAspectRatio="xMidYMid meet" aria-hidden="true">

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SVG is marked aria-hidden="true" while containing keyboard-focusable, clickable planets (tabindex=0 + keydown handler). Interactive elements inside an aria-hidden subtree are inaccessible/invalid for assistive tech. Consider removing aria-hidden on the SVG (or moving interactivity outside), and add appropriate roles/labels (e.g., role="button" + aria-label) for clickable planets.

Suggested change
<svg viewBox="${P.vbX} 0 ${P.vbW} ${P.H}" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
<svg viewBox="${P.vbX} 0 ${P.vbW} ${P.H}" preserveAspectRatio="xMidYMid meet">

Copilot uses AI. Check for mistakes.
Comment thread go/internal/devtools/backfill.go Outdated
Comment thread go/internal/state/store.go Outdated
Master has since landed the history-cards feature set (per-metric web
components in ftw-history-card.js, ftw-bar-chart.js) and the
/api/energy/daily endpoint with proper error handling and tier-deduped
LoadHistory — superseding most of this branch's web/api changes.

Resolution: take master's versions for the five conflicting UI/api files
(ftw-energy-flow.js, index.html, next-app.js, next.css, api.go). The PR
retains its unique contribution — the dev-only state.db backfill tool
plus the BulkRecordHistory / CountNonSyntheticHistory helpers it needs.

Also drops the now-orphaned state.DailyEnergy / state.DayEnergy (master's
handleEnergyDaily uses LoadHistory, which already dedupes tiers) and
fixes the backfill marker "round-trip" sanity check in
devtools/backfill.go to actually Marshal after Unmarshal and compare
(addressing Copilot review comment #7 on PR #169).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@erikarenhill
erikarenhill merged commit 1bea0a5 into master Apr 21, 2026
1 check passed
@erikarenhill
erikarenhill deleted the feat/history-perf-and-dev-backfill branch April 21, 2026 15:26
erikarenhill added a commit that referenced this pull request Apr 22, 2026
…merge

PR #169 (feat/history-perf-and-dev-backfill) described "weekly/monthly
dashboards go from seconds to tens of ms" but the merge commit
02146c9 "Merge master into feat/history-perf-and-dev-backfill" explicitly
dropped state.DailyEnergy / DayEnergy as "now-orphaned", leaving the
naïve LoadHistory-based handler on master. Measured on a live site
today: /api/energy/daily?days=7 → 1.6 s, days=30 → 1.8 s, days=90 → 3.4 s
— exactly the "seconds" the original commit claimed to eliminate.

Restoring the two missing pieces from 8c0771f:

- state.DayEnergy + DailyEnergy(sinceMs, untilMs): one round-trip that
  integrates grid/pv/bat/load via a SQL LAG() window across the
  three-tier UNION, returning a single pre-integrated row instead of
  shipping ~17k hot-tier samples per day to Go.
- Server.dailyCache + dailyCacheMu: per-local-day memo keyed by
  "YYYY-MM-DD". Past days are immutable once the day ends, so only
  today recomputes per request.

handleEnergyDaily now walks day-by-day: cache-hit for closed days,
always-recompute for today, early-return 500 on the first DB error
(keeps the existing TestHandleEnergyDailyReturns500OnDBError contract).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants