M14: Update-Check (Software+Firmware) + Karten-Design fuer Sektionen

Verbinden-Tab zeigt jetzt die volle Routerboard-Info (Modell/Revision/
Seriennummer/Firmware, aus /system routerboard) sowie einen
RouterOS-Software-Update-Check (/system package update: Kanal/
installierte/neueste Version/Status, "Jetzt pruefen"/"Update
installieren"), dazu "Firmware aktualisieren" fuer die
Routerboard-Bootloader-Firmware und "Jetzt neu starten" danach. Alle
vier Aktionen live bestaetigt, inklusive der zuvor unsicheren Frage, ob
/system routerboard upgrade's normalerweise interaktive Bestaetigung
den nicht-interaktiven SSH-Weg dieser App blockiert (tut es nicht).

Bug 20 gefunden und gefixt: fetchMenuItems' Singleton-Fallback (Bug 8)
reagierte nur auf eine geworfene Exception fuer "bad parameter terse",
aber RouterOS liefert diesen Fehler fuer /system routerboard mit
Exit-Code 0 zurueck (dasselbe Bug-10-Muster, diesmal beim Lesen statt
Schreiben) - die Routerboard-Sektion blieb dadurch leer, ohne Fehler.
Fix: zusaetzlich den Output-Text selbst pruefen, nicht nur die Exception.

Design-Durchgang: Verbinden-Detailseite/Sicherungen/Geraete liefen auf
nackter List ohne Rahmen - umgestellt auf Form+.formStyle(.grouped),
denselben nativen macOS-Karten-Look, den Wizard und Experte-Tab schon
hatten, fuer eine einheitliche App. Dark Mode auf Nachfrage gepueft und
ohne Codeaenderung bestaetigt funktionierend.

HANDOFF.md/CHATLOG.md aktualisiert: M14, Bug 20, Design-Durchgang,
Dark-Mode-Bestaetigung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CTgRxJTzaQwaRkngbaE1GJ
This commit is contained in:
Kay
2026-09-14 16:34:50 +02:00
co-authored by Claude Sonnet 5
parent 20f8d5e0bf
commit e72da84843
10 changed files with 629 additions and 27 deletions
+78 -7
View File
@@ -34,8 +34,27 @@ Bugs, 1417) und M13 (ein besonders ernster Bug, 18: erster Testlauf
sperrte den Router komplett aus, nur per Hardware-Reset behebbar) beide
zäher als erwartet, am Ende aber jeweils vom Nutzer selbst bestätigt
("das funktioniert jetzt super" / "das hat sofort funktioniert" / "gut,
das hat funktioniert"). Release-Build unter
`/Applications/RouterOS Assistant.app` ist auf aktuellem Stand.
das hat funktioniert").
**Danach, gleiche Session, M14 "Update-Check":** Verbinden-Tab zeigt jetzt
volle Routerboard-Daten (Modell/Revision/Seriennummer/Firmware, aus
`/system routerboard`) und einen RouterOS-Software-Update-Check
(`/system package update`: Kanal/installierte/neueste Version/Status,
"Jetzt prüfen", "Update installieren"), plus "Firmware aktualisieren"
für die Routerboard-Bootloader-Firmware und einen "Jetzt neu starten"-
Button danach — alle vier Aktionen live bestätigt, inkl. der zuvor
unsicheren Frage, ob `/system routerboard upgrade`s normalerweise
interaktive Bestätigung den nicht-interaktiven SSH-Weg dieser App
blockiert (tut es nicht, lief sauber durch). Dabei ein weiterer Bug im
generischen Lese-Pfad gefunden (Bug 20, siehe unten). Anschließend ein
Design-Durchgang: Verbinden-Detailseite/Sicherungen/Geräte liefen auf
nackten `List`s ohne Rahmen — umgestellt auf `Form`+`.formStyle(.grouped)`,
denselben nativen macOS-"Karten"-Look, den Wizard und Experte-Tab schon
die ganze Zeit hatten. Dark Mode auf Nachfrage geprüft: funktioniert ohne
Codeänderung (keine `.preferredColorScheme`-Überschreibung, keine feste
Farbwerte, alles adaptive System-Farben) — vom Nutzer live bestätigt.
Release-Build unter `/Applications/RouterOS Assistant.app` ist auf
aktuellem Stand.
## Ziel
@@ -106,8 +125,9 @@ RouterOSAssistant/
BackupService.swift — Config-Export (`/export terse`) über eigene SSH-Verbindung, wählbarer Zielordner, restoreBackup (M13: SFTP-Upload + reset-configuration+run-after-reset + Login-Erhalt), backupModel (Modell-Header-Parsing)
FactoryResetService.swift — /system reset-configuration über eigene SSH-Verbindung ("Gefahrenzone")
KeychainService.swift — Passwort-Speicherung
UpdateService.swift — M14: RouterOS-Software-Update (/system package update check-for-updates/install) + Routerboard-Firmware (upgrade) + reboot, eigene SSH-Verbindung
Features/
Wizard/Steps/Connect/ — Verbinden-Tab (inkl. Schnell-Backup-Button nach erfolgreicher Verbindung)
Wizard/Steps/Connect/ — Verbinden-Tab (inkl. Schnell-Backup-Button, Routerboard-Info, Software-/Firmware-Update-Check (M14), nach erfolgreicher Verbindung)
Wizard/Steps/Setup/ — Einrichten-Tab: Mode → Wan → Lan → (Vlan nur Experte) → Wifi → Firewall → Review/Apply
Expert/ — Experte-Tab (M10): ExpertView (Kategorie-/Menüliste + "eigener Pfad"), ExpertViewModel, ExpertMenuDetailView (Item-Liste + Add/Edit-Sheet)
Overview/ — Übersicht-Tab (M11): OverviewView (Diagramm+Legende+Detailpanel), OverviewViewModel (buildGraph, rein), OverviewLayout (Spalten/Zeilen-Geometrie)
@@ -343,6 +363,21 @@ erreichen (siehe Bug 1 unten).
Views mit vielen `.alert`/`.confirmationDialog`/`.sheet`-Modifiern in
Folge vorbeugend gleich aufteilen, statt erst bei diesem Fehler zu
reagieren.
20. **`fetchMenuItems`s Singleton-Fallback (Bug 8/M10) griff für
`/system routerboard` nicht — genau dasselbe Bug-10-Muster, nur an
einer Lesestelle statt beim Schreiben.** Die neue Routerboard-Sektion
(M14) blieb leer, kein Fehler, nichts. Ursache: der Fallback reagiert
bisher nur auf eine echte Exception ("bad parameter terse" via
Citadels `CommandFailed`), aber `/system routerboard print terse`
liefert diesen Fehlertext live bestätigt mit Exit-Code 0 zurück — der
Fehlertext landete also als normaler (unparsbarer) Output, `fetchMenuItems`
gab still `[]` zurück statt in den Singleton-Zweig zu fallen. Fix:
zusätzlich den zurückgegebenen Output-Text selbst auf "bad parameter
terse" prüfen, nicht nur die Exception — deckt beide Varianten ab, wie
RouterOS diesen Fehler je nach Menü meldet. Betrifft potenziell jedes
Singleton-Menü, nicht nur `/system routerboard` — der generische
Lese-Pfad wird von Übersicht-, Geräte- und Experte-Tab gemeinsam
genutzt.
**Lehren:** Citadel/NIOSSH-Fehler immer mit `String(describing:)` loggen,
nie `.localizedDescription`. Jede View, die ein ObservableObject aus einem
@@ -392,7 +427,14 @@ ersten Fehler irgendwo im Skript komplett ab. **SwiftUI-Typprüfung kann
bei langen Modifier-Ketten mit einer irreführenden Fehlerzeile
timeouten** (Bug 19) — kein Hinweis auf einen echten Logikfehler an der
genannten Stelle; bei vielen `.alert`/`.confirmationDialog` in Folge
vorbeugend in eigene `@ViewBuilder`-Properties aufteilen.
vorbeugend in eigene `@ViewBuilder`-Properties aufteilen. **"RouterOS'
Exit-Code ist kein verlässliches Erfolgssignal" (Bug 10) gilt auch für
Lesebefehle, nicht nur fürs Schreiben** (Bug 20) — derselbe
Singleton-Fallback, der für ein Menü per Exception ausgelöst wurde
(Bug 8), blieb für ein anderes Menü aus, weil RouterOS denselben
Fehlertext dort mit Exit-Code 0 zurückgibt; robuste Erkennung muss immer
auch den Output-Text selbst prüfen, nie nur auf eine geworfene Exception
vertrauen.
## `xcodebuild test` hängt — Gatekeeper, kein Code-Bug
@@ -677,6 +719,25 @@ beim Ändern die RouterOS-Suffix-Form zurück) — angewendet auf DHCP-Server
(Login-Erhalt vorangestellt) danach vom Nutzer bestätigt ("das hat
funktioniert"). Restore-Weg selbst (Modell-Match, SFTP-Upload,
reset+run-after-reset) lief dagegen schon im ersten Versuch fehlerfrei.
- ✅ M14: Update-Check im Verbinden-Tab — Routerboard-Vollinfo
(`/system routerboard`: Modell/Revision/Seriennummer/Firmware-Typ/
Firmware-Versionen), RouterOS-Software-Update-Check
(`/system package update`: Kanal/installiert/neueste Version/Status,
"Jetzt prüfen"+"Update installieren"), Routerboard-Firmware-Update
("Firmware aktualisieren") und "Jetzt neu starten" danach. **Alle vier
Aktionen live gegen Hardware verifiziert**, inkl. der zuvor offenen
Frage, ob `/system routerboard upgrade`s normalerweise interaktive
Bestätigung ("Do you really want to upgrade firmware? [y/n]") den
nicht-interaktiven SSH-Weg dieser App blockiert — tut es nicht,
Firmware-Update lief beim ersten Versuch sauber durch ("Firmware
upgraded successfully, please reboot..."), ebenso der Neustart danach.
Dabei ein weiterer Bug im generischen Lese-Pfad gefunden (Bug 20).
Anschließend Design-Durchgang: Verbinden-Detailseite/Sicherungen/
Geräte von nackter `List` auf `Form`+`.formStyle(.grouped)`
(macOS-typischer "Karten"-Look) umgestellt, damit einheitlich mit
Wizard/Experte-Tab. Dark Mode auf Nachfrage geprüft und ohne
Codeänderung bestätigt funktionierend (keine feste Farbwerte/
Appearance-Überschreibung im Code).
## Nächste Schritte
@@ -717,9 +778,19 @@ beim Ändern die RouterOS-Suffix-Form zurück) — angewendet auf DHCP-Server
nicht mehr — **nicht mehr relevant, nicht danach suchen.** Aktueller
Stand: `Kay-Uwes-iMac` an ether2 und Test-Laptop `DEDELLB2M6GK3` an
ether3, beide dynamisch, plus was auch immer die zuletzt erfolgreich
getestete Backup-Wiederherstellung zurückgespielt hat — vor
Annahmen über den genauen aktuellen Stand lieber neu per Geräte-/
Übersicht-Tab prüfen statt auf ältere Einträge hier zu vertrauen.
getestete Backup-Wiederherstellung zurückgespielt hat, und die
Routerboard-Firmware wurde per M14 aktualisiert (Neustart ausgeführt)
— vor Annahmen über den genauen aktuellen Stand lieber neu per
Geräte-/Übersicht-/Verbinden-Tab prüfen statt auf ältere Einträge hier
zu vertrauen.
10. **`fetchMenuItems`s Output-Text-Fallback (Bug 20) auf weitere
Singleton-Menüs prüfen** — live nur für `/system routerboard`
bestätigt gebraucht zu werden (`/system identity` etc. liefen schon
vorher über den Exception-Zweig, siehe Bug 8). Nicht geprüft, ob es
noch andere Menüs gibt, die den Fehler auf eine DRITTE Art melden
(weder Exception noch im Output-Text) — bei einer leer bleibenden
Liste in Übersicht/Geräte/Experte-Tab als erste Verdachtsquelle
prüfen.
Kein Gitea-Remote vorhanden — falls der Nutzer später eine Gitea-Instanz
aufsetzt (z.B. selbst gehostet auf der vorhandenen OMV-NAS, siehe