Internetzugriff: fehlenden Einrichtungs-Runbook nachgereicht, Pfad-Freigabeliste korrigiert

REVERSE_PROXY.md verwies auf INTERNET_ZUGRIFF_EINRICHTEN.md, das nie
geschrieben wurde - jetzt vorhanden (Cloudflare-Konto, Nameserver-Umstellung,
Cloudflared/NPM-Add-ons, Pfad-Freigabeliste eintragen, Prüfung).

Dabei einen echten Fehler in der Freigabeliste gefunden: sie ging noch von
einem companion-app-Web-Build unter /local/dm360/ aus (Planungsstand
2026-08-11) - das wurde nie gebaut, die App ist nativ/sideload-only. Ersetzt
durch den tatsächlichen Fernbedarf: das OTA-Bündel unter
/audi_dashboard_static/app/* (@capgo/capacitor-updater). Damit genügt auch
ein einziger Hostname statt der ursprünglich erwogenen App-/API-Trennung.
COMPANION_APP_ARCHITECTURE.md §5 und AGENTS.md entsprechend nachgezogen.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-28 14:41:10 +02:00
co-authored by Claude Sonnet 5
parent 391725e663
commit 3ad1809af6
4 changed files with 270 additions and 35 deletions
+33 -15
View File
@@ -15,9 +15,23 @@ Proxy, der ausschließlich die unten aufgeführten Pfade durchlässt.
> Seit der Umstellung auf eine native Integration (2026-08-23, siehe `AGENTS.md` Abschnitt H) heißen
> Entitäten `sensor.audi_dashboard_*` und Dienste `audi_dashboard.<name>` - keine doppelten Präfixe
> mehr. Die Regeln unten sind auf den aktuellen Stand korrigiert und um zwei seither neu hinzugekommene
> Bedarfe ergänzt (`homeassistant.restart` fürs Selbst-Update, `/local/dm360/*` für die App selbst -
> beide fehlten in der alten Fassung ersatzlos, ohne sie hätte weder der Update-Neustart-Knopf noch die
> ausgelieferte App über den Tunnel funktioniert).
> Bedarfe ergänzt (`homeassistant.restart` fürs Selbst-Update, sowie das OTA-Bündel unter
> `/audi_dashboard_static/app/*` - beide fehlten in der alten Fassung ersatzlos, ohne sie hätte weder
> der Update-Neustart-Knopf noch ein OTA-Update über den Tunnel funktioniert).
>
> **Zweite Korrektur, selber Tag:** die erste Überarbeitung übernahm noch ungeprüft die alte Annahme
> aus der frühen Planungsphase (2026-08-11), die App würde als eigener Web-Build unter
> `/config/www/dm360/` bzw. `/local/dm360/` ausgeliefert. Das wurde nie gebaut - die Distributionsart
> ist seit der Architekturentscheidung "sideload only" (siehe `COMPANION_APP_ARCHITECTURE.md` §1) eine
> **native Capacitor-App**, direkt per Xcode aufs Gerät geladen, nicht über HA im Browser aufgerufen.
> Ein `/local/dm360/*`-Pfad existiert auf dieser Instanz nicht und wird nie gebraucht. Was die native
> App stattdessen tatsächlich extern erreichen muss, ist ihr eigener Oberflächen-Nachlieferweg (OTA,
> `@capgo/capacitor-updater`, siehe `AGENTS.md` Abschnitt "Deployed-parity"-Unterabschnitt): das Bündel
> liegt unter `/audi_dashboard_static/app/bundle.zip`, ausgeliefert von der Integration selbst
> (`custom_components/audi_dashboard/frontend/app/`, `const.py`'s `BUENDEL_URL`) - dieselbe
> `basisUrl`, die die App auch für ihre normalen API-Aufrufe verwendet (`ota.ts`'s
> `buendelAnwenden()`), also derselbe Tunnel-Hostname, kein zweiter. Die Regel unten ist entsprechend
> ersetzt, nicht nur umbenannt.
## Was die App wirklich braucht
@@ -31,7 +45,7 @@ nicht geschätzt - dort gibt es genau drei REST-Aufrufmuster plus WebSocket:
| `POST` | `/api/services/audi_dashboard/*` | alle schreibenden Vorgänge (Fahrt/Tankvorgang anlegen/ändern, CSV-/Historien-Import, Update prüfen/installieren, ...) |
| `POST` | `/api/services/homeassistant/restart` | genau ein Dienst außerhalb der eigenen Domain - der "Jetzt neu starten"-Knopf nach einem Integrations-Update (siehe `AGENTS.md` Abschnitt L) |
| `GET` (Upgrade) | `/api/websocket` | Live-Aktualisierung |
| `GET` | `/local/dm360/*` | die ausgelieferte App selbst (`companion-app`, `vite.config.ts`: `base: "./"`, Ziel `/config/www/dm360/`) - ohne diesen Pfad lädt die Seite gar nicht erst |
| `GET` | `/audi_dashboard_static/app/*` | das OTA-Oberflächen-Bündel (`bundle.zip`) für die native App - ohne diesen Pfad findet ein Update aus der Ferne nicht statt (die App selbst läuft nativ auf dem Gerät, wird nicht über diesen Pfad "geladen") |
| `GET` | `/local/bilder/*.{webp,png,jpg,svg}` | Fahrzeugfotos, die die App anzeigt |
Alles andere wird geblockt, insbesondere `/auth/*`, `/lovelace*`, `/config*`, `/api/config`,
@@ -101,8 +115,9 @@ location = /api/websocket {
include conf.d/include/proxy.conf;
}
# Die App selbst (companion-app, ausgeliefert unter /config/www/dm360/).
location ^~ /local/dm360/ {
# Das OTA-Oberflächen-Bündel für die native App (siehe Hinweis oben - das ist
# NICHT die App selbst, die läuft nativ; nur ihr nachladbares HTML/CSS/JS).
location ^~ /audi_dashboard_static/app/ {
limit_except GET { deny all; }
proxy_pass http://homeassistant:8123;
include conf.d/include/proxy.conf;
@@ -121,11 +136,13 @@ location / {
}
```
Wird die App selbst unter derselben Adresse ausgeliefert (`/local/dm360/` auf demselben Hostnamen wie
die Schnittstelle), braucht dieser Proxy-Host nur die Blöcke oben - kein separater Host nötig. Ein
getrennter Hostname für die Schnittstelle (`api.datametric360.app` statt `datametric360.app`) ist
trotzdem sauberer, siehe `COMPANION_APP_ARCHITECTURE.md` §5 Punkt 4: dann bleibt der `/local/dm360/`-Block
auf dem App-Host, die übrigen Blöcke auf dem API-Host.
**Ein einziger Hostname genügt.** Die frühere Überlegung, App und Schnittstelle auf zwei getrennte
Hostnamen zu legen (`datametric360.app` für die App, `api.datametric360.app` für die Schnittstelle),
stammte aus der Annahme, die App würde selbst als Web-Build unter einer eigenen Adresse ausgeliefert
(siehe Korrektur-Hinweis oben) - das entfällt mit der nativen Distribution ersatzlos. Es gibt nur noch
*eine* Adresse, die überhaupt gebraucht wird: die, die die App beim Einrichten als "Server-Adresse"
bekommt, und über die sie sowohl die API-Aufrufe als auch das OTA-Bündel erreicht. Ein zweiter Hostname
wäre zusätzlicher Aufwand ohne Gegenwert.
## Nach der Einrichtung prüfen
@@ -133,13 +150,15 @@ Von einem Netz ohne VPN, etwa über Mobilfunk (Hostnamen unten sind Platzhalter
Einrichtung tatsächlich gewählt wurde):
```bash
API=https://api.datametric360.app
API=https://datametric360.app
T=<Zugriffstoken>
# muss gehen
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $T" "$API/api/"
curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $T" \
"$API/api/states/sensor.audi_dashboard_profil"
# kein Token nötig - statische Auslieferung, kein API-Aufruf
curl -s -o /dev/null -w '%{http_code}\n' "$API/audi_dashboard_static/app/bundle.zip"
# muss 404 oder 403 liefern
curl -s -o /dev/null -w '%{http_code}\n' "$API/auth/authorize"
@@ -160,6 +179,5 @@ geordneten Ablauf - kurz zusammengefasst bleibt vor der ersten echten Nutzung di
- Cloudflare-Konto anlegen, `datametric360.app`-Zone hinzufügen
- Nameserver von `datametric360.app` bei all-inkl auf Cloudflare umstellen („Full setup")
- Cloudflared- und Nginx-Proxy-Manager-Add-ons installieren, Tunnel + öffentliche Hostnamen einrichten
- Endgültige Hostnamen festlegen (App-Domain vs. API-Subdomain) und hier eintragen
- companion-app-Web-Build nach `/config/www/dm360/` ausliefern
- Cloudflared- und Nginx-Proxy-Manager-Add-ons installieren, Tunnel + öffentlichen Hostnamen einrichten
- `https://datametric360.app` als Server-Adresse in der App eintragen (jedes Gerät, beim Einrichten)