Installation
Aktueller Installationspfad
Abschnitt betitelt „Aktueller Installationspfad“Was heute wirklich verifiziert ist
Abschnitt betitelt „Was heute wirklich verifiziert ist“- Die Android-App baut lokal aus
superheld-android. superheld-cloudstartet lokal im Secure-Mux-Default mit Bootstrap-Token.- Die App bietet im Settings-Bereich einen Account-Sign-in/Create-Account-Pfad, der die vorhandenen
POST /account/register- undPOST /account/login-Endpoints nutzt, die Session speichert und danach zurueck auf die Home-Oberflaeche geht. Fuer normale Endnutzer (DAU) ist das der primaere Einrichtungspfad; manuelles Token-Minting ist nicht noetig. - Die App kann
POST /devices,POST /events,GET /status,GET /alerts,GET /incidents,GET /jobsund fuer den letzten sichtbaren Job zusaetzlichGET /jobs/{id}sowie bei vorhandenertrace_idGET /traces/{id}plusGET /traces/{id}/stepsgegen das lokale Backend nutzen. - Der DAU-Home-Screen zeigt keine separate Settings-/Hilfe-Karte. Setup und Hilfe sind nur ueber die Primaeraaktion auf dem Home-Screen oder den Tab „Settings” in der Bottom-Navigation erreichbar. Alle vier Tabs (Home, Warnings, Issues, Settings) sind im taeglichen Betrieb stabil sichtbar (Commit
158c53c). - Der reale Tablet-Lauf wurde mit
adb reverse tcp:8080 tcp:8080gegenhttp://127.0.0.1:8080verifiziert. - Ein fehlender
events:write-Scope ist in der App sichtbar als klares BannerEvent token is missing events:write.plusHTTP 403 insufficient_scope. - Ein fehlender
alerts:read-Scope ist in der App sichtbar alsAlert read failed.plusHTTP 403 insufficient_scope. - Ein fehlender
incidents:read-Scope ist in der App sichtbar alsHTTP 403 insufficient_scope. - Ein fehlender
jobs:read-Scope ist in der App sichtbar alsHTTP 403 insufficient_scope. - Ein absichtlich falscher App-Tenant bleibt ebenfalls sichtbar: mit
tenant-debugin der App, aber einem weiter tenant-local-gebundenen Token zeigte dieselbe KonfigurationskarteLast backend tenant: tenant-localplus eine explizite Tenant-Mismatch-Warnung.
Was noch nicht als aktueller Runtime-Stand belegt ist
Abschnitt betitelt „Was noch nicht als aktueller Runtime-Stand belegt ist“- Distribution über Play Store oder App Store
- iOS-, Windows-, macOS- oder Linux-App als verifizierter v1-Lieferpfad
- Web-Dashboard als verifizierter Betriebs- oder Nutzerpfad
- Emulator-Flow in diesem Workspace; die lokale SDK-Installation enthält derzeit kein
emulator-Binary und keinesystem-images
Voraussetzungen
Abschnitt betitelt „Voraussetzungen“- Workspace unter
/Users/benediktpoller/code/sh - Go-Toolchain für
superheld-cloud - JDK 17 oder 21
- Android SDK Platform 35
adb,curlundjq- Optional, aber für den verifizierten Pfad empfohlen: ein per USB angeschlossenes Android-Tablet
Schnell-Check der Voraussetzungen
Abschnitt betitelt „Schnell-Check der Voraussetzungen“go version # erwartet: go1.22 oder neuerjava -version # erwartet: 17 oder 21adb version # erwartet: beliebige aktuelle Versioncurl --version # erwartet: beliebige aktuelle Versionjq --version # erwartet: beliebige aktuelle Versionls "$HOME/Library/Android/sdk/platforms/android-35/" # erwartet: kein FehlerFalls android-35 fehlt, kann die Plattform ueber den SDK Manager nachinstalliert werden:
"$HOME/Library/Android/sdk/cmdline-tools/latest/bin/sdkmanager" "platforms;android-35"Workspace-Umgebung vorbereiten
Abschnitt betitelt „Workspace-Umgebung vorbereiten“Der Android-Build benoetigt local.properties mit dem SDK-Pfad. Falls die Datei noch nicht existiert:
echo "sdk.dir=$HOME/Library/Android/sdk" > /Users/benediktpoller/code/sh/superheld-android/local.propertiesDie folgenden Umgebungsvariablen halten Gradle-Caches im Workspace und vermeiden Konflikte mit globalen Einstellungen:
export ANDROID_USER_HOME=/Users/benediktpoller/code/sh/workspace/.androidexport GRADLE_USER_HOME=/Users/benediktpoller/code/sh/workspace/.gradle-home1. Lokale Cloud starten
Abschnitt betitelt „1. Lokale Cloud starten“cd /Users/benediktpoller/code/sh/superheld-cloudSUPERHELD_BOOTSTRAP_TOKEN=bootstrap-token \SUPERHELD_BOOTSTRAP_TENANT_ID=tenant-local \go run ./cmd/serverWichtige Runtime-Fakten:
- Default-Bind:
127.0.0.1:8080 - Secure-Mux ist Default; ohne
SUPERHELD_BOOTSTRAP_TOKENstartetcmd/servernicht im sicheren Modus - Persistenz liegt standardmäßig unter
./data; mitSUPERHELD_DATA_DIR(JSON-Dateien) oderSUPERHELD_SQLITE_PATH(SQLite-Datenbank) kann der Lauf expliziter gemacht werden - Mit
SUPERHELD_SQLITE_PATHueberleben Incidents und andere Daten einen Server-Restart zuverlaessig
Schnelltest nach dem Start (in einem zweiten Terminal):
curl -s http://127.0.0.1:8080/status \ -H 'Authorization: Bearer bootstrap-token' | jq .Erwartet wird eine JSON-Antwort mit dem aktuellen Schutzstatus. Falls der Aufruf fehlschlaegt, ist der Server nicht korrekt gestartet.
2. Einrichtungspfad waehlen
Abschnitt betitelt „2. Einrichtungspfad waehlen“Seit Commit 0371231 bietet die Android-App im Settings-Bereich zwei Wege zur Einrichtung:
DAU-Pfad: Account-Sign-in (empfohlen fuer Endnutzer)
Abschnitt betitelt „DAU-Pfad: Account-Sign-in (empfohlen fuer Endnutzer)“Normale Endnutzer muessen kein Token manuell minten. Stattdessen wird im Settings-Bereich der App ein Account erstellt oder ein bestehender Account verwendet. Die App nutzt dafuer die vorhandenen Endpoints POST /account/register (mit E-Mail, Passwort und Tenant-ID) bzw. POST /account/login (mit E-Mail und Passwort). Nach erfolgreichem Sign-in speichert die App die Session und kehrt zur Home-Oberflaeche zurueck. Die Session traegt automatisch die benoetigten Scopes (status:read, devices:read, alerts:read, incidents:read, tokens:read, tokens:write).
Fuer diesen Pfad reicht es, nach dem Start der lokalen Cloud (Schritt 1) direkt mit dem App-Build (Schritt 3) fortzufahren. Die Account-Einrichtung erfolgt dann in der App selbst.
Operator-/Entwickler-Pfad: Manuelles Token minten
Abschnitt betitelt „Operator-/Entwickler-Pfad: Manuelles Token minten“Fuer Operatoren, Entwickler und automatisierte Setups bleibt der manuelle Token-Pfad verfuegbar. Das App-Token fuer den verifizierten Android-MVP benoetigt mindestens diese Scopes:
devices:writeevents:writestatus:readalerts:readincidents:readjobs:read
Für den heute verifizierten host-seitigen Demo-Job-Lauf kam zusätzlich jobs:write hinzu.
curl -s \ -X POST http://127.0.0.1:8080/tokens \ -H 'Authorization: Bearer bootstrap-token' \ -H 'Content-Type: application/json' \ -d '{"scopes":["devices:write","events:write","status:read","alerts:read","incidents:read","jobs:read","jobs:write"]}' \ | jq .Erwartet wird eine Antwort mit einem Roh-Token, das genau einmal zurückgegeben wird, plus tenant_id=tenant-local.
Diese Token-Bindung ist die Runtime-Wahrheit. Wenn die App spaeter mit einer anderen tenant_id startet, signalisiert sie den Drift jetzt explizit, statt einen normalen Success ohne Hinweis zu zeigen.
2b. Optionaler, aber heute verifizierter Demo-Job
Abschnitt betitelt „2b. Optionaler, aber heute verifizierter Demo-Job“Um die Job-Karte in der App mit echtem Backend-Inhalt zu fuellen, wurde im verifizierten Lauf host-seitig ein kleiner Demo-Job angelegt:
curl -s \ -X POST http://127.0.0.1:8080/jobs \ -H 'Authorization: Bearer <tenant-app-token>' \ -H 'Content-Type: application/json' \ -d '{"job_class":"incident_triage","workflow_id":"incident_triage_v1","input_refs":{"event_ids":["evt-job-read-demo-missing"]}}' \ | jq .Dieser Demo-Job landet ohne vorhandenes Quellereignis erwartbar in failed_terminal, bleibt tenant-scoped ueber GET /jobs sichtbar und wird in der App fuer den letzten sichtbaren Job zusaetzlich ueber GET /jobs/{id} nachgeladen. Der Pfad traegt dabei eine trace_id, die in der App unmittelbar fuer GET /traces/{id} und GET /traces/{id}/steps weiterverwendet wird.
3. Android-App lokal bauen
Abschnitt betitelt „3. Android-App lokal bauen“cd /Users/benediktpoller/code/sh/superheld-androidANDROID_USER_HOME=/Users/benediktpoller/code/sh/workspace/.android \GRADLE_USER_HOME=/Users/benediktpoller/code/sh/workspace/.gradle-home \./gradlew testDebugUnitTest assembleDebugWenn local.properties noch fehlt, muss sdk.dir=/Users/benediktpoller/Library/Android/sdk gesetzt sein.
4. USB-Tablet vorbereiten
Abschnitt betitelt „4. USB-Tablet vorbereiten“adb devicesadb reverse tcp:8080 tcp:8080Für den verifizierten Tablet-Pfad gilt:
- bevorzugte Backend-URL in der App:
http://127.0.0.1:8080 10.0.2.2:8080bleibt der Emulatorpfad und ist in diesem Workspace aktuell nicht als realer Lauf belegt
5. App installieren und starten
Abschnitt betitelt „5. App installieren und starten“DAU-Pfad (Account-Sign-in in der App)
Abschnitt betitelt „DAU-Pfad (Account-Sign-in in der App)“Wenn der Account-Sign-in-Pfad genutzt wird, genuegt die Installation ohne Build-Parameter fuer Token und Tenant. Die Backend-URL kann optional vorbelegt werden:
cd /Users/benediktpoller/code/sh/superheld-androidANDROID_USER_HOME=/Users/benediktpoller/code/sh/workspace/.android \GRADLE_USER_HOME=/Users/benediktpoller/code/sh/workspace/.gradle-home \./gradlew installDebug \ -Psuperheld.baseUrl=http://127.0.0.1:8080
adb shell am start -W -n com.superheld.android/.MainActivityDie App oeffnet den Settings-Bereich und bietet dort Account erstellen oder anmelden an. Nach erfolgreichem Sign-in kehrt die App zur Home-Oberflaeche zurueck.
Operator-Pfad (manuelles Token)
Abschnitt betitelt „Operator-Pfad (manuelles Token)“cd /Users/benediktpoller/code/sh/superheld-androidANDROID_USER_HOME=/Users/benediktpoller/code/sh/workspace/.android \GRADLE_USER_HOME=/Users/benediktpoller/code/sh/workspace/.gradle-home \./gradlew connectedDebugAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.class=com.superheld.android.DeviceIdentityManagerInstrumentedTest
ANDROID_USER_HOME=/Users/benediktpoller/code/sh/workspace/.android \GRADLE_USER_HOME=/Users/benediktpoller/code/sh/workspace/.gradle-home \./gradlew installDebug \ -Psuperheld.baseUrl=http://127.0.0.1:8080 \ -Psuperheld.apiToken=<tenant-app-token> \ -Psuperheld.tenantId=tenant-local
adb shell am start -W -n com.superheld.android/.MainActivity6. Verifikation nach der Installation
Abschnitt betitelt „6. Verifikation nach der Installation“Nach dem Start zeigt die App den DAU-Hauptscreen. Im aktuell verifizierten Lauf wurde diese Reihenfolge erfolgreich geprüft:
- App zeigt „Start here” mit Setup-Wording-CTA zur Einrichtung
- Der CTA fuehrt zum Settings-Tab und landet zuerst auf der ruhigen Support-Uebersicht (nicht direkt in Eingabefeldern)
- DAU-Pfad: Im Bereich Account erstellen oder anmelden — die App nutzt
POST /account/registeroderPOST /account/login, speichert die Session und kehrt zur Home-Oberflaeche zurueck - Operator-Pfad: Von der Support-Uebersicht explizit in den Bereich Verbindung/Registrierung navigieren und Verbindungsdaten manuell eingeben (Service-Adresse, Zugangscode, Familien-Code)
- Geraet registrieren ueber die Support-Aktionen auf dem Settings-und-Hilfe-Screen
- Ueber den Tab „Home” in der unteren Navigation zurueck zum Hauptscreen: Status wechselt zu „Everything looks calm”; der Home-Screen zeigt keine separate Settings-/Hilfe-Karte
- Schnell-Check-Metriken zeigen Geraetestatus, Warnungen und ernste Probleme
Sichtbare Erfolgsindikatoren:
- Der Hauptscreen zeigt „Everything looks calm” mit ruhigem Hintergrundton nach erfolgreicher Einrichtung. Der Home-Screen zeigt keine separate Settings-/Hilfe-Karte; Setup und Hilfe sind ueber die Primaeraaktion oder den Tab „Settings” in der Bottom-Navigation erreichbar.
- Schnell-Check-Metriken erscheinen: Geraet geschuetzt, keine Warnungen, keine ernsten Probleme.
- Nach einem Demo-Event (ueber Support-Aktionen auf dem Settings-und-Hilfe-Screen → „Send guided test event”) wechselt der Status auf „Needs attention now” mit einer Problem-Karte in Klarsprache.
- Einrichtung und technische Details befinden sich auf dem separaten Settings-und-Hilfe-Screen. Der Hauptscreen zeigt keine separate Settings-/Hilfe-Karte; Setup und Hilfe sind nur ueber die Primaeraaktion oder den Tab „Settings” erreichbar.
Fuer den technischen Verifikationspfad mit Backend-API-Aufrufen und Telemetrie-Details siehe das Operator-Runbook.
7. Sichtbare Fehlerpfade
Abschnitt betitelt „7. Sichtbare Fehlerpfade“Die App klassifiziert Fehler in vier Kategorien mit dedizierter Guidance pro Read-/Write-Karte:
| Fehlerklasse | Typische Ursache | Beispiel-Anzeige |
|---|---|---|
Auth (unauthorized) | Ungueltiges oder abgelaufenes Token | Refresh rejected by backend authentication. |
Scope (insufficient_scope) | Token hat den benoetigten Scope nicht | Alert read was rejected due to missing scope. |
Tenant (tenant_mismatch) | App-Tenant stimmt nicht mit Token-Bindung ueberein | Trace read is using the wrong tenant context. |
Netzwerk (network_error) | Backend nicht erreichbar | Refresh could not reach the backend. |
Jede Fehlerkarte zeigt zusaetzlich run_id, Result, Backend version (wenn vorhanden) und Error code.
Verifizierte Negativlaeufe auf dem USB-Tablet:
- Scope-Fehler: Tokens ohne
events:write,alerts:read,incidents:readoderjobs:readzeigen dedizierte Scope-Guidance pro Karte plusHTTP 403 insufficient_scope - Auth-Fehler: Ein komplett ungueltiges Token zeigt
unauthorized-Guidance in allen Read-Karten (Status, Alerts, Incidents, Jobs) - Tenant-Mismatch: App-Tenant
tenant-debugmit tenant-local-gebundenem Token zeigt Mismatch-Warnung und Korrekturhinweis - Netzwerk-Fehler: Nach einem erfolgreichen Refresh verschwindet das Backend; der naechste Refresh zeigt Netzwerk-Guidance in allen Karten plus
Last successful sync-Zeitstempel - Downstream-Detailfehler: Ein einzelner
GET /incidents/{id}404 nach erfolgreichem Listenread zeigtIncident list loaded, but the latest incident detail read failed.; einGET /traces/{id}403tenant_mismatchnach erfolgreichem Job-Read zeigt Tenant-Guidance in der Trace-Karte
Alle diese Pfade sind als wiederholbare Instrumentation-Tests auf dem angeschlossenen Tablet verifiziert.
Typische Stolpersteine
Abschnitt betitelt „Typische Stolpersteine“| Problem | Wahrscheinliche Ursache | Aktueller Umgang |
|---|---|---|
cmd/server startet nicht im sicheren Modus | SUPERHELD_BOOTSTRAP_TOKEN oder SUPERHELD_BOOTSTRAP_TENANT_ID fehlt | Secure-Mux mit Bootstrap-Token starten |
| Tablet erreicht das lokale Backend nicht | adb reverse tcp:8080 tcp:8080 fehlt | Reverse erneut setzen und App mit http://127.0.0.1:8080 konfigurieren |
| Refresh wirkt erfolgreich, aber die App zeigt einen Tenant-Mismatch | Token ist an einen anderen Tenant gebunden als die in der App gesetzte tenant_id | App-Tenant auf die Token-Bindung ziehen oder ein Token fuer den beabsichtigten Tenant minten |
| Incident-Sektion bleibt leer | Es gibt aktuell noch keinen tenant-sichtbaren Incident | Nach Send Demo Event erneut Refresh Status ausfuehren; das Demo-Event erzeugt unmittelbar einen malicious_app-Incident. Bei SQLite-Persistenz bleiben Incidents auch ueber Server-Restarts erhalten |
| App zeigt beim Start alten Zustand statt „Start here” | Die App persistiert den letzten erfolgreichen Home-Snapshot lokal und stellt ihn beim naechsten Start sofort wieder her | Das ist Normalverhalten seit Commit 6a67f8d. Einen frischen Startzustand erhaelt man durch Aendern der Service-Adresse, des Zugangscodes oder des Familien-Codes auf dem Settings-Screen |
| Job-Sektion bleibt leer | Es existiert aktuell kein tenant-sichtbarer Job | Host-seitig einen kleinen Demo-Job über POST /jobs anlegen und danach erneut refreshen |
| Emulator-Befehle fehlen | SDK enthält lokal kein emulator-Binary | USB-Tablet als bevorzugten Testpfad verwenden |