From 41e272949f8d95ffeed1b025fea7363b1cabfac7 Mon Sep 17 00:00:00 2001 From: Eratostenes de Gitjabia Date: Sat, 9 May 2026 12:25:44 +0000 Subject: [PATCH] =?UTF-8?q?docs(decisions):=20ADR=200006=20=E2=80=94=20rou?= =?UTF-8?q?ter=20serves=20shell,=20Cell=20provides=20APIs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- decisions/0006-router-sirve-shell-ui.md | 49 +++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 decisions/0006-router-sirve-shell-ui.md diff --git a/decisions/0006-router-sirve-shell-ui.md b/decisions/0006-router-sirve-shell-ui.md new file mode 100644 index 0000000..b388a07 --- /dev/null +++ b/decisions/0006-router-sirve-shell-ui.md @@ -0,0 +1,49 @@ +# 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//*` → 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.