M26: SavedRouter bekommt ein optionales serialNumber-Feld. Zwei
physisch verschiedene Router mit identischem Host+Benutzername
(Werks-Adresse) blieben bisher ein gemeinsamer "Bekannte Router"-
Eintrag; recordSuccessfulConnection matcht jetzt zusätzlich nach
Seriennummer, mit sauberer Migration bestehender Einträge ohne
Seriennummer. Drei neue Tests.
M27, beim Live-Test von M26 gefunden:
- Passwort-Anzeige-Button (Augen-Symbol) im Verbinden-Tab
- Bug 35: KeychainService speicherte Passwörter nur nach
"username@host" — beide Router teilten sich denselben
Schlüsselbund-Eintrag trotz getrennter SavedRouter-Einträge. Fix:
optionaler serialNumber-Parameter qualifiziert den Account-Key,
mit Fallback auf den alten Key für bereits gespeicherte Passwörter.
- Bug 36: neuer Router zeigte keine Routerboard-Infos/Seriennummer —
derselbe Root Cause wie der zuvor gemeldete "Jetzt prüfen"-Fehler:
/system routerboard und /system package update scheitern auf diesem
Router mit "expected end of command" statt dem bisher einzig
abgefangenen "bad parameter terse". SSHTransport.fetchMenuItems
erkennt jetzt beide Formulierungen.
Alles live bestätigt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Der Aktionen-Button (M24) ersetzte den Rechtsklick im Code, aber ein
App-eigener Warnhinweis (Feste-IP-Bestätigung) und README.md/Manual.md
(DE+EN) verwiesen weiterhin auf Rechtsklick. Gefunden durch Nutzer-
Hinweis nach Prüfung auf Gitea.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Rechtsklick-Kontextmenü ersetzt durch sichtbaren "Aktionen"-Button
je Geräte-Zeile (bisher nicht diskoverbar)
- Live-Traffic pro Port (↓/↑, wiederverwendet InterfaceTrafficMonitor)
plus kleines Sparkline-Liniendiagramm der letzten 10 Sekunden
(Swift Charts, neuer TrafficSample-Typ)
- Bug 34: ARP-Tabelle kann mehrere Zeilen für dieselbe MAC halten
(reachable + stale/failed) — Auflösung bevorzugte bisher blind die
zuletzt gesehene Zeile statt die erreichbare. Zwei Regressionstests.
- Nebenbefund: dedizierte SSH-Dienste (Backup/NetworkTools/Traffic/
Update/FactoryReset) haben keinen eigenen Bestätigungspfad für einen
neuen SSH-Host-Key, scheitern still solange REST verbindet — als
offener Punkt dokumentiert.
Alles live bestätigt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
WireGuard-Peer "Keepalive", Scheduler "Intervall" und Netwatch
"Prüf-Intervall" nutzen jetzt RouterOSFieldSchema.Kind.duration statt
Freitext. Netwatch-Default von "00:00:10" auf "10s" umgestellt, da
DurationFieldEditor.parse nur das Suffix-Format versteht, kein
HH:MM:SS. Vorher live geprüft, dass RouterOS das Suffix-Format bei
allen drei Feldern akzeptiert. Live bestätigt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Vorher kein Weg aus dem Wizard außer schrittweise "Zurück" bis zu
Modus. Zentral als Toolbar-Button in SetupView (nicht pro Schritt
dupliziert), mit Bestätigungsdialog gegen Datenverlust, deaktiviert
während eines laufenden Apply. SetupViewModel.finish() in gemeinsame
resetToInitialState() plus benannte finish()/cancel()-Wrapper
aufgeteilt. Live bestätigt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Einrichten-Wizard (alle sieben Schritte), Übersicht, LAN-Scanner,
Sicherungen laufen jetzt über L10n.t statt fester deutscher
String-Literale — Experte- und Verbinden-Tab waren bereits vorher
umgestellt (M16/M17). Model-Layer-Strings werden am Verwendungsort
gewrappt, ViewModel-generierte Laufzeitstrings (Fehlermeldungen,
CLI-Zeilen, Log) bleiben bewusst unübersetzt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tab "Geräte" -> "LAN-Scanner", Refresh-Button "Neu scannen" + prominenter
Stil. Neues Netzwerk-Tools-Menü: Ping/Traceroute/DNS-Auflösung über
NetworkToolsService (eigene SSH-Verbindung, wie Backup/InterfaceTraffic-
Monitor), mit Zeichen-Validierung gegen Command-Injection ueber einen
boeswilligen DHCP-Hostnamen. Port-Scan laeuft direkt von diesem Mac ueber
Network.framework (RouterOS hat kein eingebautes Portscan-Tool) - dabei
einen echten NWConnection-Bug gefunden (verweigerte Verbindung meldet sich
ueber .waiting, nicht .failed) und per Unit-Test gegen einen Loopback-Port
aufgedeckt und gefixt.
Zusaetzlich: Warnhinweis bei "Feste IP zuweisen" erklaert jetzt den
Rueckweg. DE/EN-Umschalter zeigt Landesflaggen statt Text.
92 Tests gruen. HANDOFF.md/README.md (inkl. Mermaid-Diagramm)/Manual.md/
CHATLOG.md aktualisiert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
M17: "Bekannte Router" im Verbinden-Tab (SavedRouter/SavedRoutersStore),
Standort-Freitextfeld, Scroll-Cap ab 4 Einträgen. Bugfix: Umbenennen-
TextField steckte in einem sich selbst deaktivierenden Button.
M18: Live-Traffic-Punkt an Interfaces (InterfaceTrafficMonitor, eigene
SSH-Verbindung, monitor-traffic-Polling). Dabei zwei reale CLI-Parser-Bugs
gefunden und gefixt: running/disabled-Flags werden als Buchstaben vor dem
ersten Feld codiert, nicht als key=value; monitor-traffic liefert
"50.7kbps" statt einer reinen Zahl.
M19: Übersicht-Tab — animierte Flussrichtung auf allen Verbindungslinien
(TimelineView+dashPhase), frei verschiebbare Knoten mit Live-folgenden
Linien, Zurücksetzen-Button.
Zusätzlich (noch nicht live getestet, nur Build+Unit-Tests grün):
LAN-Port-Konflikt-Prüfung im Einrichten-Assistenten mit doppelter
Sicherheitsbestätigung, "Fertig"-Button nach erfolgreichem Anwenden.
82 Tests grün. HANDOFF.md/README.md/Manual.md/CHATLOG.md aktualisiert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
.environment(\.locale) + Localizable.xcstrings schaltete Text(LocalizedStringKey)
live nachweislich nicht um. Ersetzt durch Core/Localization/L10n.swift
(Dictionary-Lookup je AppStorage("appLanguage")), Umschalt-Button in der Toolbar.
Vollständig übersetzt: alle Tab-Namen, alle Menü-Kategorien, kompletter
Experte-Tab inkl. Firewall-Formulare. 60 Tests grün, live bestätigt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG