← all branches

feat/powerradar

safeviewing older commit
1e80096 · incrementalPR #327reviewed 2026-07-22 16:42 UTC0H · 0M · 1L · 2I
The branch
Purpose
Add an automatic, API-based PowerRadar (Centrica/Panoramic Power) metrics integration replacing the manual-CSV path with native 5/15/60-min collection via the portal's internal /eigw API and headless OAuth password-grant auth.
Goal
Second access path to the powerradar brand (powerradar-api), mirroring the shelly-cloud→shelly-fleet split; fully headless (no MFA, no browser), live-verified end-to-end.
Sub-goals
  • SG-1: Transport engine — headless OAuth password-grant + /eigw chart-data client, live-verified
  • SG-2: Manifest + catalog + provider enum + ARN REGISTRY registration
  • SG-3: Pure chart-to-batu translation (demand←consumption, solar_generation←generation) + 13 tests
  • SG-4: Metrics handler (§9 one-fetch-per-grain, resilient skips) + 18 tests
  • SG-5: CDK stack + paths.ts + main.ts + coordinator invoke grant
  • SG-6/7: Live worker e2e (15m/2d→191 demand points, 1h/3d→71 solar skipped) + integrations CLAUDE.md
The changes (whole branch)
What
4 CI-fix commits: (1) add 'powerradar-api' to SecretProvider domain union to mirror Drizzle schema (schema drift caught by AssertEqual compile check failing CI); (2-4) lockfile regeneration fixes — prior regen pruned services/findings importer causing ERR_PNPM_LOCKFILE_MISSING_DEPENDENCY on frozen-lockfile CI; final fix resets to main's complete lockfile and adds only the powerradar-api importer block.
Why
CI was failing on multiple jobs (Validate Code Quality, Database Schema, e2e) due to the type drift and lockfile inconsistency introduced when adding the new powerradar-api package to the monorepo.
Areas
services/metrics+15930.branch+288315infra/cdk+1932packages/integration-manifests+1090packages/database+170domains/core+21
Blast
26 files, +2309/-320 across 6 areas; new worker package in services/metrics (1593 adds), CDK infra (193 adds), manifests (109 adds), DB seed (17 adds), domain type fix (2 adds/1 del). No shared infra or auth layer modified.
powerradar-api OAuth uses password grant — CloudFront WAF/bot-detection mitigated by browser-like headers + token caching + sequential pacing; unverified from prod AWS IPs
ci· CI re-triggered by 3eea497d; results not yet available at review timecoderabbit· no .coderabbit.yaml in repo

Findings · 3

conventions1

info

Lockfile approach is correct: add-only, zero deletions

pnpm-lock.yaml

The 1e80096f commit resets to main's complete lockfile then adds only the powerradar-api importer block (+37 lines, 0 deletions), copied verbatim from the solark importer. This is the correct add-only convention after the prior regen accidentally pruned services/findings. CI should now pass.

tests1

info

No runtime fixture for provider='powerradar-api' in secret-configuration tests

domains/core/src/secret-configuration/__tests__/secret-configuration.decisions.test.ts

The compile-time AssertEqual guard is canonical and sufficient for a pure union extension with no behavioral branching. Acceptable as-is; adding a fixture to the integration test when a full onboarding scenario is built would close the gap.

improvement1

low

SecretProvider union is manually maintained — derivable from DB schema const

domains/core/src/secret-configuration/secret-configuration.type.ts

This bug proves the drift risk: 'powerradar-api' landed in the DB schema enum but wasn't mirrored in the domain union simultaneously, causing a CI failure. The AssertEqual guard doesn't catch subset drift because pg enums infer as string. A safer pattern: export a const array from the DB schema (e.g. `export const SECRET_PROVIDER_VALUES = ['cfe', ..., 'powerradar-api'] as const`) and derive the domain type as `type SecretProvider = typeof SECRET_PROVIDER_VALUES[number]`. This eliminates the dual-maintenance surface entirely.

History · 15 commits

  1. f34e4ceneeds attentionincremental0H · 1M · 3L2026-07-23 00:32
  2. 1bc8aedneeds attentionincremental0H · 2M · 3L2026-07-22 21:34
  3. 31e63bbneeds attentionincremental0H · 2M · 5L2026-07-22 20:53
  4. 482cb88safeincremental0H · 0M · 1L2026-07-22 17:56
  5. 9a73b79safeincremental0H · 0M · 0L2026-07-22 17:34
  6. 87f8298needs attentionincremental0H · 1M · 3L2026-07-22 16:59
  7. 1e80096safeincremental0H · 0M · 1L2026-07-22 16:42current
  8. 6ed65b4safeincremental0H · 1M · 3L2026-07-22 00:00
  9. 74a1131needs attentionfull0H · 7M · 12L2026-07-21 19:06
  10. 563252bneeds attentionincremental4H · 9M · 8L2026-07-21 18:32
  11. beced58needs attentionincremental0H · 3M · 3L2026-07-21 01:13
  12. 7fa8684needs attentionincremental4H · 9M · 7L2026-07-20 22:56
  13. 230784fneeds attentionfull2H · 11M · 14L2026-07-10 00:15
  14. b876b54needs attentionincremental2H · 2M · 5L2026-07-08 04:44
  15. ec4847fneeds attentionfull2H · 11M · 8L2026-07-08 03:32