Skip to content

feat(cli): validate --location against vendored zone list (#94)#95

Draft
LukasWodka wants to merge 1 commit into
feat/84-location-autodetectfrom
feat/84-location-validation
Draft

feat(cli): validate --location against vendored zone list (#94)#95
LukasWodka wants to merge 1 commit into
feat/84-location-autodetectfrom
feat/84-location-validation

Conversation

@LukasWodka

Copy link
Copy Markdown
Contributor

Summary

Closes #94. EdgeDevice.location is CharField(choices=ZONE_CHOICES) (electricityMaps zones), so the backend's ChoiceField rejects any zone not in the list. The CLI didn't validate --location / the prompt, so a bad value (Germany, eu-central-1, a typo) only failed as an opaque 400 at create time. This validates against a vendored copy of the list and fails fast with suggestions.

Stacked on #93 (feat/84-location-autodetect, itself on #92) — retarget down the chain as each merges.

What's here

  • internal/zones — the backend's ZONE_CHOICES vendored as zones.json (352 zones: countries + sub-zones like US-CAL-CISO), embedded via go:embed. Valid / Name / Suggest.
  • scripts/sync-zones.sh — regenerates zones.json from the backend's metaApi/models/zone_choices.py (the source of truth — it's what the API validates against), with a --check drift mode for CI.
  • client create--location and the location prompt validate against the list, failing fast with close-match suggestions ("germany"did you mean: DE?; "de"DE). The feat(cli): location auto-detect for client create (#84) #93 auto-detect only pre-fills a detected zone if it's actually valid.

Why a local-file sync (not a URL like sync-schema.sh)

sync-schema.sh curls data-ingestors (a public repo). backend is private, so an anonymous curl of zone_choices.py won't work — and the backend file is the authoritative validation source, so the script reads it from a sibling checkout (ZONES_SOURCE to override). The committed zones.json is what the binary uses; the script is the maintenance / CI-drift tool.

Tests

internal/zones: Valid/Name (case-sensitivity + sub-zones), Suggest (name match, wrong-case, prefix, garbage → none). internal/cli: an invalid --location errors with a DE suggestion before any API call; the existing flow/interactive tests still pass (DE/US/detected FR are valid). Full go build / vet / test ./... green.

🤖 Generated with Claude Code

EdgeDevice.location is CharField(choices=ZONE_CHOICES) (electricityMaps zones),
so the backend rejects any zone not in the list. The CLI didn't validate, so a
bad --location (or a prompt typo) only failed as an opaque 400 at create time.

- internal/zones: the backend's ZONE_CHOICES vendored as zones.json (352 zones)
  and go:embed-ed; Valid / Name / Suggest. scripts/sync-zones.sh regenerates it
  from the backend's metaApi/models/zone_choices.py (the source of truth — a
  private repo, so a local sibling read rather than a curl), with a --check
  drift mode for CI, mirroring sync-schema.sh.
- client create: --location and the location prompt validate against the list
  and fail fast with close-match suggestions ("germany" → did you mean DE?). The
  cli#93 auto-detect only pre-fills a detected zone if it's valid.

Tests: zones Valid/Name/Suggest; cli rejects an invalid --location before any
API call. go build/vet/test green.

Closes #94.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@LukasWodka LukasWodka requested a review from saadqbal June 22, 2026 06:52
@saadqbal saadqbal marked this pull request as draft June 22, 2026 07:34
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.

1 participant