feat/huawei
needs attentionviewing older commit01f16f6 · fullpre-PRreviewed 2026-07-07 21:03 UTC1H · 4M · 10L · 5I- Purpose
- Foundation scaffolding for porting 12 legacy device integrations into the v2 metrics engine. Pre-declares all shared seams so brand-specific branches each add only their own vendor package + CDK stack.
- Goal
- Port the Huawei FusionSolar integration (90 devices) plus lay the shared foundation for all 12 device-integration ports.
- Sub-goals
- SG-1: Add 12 device-integration manifests
- SG-2: Seed catalog rows (Make/Integration/MetricType)
- SG-3: Pre-declare CDK paths.ts handler entries
- SG-4: ARN-seed REGISTRY with --only guard
- SG-5: D3 legacy-registry migration script
- SG-6: D2 legacy-credential copy script + SecretProvider widening
- SG-N: Framework learnings fold-back
- What
- 12 new IntegrationManifest files; SecretProvider union widened (TS-only); 3 new MetricTypes; 11 new Makes + 12 Integration rows; 12 REGISTRY entries + --only guard; 185 lines CDK paths contracts; new @batu/metrics-migration workspace package with D2/D3 scripts + tests; docs updates
- Why
- Enables remaining 12 brand branches to each add only vendor package + CDK stack with all shared seams pre-landed. Victron (PR #269) is the first consumer.
- Areas
- packages/integration-manifests+980−2scripts/metrics+1645−0packages/database+257−14infra/cdk+185−0domains/core+16−1services/metrics/integrations+38−8
- Blast
- ~3,150 lines added across 7 areas. No runtime production code changed — manifests are pure data; seeds are one-shot; D2/D3 scripts are operator tools with --apply gate.
Findings · 20
correctness2
paths.ts comment says handler keys mirror REGISTRY as 'explore' — REGISTRY uses 'exploration'
infra/cdk/src/lib/paths.ts:233
Brand-branch authors reading the comment could seed with key 'explore' instead of 'exploration', getting WorkerArnMissing at dispatch.
'load' MetricType lacks billing-interpretation note in site-metrics-seam.md
packages/database/src/seed-metrics-catalog.ts:341
security3
--source-env unvalidated; used in regex interpolation in legacy-secrets-core.ts
scripts/metrics/copy-legacy-secrets.ts:277
--target-env has an allowlist; --source-env does not. Metacharacters in the value widen the secret name filter.
DB rows emitted for secrets whose value was NOT refreshed when --overwrite omitted
scripts/metrics/copy-legacy-secrets.ts:168
Existing-secret case adds item to outcomes and emits DB rows pointing to the existing ARN regardless of whether its value is current.
Top-level catch logs raw AWS Error — safe (no secret values in SDK errors)
scripts/metrics/copy-legacy-secrets.ts:338
conventions5
'exploration' REGISTRY key vs 'explore' paths.ts handler key undocumented in INTEGRATION_STANDARDS.md
packages/database/src/seed-integration-arns.ts:79
Dispatch reads workerArns?.exploration. paths.ts uses handlers.explore. Consistent but undocumented; brand branches risk seeding the wrong key.
scripts/metrics is the first workspace-package script — convention not formalized
pnpm-workspace.yaml:23
huawei-portal/shelly-cloud seed rows missing credentialFields lockstep reminder
packages/database/src/seed-metrics-catalog.ts:181
buildMigrationPlan ADR-016 compliance — correct (issues[] IS the error channel)
scripts/metrics/lib/legacy-registry-core.ts:230
All 12 manifest structures match growatt/egauge/helioscope precedent exactly
packages/integration-manifests/src/manifests/huawei-portal.ts:31
tests7
migrate-legacy-registry apply() path has zero test coverage — unmapped-sites safety gate untested
scripts/metrics/migrate-legacy-registry.ts:138
The apply() function performs catalog pre-fetch, site lookup, and provisionAssetShell per device. The pre-apply refusal on unmapped sites and the missing-catalog detection have no tests.
No test for --only guard in seed-integration-arns.ts
packages/database/src/seed-integration-arns.ts:118
Given the dangling-ARN warning, the unknown-code throw path deserves regression protection.
No test enforces credentialFields lockstep between manifests and seed-metrics-catalog.ts
packages/database/src/seed-metrics-catalog.ts:156
A manifest field rename on a brand branch would skew the FE wizard with no signal.
D3 test doesn't isolate LEGACY_CANONICAL_TO_METRIC_TYPE fallback miss path
scripts/metrics/__tests__/legacy-registry-core.test.ts:146
legacy-secrets-core test doesn't assert portal boolean on SecretCopyPlanItem
scripts/metrics/__tests__/legacy-secrets-core.test.ts:89
externalVariableId spot-checks all verified correct against actual manifests
packages/integration-manifests/src/__tests__/device-integrations.test.ts:128
egauge.test.ts granularity update to ['5m','15m'] is self-consistent and correct
packages/integration-manifests/src/__tests__/egauge.test.ts:31
improvement3
@aws-sdk/util-dynamodb dep declared but parseSitesDevicesItems hand-rolls the same attr() walker
scripts/metrics/lib/legacy-registry-core.ts:169
credentialFields lockstep has no compile-time enforcement
packages/integration-manifests/src/__tests__/device-integrations.test.ts:49
Dry-run-by-default (--apply opt-in) is correct but non-discoverable in shell history
scripts/metrics/copy-legacy-secrets.ts:309