Per explizitem Nutzerwunsch die "Port freimachen?"-Abfrage samt allen
Warnungen aus dem LAN-Schritt des Wizards auch auf den Experte-Tab
angewendet, ausgeloest durch echten Live-Fall (ether4 wurde manuell
ueber Expert als eigenes Netz angelegt, blieb dabei unbemerkt Bridge-
Mitglied - zwei DHCP-Server im selben Broadcast-Domain).
PortConflictWarningView aus LanStepView.swift in Features/Shared/
extrahiert (jetzt von Wizard UND Experte-Tab genutzt), neuer
immediateApply-Parameter fuer die kontextabhaengige Abschluss-Meldung
(Wizard: erst bei "Jetzt anwenden"; Experte: sofort bei "Anlegen"/
"Speichern"). Neue PortConflict.resolutionCommandsIncludingBridgeDetach()
- der Experte-Tab hat anders als der Wizard keinen separaten,
automatischen Bridge-Detach-Schritt, muss die Bridge-Entfernung also
selbst mit auflisten.
ExpertViewModel bekommt dieselbe Race-sichere Generation-Zaehler-Logik
wie SetupViewModel (bugs.md #1), angewendet auf das .interfacePick-Feld
des jeweils offenen Schemas. Speichern-Button gesperrt bis Konflikt
bestaetigt oder Port gewechselt.
6 neue Regressionstests. Build + alle 111 Unit-Tests gruen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Race Condition bei LAN-Port-Konflikt-Prüfung (Generation-Zähler), Firewall-Titel
widersprach sich im Einfach-Modus, 2 fehlende EN-Übersetzungen, Health-Check-
Herzschlag ignorierte laufende Wizard-/Experte-Schreibvorgänge. Außerdem M7/M9
im README/HANDOFF auf fertig aktualisiert (Modusschalter+Experte-Zweig liefen
bereits über die Multi-LAN/WLAN-Live-Tests).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Neues Schema für /system routerboard mode-button (enabled/on-event/
hold-time), live gegen echte Hardware verifiziert.
Dabei drei echte Bugs gefunden und gefixt:
- SSH-Trust-Dead-End beim ersten Experte-Tab-Schreiben (Backup-vor-
Schreiben-Pfad hatte keinen Weg, den Trust-Dialog auszulösen) —
ConnectionService.noteUntrustedSSHHostKey
- RouterOSFieldSchema.clearable: optionale Felder senden nie mehr
einen expliziten Leer-Wert, wenn das RouterOS ablehnt
- RouterOSMenuSchema.writesRequireSSH + ConnectionService.applyViaSSH:
für Menüs ohne REST-Anbindung (bewiesen per direktem SSH-Test) wird
zwingend eine dedizierte SSH-Verbindung genutzt statt REST
Live Ende-zu-Ende bestätigt: Skript anlegen, Mode-Taste zuweisen,
Tastendruck löst Skript korrekt aus.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Gleiche Ursache wie Bug 26, aber bei einem kuratierten statt einem
unkuratierten Feld: eine dynamische/verbundene Route hat distance=0,
RouterOS akzeptiert das nur system-intern, nicht als expliziten Eingabe-
wert für "set" — auch wenn der Wert unverändert zurückgesendet wird
("value of distance out of range (1...255)").
Fix generalisiert das "nur bei Änderung senden"-Prinzip aus Bug 26 von
unkuratierten auf ALLE Felder beim Bearbeiten eines bestehenden Items:
pendingCommand diffed jetzt gegen das ursprünglich geladene Item, statt
kuratierte Felder immer komplett neu zu senden. Deckt implizit auch das
Leeren eines Feldes ab (Bug 25), dessen Sonderfall dadurch überflüssig
wurde und entfernt ist.
Nebenbei: ExpertViewModelTests.swift lief bisher gar nicht mit, weil
nach dem Anlegen der Datei kein "xcodegen generate" lief (Xcodegen
erzeugt die Sources-Dateiliste einmalig beim Generieren). Nach erneutem
Generate 58 Unit-Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
Beide Bugs in ExpertViewModel.pendingCommand, betreffen Experte-Tab
direkt (nicht nur den neuen Übersicht-Bearbeiten-Weg):
- Bug 25: ein geleertes Textfeld (z.B. Kommentar löschen) wurde beim
Speichern aus den Argumenten gefiltert statt explizit als "" gesendet
— RouterOS' `set` ändert nur übergebene Parameter, ein weggelassener
bleibt unangetastet statt geleert. Fix: Feld bleibt im Argument-Set,
wenn es vorher einen Wert hatte; RouterOSCommand's SSH-Zeilen-Rendering
gibt einen leeren Wert jetzt als `""` statt als nacktes `feld=` aus.
- Bug 26: eine Route bearbeiten (z.B. nur Kommentar ändern) scheiterte
mit "bad parameter immediate-gw" — dieses von RouterOS mitgelieferte,
nur lesbare/berechnete Feld landete unkuratiert in den freien
"Weiteren Parametern" und wurde bei jedem Speichern blind
mitgeschickt. Fix: ein unkuratiertes Feld wird nur noch gesendet, wenn
sein Wert sich gegenüber dem ursprünglich geladenen Item tatsächlich
geändert hat.
54 Unit-Tests grün (neue ExpertViewModelTests + eine Ergänzung in
RouterOSCommandBuilderTests).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YDmUd93KxsYGr2kLTotWnG
M9: Einrichten-Wizard bekommt einen Einfach/Experte-Modusschalter
(ModeStepView). Einfach überspringt VLAN, erlaubt nur ein LAN-Netzwerk
ohne Isolation, Firewall-Grundschutz fest an.
M10: neuer "Experte"-Tab mit generischem Motor (RouterOSMenuItem,
RouterOSCommand.remove, ConnectionService.fetchMenuItems, freies
"eigener Menüpfad"-Feld) plus kuratierten Formularen mit Tooltips
(RouterOSSchemaCatalog) für Firewall/NAT/Mangle/Raw/Adress-Listen,
Interfaces, IP, VPN, WLAN, Queues, System, Werkzeuge.
Live gegen einen hEX-Testrouter verifiziert (erst per SSH, dann vom
Nutzer selbst in der App), dabei 7 reale Bugs gefunden und gefixt —
der wichtigste: RouterOS' SSH-CLI gibt bei fehlgeschlagenen Befehlen
Exit-Code 0 zurück, wodurch apply() app-weit Fehler verschluckte statt
sie zu melden. Danach ergänzt: Bestätigungsdialog vor Anlegen/Ändern
+ Auto-Backup vor dem ersten Experte-Tab-Schreibvorgang je Sitzung
(Angleichung an den Wizard), sowie ein Dauer-Editor (Tage/Std/Min/Sek)
für Lease-/Ablaufzeit-Felder statt Freitext.
Details zu allen Bugs/Fixes: HANDOFF.md, CHATLOG.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EW3r6rW1xCf6UT5jNvt6rn