← all branches

feat/sites-v2

safeviewing older commit
3d49126 · incrementalpre-PRreviewed 2026-08-11 23:15 UTC0H · 0M · 2L · 4I
The branch
Purpose
Provide a Sites & Devices demo org with realistic, differentiated timeseries data so all five hero sites show distinct production curves, accurate savings, and full data-quality coverage in the Batu platform UI.
Goal
Bootstrap the feat/sites-v2 preview environment with a seeded demo org that makes the sites-and-devices experience reviewable end-to-end without real CFE connections.
Sub-goals
  • SG-1: Extract prod fixture — prod extractor + preview seeder scaffold
  • SG-2: Seed org end-to-end — sites, devices, streams, contracts, bills in Postgres
  • SG-3: Seed metrics in Tinybird — hourly W series reconciled to billed kWh
  • SG-4: Fix preview reads DEV Tinybird workspace, not staging/prod
  • SG-5: Fix distinct per-site production sizing + dataQuality 1.0
The changes (whole branch)
What
Replaced `hiredDemandKw`-based PV array sizing with `meanLoadW` derived from each site's own billed consumption, giving each hero site a distinct generation curve. Removed the `watts <= 0` early-continue guard so nighttime/zero hours emit explicit rows, driving dataQuality to 1.0.
Why
The `hiredDemandKw` was 3/4/null across the five sites so four collapsed to an identical 3 kW fallback curve. Billed consumption is the right denominator since it's what the savings analysis compares against. Zero-watt rows were accidentally suppressing full slot coverage, making dataQuality < 1.0 even for well-monitored sites.
Areas
.github/workflows/preview-provision.yml+143.claude/sites-devices-demo/execution-prompt.md+2550packages/database/src/demo/extract-prod-fixture.ts+2540packages/database/src/demo/seed-demo-metrics.ts+2890packages/database/src/demo/seed-demo-org.ts+8910
Blast
5 new/modified files, +1709/−5 lines. All changes are demo/dev-only (preview seeder scripts and a workflow step). No production code touched.
demo-only no-prod-impact tinybird-write
CI / GitHub checks· No PR open — pre-PR branch; CI status not availableCodeRabbit· No .coderabbit.yaml in repo

Findings · 6

correctness2

low

meanLoadW uses unweighted mean of per-period mean-powers

packages/database/src/demo/seed-demo-metrics.ts:189

The reducer accumulates (kwh*1000/hrs) per period and divides by period count — an unweighted mean. For unequal-length periods (partial first period, mixed bimestral/mensual) this will differ from the true time-weighted mean (totalKwh*1000/totalHours). For the demo's uniform CFE periods the error is negligible, but a comment noting the approximation would prevent a future 'fix' that still gets it wrong.

info

LOAD_SHAPE comment says 'sums to 24' but the array sums to 24.85

packages/database/src/demo/seed-demo-metrics.ts:68

The comment is inaccurate (24.85, not 24). No semantic impact — LOAD_SHAPE is used as a relative shaping factor, not integrated. Could mislead a future maintainer trying to re-derive mean power from the shape.

conventions2

info

Constant 0.65 in export load formula lacks origin comment

packages/database/src/demo/seed-demo-metrics.ts:237

The comment explains WHY the load is scaled (full load prevented surplus from ever clearing), but the value 0.65 itself is unexplained — is it 1−0.35 from the old code, or independently derived? A brief note ('// 0.65 = daytime coincident fraction') would close the gap per the project's 'explain the WHY' convention.

info

Removed `continue` guard has no comment explaining intent

packages/database/src/demo/seed-demo-metrics.ts:241

The removed `if (watts <= 0 && t.variable !== 'grid_import') continue` now causes zero-watt rows to be emitted for nighttime solar and non-exporting sites. This drives dataQuality to 1.0 (the commit's stated goal). A one-line comment at `energyWh += watts` noting 'zero-watt rows are emitted deliberately for full slot coverage (DQ=1.0)' would prevent accidental revert as 'dead weight'.

tests1

info

No unit tests — expected for demo seeder scripts

packages/database/src/demo/seed-demo-metrics.ts:1

Demo seeder scripts in packages/database/src/demo/ have no test suite by convention. The --dry-run flag is the intended verification path. The new meanLoadW/kwpDerived calculations are simple enough that dry-run inspection covers the risk adequately.

improvement1

low

`kwpDerived * 1000` repeated in two branches of the inner loop

packages/database/src/demo/seed-demo-metrics.ts:230

Both solar_generation and NETMET grid_export compute `kwpDerived * 1000`. Trivially cheap at runtime, but hoisting to `const kwpDerivedW = kwpDerived * 1000` before the loop removes duplication and makes the kWp→W conversion visible once at the definition site.

History · 7 commits

  1. bf960baneeds attentionincremental5H · 12M · 4L2026-08-12 05:48
  2. eb284feneeds attentionincremental0H · 5M · 4L2026-08-12 05:10
  3. 6bfc5bcneeds attentionincremental4H · 7M · 6L2026-08-12 02:49
  4. 3d49126safeincremental0H · 0M · 2L2026-08-11 23:15current
  5. df18b6bneeds attentionincremental2H · 5M · 5L2026-08-11 23:08
  6. 8b42c1eneeds attentionincremental0H · 2M · 3L2026-08-11 23:01
  7. 5c64ea3needs attentionfull3H · 4M · 5L2026-08-11 19:15