Skip to content

feat(radioHardware): save through update_radio_hardware_config - #92

Draft
npdgm wants to merge 1 commit into
openhop-dev:devfrom
npdgm:feat/radio-hardware-endpoint
Draft

feat(radioHardware): save through update_radio_hardware_config#92
npdgm wants to merge 1 commit into
openhop-dev:devfrom
npdgm:feat/radio-hardware-endpoint

Conversation

@npdgm

@npdgm npdgm commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Problem

The Radio Hardware tab saves through ApiService.importConfig/api/config_import. That endpoint is auth-exempt for first-run restore and never sees an authenticated user, so on a configured node every save returns 403 "Unauthorized restore" — masked as "Unknown error occurred" because handleError only understands axios errors, not the HttpResponse objects thrown by the generated fetch client (src/generated/openapi.ts: if (!response.ok) throw data).

The tab also only sent the form's visible pin fields: preset fields without widgets (use_dio3_tcxo, use_dio2_rf, gpio_chip, ...) were silently dropped — a Station G3 configured from the tab would lose its TCXO settings.

Change

  • Save through the new authenticated POST /api/update_radio_hardware_config (generated client refreshed from the repeater openapi.yaml via npm run api:generate). With a board preset selected the payload is {hardware_key, overrides}: the backend applies the full preset — hidden fields included — and the visible form fields ride along as overrides (values equal to the preset are no-ops, deliberate edits win). Without a preset the payload stays {radio_type, <section>} (manual mode).
  • applyBoardPreset() resets fields absent from the preset to neutral defaults instead of keeping the previous board's values, so the form always reads "preset + deliberate edits" and a stale txen_pin can't leak into the new board.
  • New read-only "Preset-managed settings" block under the preset dropdown, listing every preset field that has no editable widget. Server-applied values become visible, and a preset field added upstream shows up automatically with no UI change. The note warns that presets defining tx_power/preamble_length override those Radio Settings values on save.
  • handleError() fix: surfaces the server's error message from non-2xx responses thrown by the generated client (body in .error), instead of the generic "Unknown error occurred". This benefits every generated-client call, not just this tab. Note this changes user-visible error strings globally (e.g. 401s now read "Unauthorized - Valid JWT or API token required").

Depends on

Backend PR adding the endpoint: openhop-dev/openhop_repeater#384

Test plan

  • npm run type-check clean
  • eslint — zero new findings (9 pre-existing no-explicit-any on untouched lines, present on dev)
  • vitest — 200 passed, 1 pre-existing failure on dev (nav styles, unrelated)
  • npm run api:generate output committed (api:check stays green against the backend branch)

The Radio Hardware tab saved through ApiService.importConfig →
/api/config_import. That endpoint is auth-exempt for first-run restore
and never sees an authenticated user, so on a configured node every save
returned 403 "Unauthorized restore" — masked as "Unknown error occurred"
because handleError only understood axios errors, not the HttpResponse
objects thrown by the generated fetch client.

* Save through the new authenticated /api/update_radio_hardware_config
  (generated client refreshed from the repeater openapi.yaml). With a
  board preset selected the payload is {hardware_key, overrides}: the
  backend applies the full preset — including fields this form has no
  widgets for (use_dio3_tcxo, use_dio2_rf, gpio backend, ...), which
  were silently dropped before — and the visible form fields ride along
  as overrides (values equal to the preset are no-ops, deliberate edits
  win). Without a preset the payload stays {radio_type, <section>}
  (manual mode).
* applyBoardPreset() resets fields absent from the preset to neutral
  defaults instead of keeping the previous board's values, so the form
  always reads "preset + deliberate edits".
* New read-only "Preset-managed settings" block listing every preset
  field without an editable widget — server-applied values become
  visible, and a preset field added upstream shows up automatically
  with no UI change. The note warns that presets defining tx_power /
  preamble_length override those Radio Settings values on save.
* handleError() surfaces the server's error message from non-2xx
  responses thrown by the generated client instead of the generic
  "Unknown error occurred".

Requires the repeater branch adding /api/update_radio_hardware_config.

Signed-off-by: Thibault VINCENT <root@devcat.org>
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