feat/sites-v2
needs attentionviewing older commitdf18b6b · incrementalpre-PRreviewed 2026-08-11 23:08 UTC2H · 5M · 5L · 4I- Purpose
- Demo seeder for the Sites & Devices demo org — provisions a realistic multi-site energy portfolio in preview databases so the demo can be shown end-to-end
- Goal
- Fix the resolved granularity on demo metric sources so energy and data quality display correctly in the UI
- Sub-goals
- Purge stale non-1h metric_sources left by earlier seeder runs
- Cap each stream to exactly two sources (one asset-less, one asset-bearing)
- Replace ON CONFLICT upsert with explicit find-then-update-or-insert to handle two overlapping unique indexes
- What
- seed-demo-org.ts: added pre-loop DELETE for non-1h sources, added assetTaken flag to cap asset-bearing sources per stream, rewrote metric_sources upsert to handle dual unique index conflict
- Why
- Stale 5m siblings from earlier runs caused resolveSiteEnergyStreams to pick 300s granularity, making the energy integral divide by 12 and reporting dataQuality 0.04. The ON CONFLICT could only target one of two overlapping unique indexes.
- Areas
- packages/database+1436−5.github/workflows+12−0docs/development+255−0.gitignore+5−0
- Blast
- 7 files, +1694/-5; scoped entirely to demo seeder infrastructure and preview provisioning — no production code paths touched
Findings · 5
correctness3
Purge scope too broad — no heroSiteNames filter
packages/database/src/demo/seed-demo-org.ts:468
DELETE removes ALL non-1h sources for the org, not just hero sites. If the demo org gains a legitimate non-1h source, a re-run silently deletes it.
INSERT path has no conflict guard
packages/database/src/demo/seed-demo-org.ts:600
The find-then-insert dropped the ON CONFLICT clause. If the SELECT dupe-check misses a row (coalesce edge case or index predicate mismatch), the INSERT throws an unhandled unique violation.
coalesce(externalVariableId, '') conflates NULL and empty-string
packages/database/src/demo/seed-demo-org.ts:600
The SELECT can return no row while the INSERT hits the constraint if the DB stores NULL and the coalesce branch expects empty-string.
conventions1
Partial-failure hazard between purge and upsert not documented
packages/database/src/demo/seed-demo-org.ts:466
Purge runs before the upsert loop; a crash between them leaves the org with no sources.
improvement1
Disjunctive dupe-check OR-predicate can overwrite wrong row
packages/database/src/demo/seed-demo-org.ts:489
A priority-only match can cause UPDATE to overwrite a row with different asset/integration. Two separate targeted lookups (one per index) would be safer.
History · 7 commits
- bf960baneeds attentionincremental5H · 12M · 4L2026-08-12 05:48
- eb284feneeds attentionincremental0H · 5M · 4L2026-08-12 05:10
- 6bfc5bcneeds attentionincremental4H · 7M · 6L2026-08-12 02:49
- 3d49126safeincremental0H · 0M · 2L2026-08-11 23:15
- df18b6bneeds attentionincremental2H · 5M · 5L2026-08-11 23:08current
- 8b42c1eneeds attentionincremental0H · 2M · 3L2026-08-11 23:01
- 5c64ea3needs attentionfull3H · 4M · 5L2026-08-11 19:15