Files
wdmUI/decisions/0006-router-sirve-shell-ui.md

1.8 KiB

ADR-0006 · Router serves console shell, Cell provides APIs

Status: accepted Date: 2026-05

Context

The operator console is a SPA that needs:

  • A stable, well-known URL (http://blocao-router.local/).
  • Access to APIs from both the router (network config) and the Cell (Frigate, forensic engine).
  • TLS termination.
  • Auth.

Options:

  1. SPA hosted on the Cell, router redirects.
  2. SPA hosted on the router, Cell exposes APIs cross-origin.
  3. SPA hosted on the router, router reverse-proxies to Cell APIs.

Decision

Option 3. The router always serves the SPA shell at http://blocao-router.local/ (or HTTPS once cert is set up). The Cell provides APIs only — never a UI directly.

The router reverse-proxies API calls based on path:

  • /api/router/* → local ubus over /ubus
  • /api/cell/* → discovered Cell IP/port
  • /api/cell/<cell-id>/* → specific Cell when multi-Cell

The browser only ever talks to the router. CORS never appears.

Consequences

Good:

  • Single origin, no CORS complications.
  • Cell can be unreachable temporarily without breaking the router-side parts of the UI.
  • Router is the natural single point of auth.
  • Cell discovery is a router responsibility, transparent to the UI.

Bad / trade-offs:

  • Router has to do reverse-proxy work; small CPU cost on a low-power device.
  • If the router is down, no UI access at all. Mitigated by Tailscale fallback to direct Cell SSH (ops only).
  • The mental model "router = thin, Cell = fat" is partially violated — router does carry the SPA bytes.

Alternatives considered

  • Cell hosts the SPA: requires Cell to be discoverable from operator's machine, makes URLs unstable when Cell IPs change.
  • Hub hosts the SPA, both router and Cell expose APIs: requires WAN connectivity for the operator UI, breaks air-gapped deployments.