Kompletter Umbau (ROADMAP_UMSETZUNG.md Phase 2). Die alte Fassung hatte vier Probleme, die den Test praktisch wertlos machten: kein festes Intervall (ein "Messpunkt" dauerte so lange wie das Ziel zufaellig antwortete — Prod #126: 38 Punkte in 300 s statt der ueblichen ~250-300), keine Zeitreihe (nur Summen), kein Foreground-Service trotz gegenteiliger Doku-Behauptung, kein Abbruchpfad. Vor allem aber: waehrend der 1-60 Minuten sah man nichts ausser "Messung laeuft ...". Nativ (NetDiagScannerPlugin.kt, MonitorService.kt) StressRun komplett neu: feste Taktung per naechstem Fixpunkt (nextTick += intervalSec*1000, kein Zeitverzug ueber eine Stunde), Rohzaehler (sentTotal/receivedTotal/rttSum/Min/Max) + echte Zeitreihe (Liste aus {ts,rtt}), Ausfallsegmente werden waehrend des Laufs erkannt und geschlossen. Laeuft im MonitorService (Foreground, wie der Geraete-Monitor) — dafuer wurde der Dienst auf eine Job-Registry umgestellt (jobId -> Text), damit ein gleichzeitig laufender Geraete-Monitor und Dauertest sich beim Beenden nicht gegenseitig die Benachrichtigung wegnehmen. Events stressSample (live, pro Probe) und stressFinished (einmalig, Grund completed/stopped) + getStressStatus zur Wiederaufnahme nach Seitenwechsel. WICHTIG geloest: laeuft der Test natuerlich aus, waehrend niemand zuhoert (App im Hintergrund, andere Seite offen), bleibt der Lauf-Eintrag in stressRuns bestehen (wie monitorRuns) statt sofort geloescht zu werden — sonst waere das Ergebnis unwiederbringlich weg. Neuer Aufraeum-Call dismissStressRun. Nebenbei: der geteilte io-Scope aller Plugin-Methoden lief bisher auf einem gewoehnlichen Job — eine unbehandelte Exception in EINER Coroutine (z.B. IP-Scan mit kaputtem Host) haette strukturell alle Geschwister-Coroutinen mitgerissen, auch einen parallel laufenden Monitor/Dauertest. Jetzt SupervisorJob + CoroutineExceptionHandler. Kritischer Bug gefunden UND gefixt (im Emulator, echter Netzausfall-Test): `.put("rtt", rtt as Any?)` mit Kotlin null wird von org.json.JSONObject behandelt wie `remove(key)` — der Schluessel verschwindet komplett statt als JSON null anzukommen. Die App bekam damit `undefined` statt `null` fuer verlorene Proben; `!== null`-Filter hielten das faelschlich fuer "erhalten". Ergebnis: ein per Flugmodus ausgeloester echter Ausfall zeigte live "0 % Verlust" und "NaN ms" bei Min/Max/Oe. Betraf NUR die Live-Anzeige — die gespeicherte Messung war unabhaengig davon korrekt, weil buildStressResult() ausschliesslich aus dem nativen Kotlin-Zustand rechnet, nie ueber die Pro-Probe-JSON-Bruecke. Fix: ueberall explizit JSONObject.NULL statt bloss `null` (betraf auch die Traceroute-Korrektur aus Phase 1). Zusaetzlich TS-seitig als zweite Verteidigungslinie `!= null` statt `!== null` (deckt sowohl null als auch undefined ab). Neu: gemeinsame Bewertung (tools/rating.ts) ping.ts und der alte Dauertest bewerteten denselben Netzzustand unterschiedlich (ping.ts: avgMs>100 -> Rot; Dauertest: nur lossPct/maxMs). rateLatency() ist jetzt die einzige Stelle: Verlust, Jitter, Latenz nach Zielklasse (LAN/WLAN/WAN) UND eine eigene Regel "jeder Ausfall > 5 s = Rot" unabhaengig vom Gesamt-Verlustprozentsatz. ping.ts umgestellt, unveraendertes Verhalten fuer die bisherigen Schwellen (inkl. Jitter>10ms, das beim Portieren fast uebersehen wurde). Neue Route statt Dialog (routes/protokoll/[id]/stresstest/) Wie IP-Test/WLAN/Monitor eine eigene Seite statt des blockierenden Werkzeug-Dialogs. Einrichtung (Ziel leer=Gateway, Dauer, Takt) mit Vorlaufprobe wie zuvor in stresstest.ts. Laufend: grosse Live-Zahl mit Ampelfarbe (rateLatency), Fortschrittsbalken mit Restzeit, Streifendiagramm (StressChart.svelte, live rollierendes 120s-Fenster), Zaehler gesendet/verloren/Ø/Min/Max, offener-Ausfall-Banner, Ereignisliste mit Uhrzeit ("Ausfall — wieder da nach 16 s"), Abbrechen. Abgeschlossene Laeufe darunter aufklappbar mit demselben Diagramm (kompletter Verlauf statt Fenster). stresstest.ts (Tool-Registry-Eintrag) ist jetzt nur noch Namens-Lookup fuer die Messungen-Liste, run() wirft bewusst einen Fehler, falls doch noch etwas den alten Weg aufruft. Sicherheitsnetz gegen verpasste Events (lib/stresstest.ts) Ein natuerlich beendeter Test, waehrend niemand auf der Stresstest-Seite ist, verpasst dort das stressFinished-Event. Die Hauptprotokollseite prueft deshalb beim Oeffnen zusaetzlich per resumeFinishedStressSessions() nach (praktisch immer besucht, bevor ein Protokoll abgeschlossen wird) und traegt das Ergebnis nach. Bekannter Rest-Fall (dokumentiert): verlaesst der Techniker das Protokoll komplett ohne eine der beiden Seiten noch einmal zu oeffnen, bleibt der fertige Lauf bis zum naechsten Besuch liegen. Ergebnis-Speicherung: Zeitreihe in 1-Minuten-Buckets + Ausfallsegmente + laengster Ausfall als Measurement (tool=stresstest, sync-faehig) — Ausfaelle werden beim Abschliessen mit dem nativen (autoritativen) Ergebnis abgeglichen, nicht nur mit der lokal live mitgefuehrten Kopie. Getestet im Emulator (Pixel 6 / Android 14): - 1-Minuten-Lauf komplett bei ausgeschaltetem Display durchgelaufen (Foreground-Service haelt den Prozess), automatischer Abschluss + Toast - Echter Netzausfall per Flugmodus (15s) waehrend laufendem 5-Minuten-Test: korrekt 23,2%/16,7% Verlust, Min/Max ohne NaN, Ereignisliste mit exakter Uhrzeit und Dauer — nach dem NULL-Fix verifiziert - Abbrechen-Pfad: sofortiger Stopp, korrektes Teil-Ergebnis - Wiederaufnahme: laufender Test nach APK-Neuinstallation (Prozess-Kill) korrekt als beendet erkannt - gradle compileDebugKotlin ok, svelte-check 0 Fehler Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| android | ||
| native-plugin | ||
| src | ||
| .gitignore | ||
| capacitor.config.ts | ||
| package.json | ||
| README.md | ||
| svelte.config.js | ||
| tsconfig.json | ||
| vite.config.ts | ||
NetDiag — Diagnose-App (Android)
Mobile Netzwerk-Diagnose-App. Erfasst vor Ort beim Kunden (Handy am WLAN oder
USB-C→RJ45-Adapter) Geräte, Ports und Messungen und hängt die Protokolle ans
Dolibarr-Modul netdiag an Kunde und Auftrag.
Stack
SvelteKit 2 · Svelte 5 · Tailwind 4 · Vite 7 · Capacitor 6 · SQLite-Offline
Entwicklung (Browser)
npm install
npm run dev # http://localhost:5175
Im Browser liefert ein Mock (src/lib/scanner.ts) Beispiel-Scandaten — die
Oberfläche lässt sich ohne Gerät entwickeln. API-Aufrufe gehen über den
Vite-Proxy an den Dolibarr-Testserver (192.168.155.11, siehe vite.config.ts).
Android-Build
npm run build
npx cap add android # einmalig
# android/ liegt komplett im Repo — cap sync kopiert nur die Web-Assets
npx cap sync android
npx cap open android
Release-APK über CI: Commit mit [apk] in der Message → Forgejo baut und lädt
die APK in die Package Registry (netdiag-apk). Siehe .forgejo/workflows/build.yml.
Architektur
src/lib/
api.ts JSON-API-Client (JWT, 401-Refresh, Timeout)
auth.svelte.ts Anmelde-Status
db.ts Offline-Speicher (SQLite nativ / localStorage Browser)
sync.svelte.ts Sync-Queue -> Dolibarr (idempotent über clientUuid)
scanner.ts Brücke zum nativen Plugin (+ Browser-Mock)
backButton.svelte.ts Hardware-Back (Single-Instance, KB #480/#549)
updater.ts APK-Auto-Update-Prüfung (KB #363)
tools/ erweiterbare Tool-Plattform
index.ts Registry — neues Tool hier eintragen
netzwerk/ IP-Scan, Port, Ping, IP-Konflikt, SNMP, Traceroute, Stress
internet/ Durchsatz-Test
telefonie/ (folgt: SIP, FreePBX, RTP)
src/routes/
login/ auftraege/ kunden/ protokoll/[id]/ einstellungen/
android/ natives Android-Projekt inkl. Kotlin-Plugin (einzige Quelle)
native-plugin/ nur noch Anleitung/Hinweise zum Plugin
Neues Tool hinzufügen
- Datei unter
src/lib/tools/<kategorie>/<id>.tsanlegen,Toolimplementieren. - In
src/lib/tools/index.tsimportieren und inTOOLSeintragen.
Kein Eingriff in App-Logik, Sync oder Datenbank — das Ergebnis ist generisches JSON. Braucht das Tool eine neue native Messroutine, eine Methode im Kotlin-Plugin ergänzen.
Bedienung
- Anmelden (Dolibarr-Zugang; auf dem Gerät zusätzlich Server-URL).
- Aufträge — aktive direkt sichtbar, abgeschlossene per Checkbox, Suche. Alternativ über Kunden suchen.
- Auftrag/Kunde antippen → Diagnose-Protokoll öffnet sich.
- Werkzeuge ausführen (IP-Scan füllt die Geräteliste, je Gerät weitere Tools).
- Abschließen & synchronisieren — Protokoll geht ans Dolibarr, PDF landet im ECM. Offline bleibt es lokal und synct automatisch bei Verbindung.