forked from kay/RouterOS
Handoff aktualisiert: M5-Stand, neues .set-Architekturprinzip
Reflektiert den WLAN-Schritt, die erweiterte RouterOSCommand-Operation (.add/.set) und die noch fehlende Verifikation gegen echte WLAN-Hardware. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HReLXMbmPvtQ23p1iWiJNW
This commit is contained in:
+43
-20
@@ -1,13 +1,16 @@
|
||||
# RouterOS Assistant — Handoff
|
||||
|
||||
Stand: nach M4 (VLAN-Schritt), alle Milestones M1–M4 gegen ein echtes
|
||||
physisches Mikrotik-Testgerät (RouterOS 7.24.2) verifiziert.
|
||||
Stand: nach M5 (WLAN-Schritt). M1–M4 gegen ein echtes physisches
|
||||
Mikrotik-Testgerät (RouterOS 7.24.2) verifiziert; M5 ist gebaut und
|
||||
getestet (Build + Unit-Tests grün), aber noch **nicht gegen echte
|
||||
WLAN-Hardware verifiziert** — unklar, ob das Testgerät überhaupt einen
|
||||
WLAN-Chip hat.
|
||||
|
||||
## Ziel
|
||||
|
||||
Native macOS-App (SwiftUI), die Laien per geführtem Interview-Wizard durch
|
||||
die häufigsten Mikrotik-RouterOS-Konfigurationen führt: Internet-Anschluss,
|
||||
Heimnetzwerk/DHCP, zusätzliche VLAN-Netzwerke, (geplant: WLAN, Firewall).
|
||||
Heimnetzwerk/DHCP, zusätzliche VLAN-Netzwerke, WLAN, (geplant: Firewall).
|
||||
Vollständiger Plan/Kontext: `~/.claude/plans/purrfect-puzzling-bunny.md`
|
||||
(ursprüngliche Architekturentscheidung — seither an mehreren Stellen
|
||||
weiterentwickelt, siehe unten).
|
||||
@@ -40,8 +43,8 @@ RouterOSAssistant/
|
||||
App/RouterOSAssistantApp.swift — 3 Tabs, teilen sich EINE ConnectionService-Instanz
|
||||
Core/
|
||||
Models/
|
||||
RouterOSCommand.swift — eine Änderung, zwei Renderer (CLI-Zeile / REST-JSON)
|
||||
WanConfig.swift, LanDhcpConfig.swift, VlanEntry.swift — bauen je RouterOSCommand-Listen
|
||||
RouterOSCommand.swift — eine Änderung, zwei Operationen (.add/.set), zwei Renderer (CLI-Zeile / REST-JSON)
|
||||
WanConfig.swift, LanDhcpConfig.swift, VlanEntry.swift, WifiNetworkConfig.swift — bauen je RouterOSCommand-Listen
|
||||
DhcpServerCommandBuilder.swift — geteilte "Adresse+Pool+Server+Netzwerk"-Logik (LAN + VLAN)
|
||||
RouterOSModels.swift — Credentials, DeviceInfo, Interface, RouterOSError
|
||||
Networking/
|
||||
@@ -56,16 +59,23 @@ RouterOSAssistant/
|
||||
KeychainService.swift — Passwort-Speicherung
|
||||
Features/
|
||||
Wizard/Steps/Connect/ — Verbinden-Tab
|
||||
Wizard/Steps/Setup/ — Einrichten-Tab: Wan → Lan → Vlan → Review/Apply
|
||||
Wizard/Steps/Setup/ — Einrichten-Tab: Wan → Lan → Vlan → Wifi → Review/Apply
|
||||
Backup/ — Sicherungen-Tab
|
||||
RouterOSAssistantTests/ — reine Unit-Tests (Command-Builder, CLI-Parser, Fallback-Logik via Mock-Transport)
|
||||
```
|
||||
|
||||
**Wichtiges Architekturprinzip:** `RouterOSCommand` unterstützt nur "add"
|
||||
(CLI: `... add key=value ...`, REST: `POST`). Kein "set"/PATCH auf
|
||||
bestehende Einträge — deshalb hat der VLAN-Schritt keine Port-Zuweisung
|
||||
(Access/Trunk), das bräuchte RouterOS Bridge-VLAN-Filtering mit `set`.
|
||||
Mit dem Nutzer abgestimmt, bewusste Scope-Entscheidung.
|
||||
**Wichtiges Architekturprinzip (seit M5 erweitert):** `RouterOSCommand`
|
||||
kennt zwei Operationen: `.add` (neuer Eintrag — CLI `... add key=value`,
|
||||
REST `POST`) und `.set` (bestehenden Eintrag ändern, per `matchField`/
|
||||
`matchValue` gefunden — CLI `... set [find field=value] key=value` löst
|
||||
das inline, REST muss dafür erst per GET das Item suchen, seine
|
||||
RouterOS-interne `.id` auslesen, dann `PATCH restPath/<id>` schicken,
|
||||
siehe `RestTransport.findItemID`). Eingeführt für M5 (WLAN), weil
|
||||
Wireless-Interfaces schon vor jeder Konfiguration existieren — kein
|
||||
"add" möglich. VLAN (M4) hat trotzdem weiterhin keine Port-Zuweisung
|
||||
(Access/Trunk): das bräuchte zusätzlich RouterOS Bridge-VLAN-Filtering,
|
||||
technisch jetzt machbar, aber bewusst nicht rückwirkend nachgezogen
|
||||
(Scope-Entscheidung, nicht mehr Architektur-Zwang).
|
||||
|
||||
**ConnectionService ist der einzige geteilte State.** Alle drei Tabs
|
||||
bekommen dieselbe Instanz von der App-Ebene injiziert (kein
|
||||
@@ -120,11 +130,22 @@ selbst separat als `@ObservedObject` halten.
|
||||
- **Kein garantiertes Auto-Rollback** bei Verbindungsabbruch während
|
||||
"Jetzt anwenden" — nur Backup-vorher + Bestätigungspflicht. Steht auch
|
||||
im UI-Text auf dem Übersichtsschritt.
|
||||
- **VLAN ohne Port-Zuweisung** (siehe oben, Architekturprinzip).
|
||||
- **VLAN ohne Port-Zuweisung** (siehe oben, Architekturprinzip) — bewusste
|
||||
Scope-Entscheidung, nicht mehr technisch erzwungen.
|
||||
- **REST-Pfad ungetestet für Schreibvorgänge** — beim Testgerät ist
|
||||
`www-ssl` (Port 443) aus, daher lief jeder bisherige Schreibtest über
|
||||
SSH. Der REST-`apply()`-Pfad (`POST` mit JSON-Body) ist nur gegen Mocks
|
||||
getestet, nicht gegen ein echtes Gerät mit aktiver REST-API.
|
||||
SSH. Der REST-`apply()`-Pfad (`POST`/`PATCH` mit JSON-Body,
|
||||
`findItemID` für `.set`) ist nur gegen Mocks getestet, nicht gegen ein
|
||||
echtes Gerät mit aktiver REST-API.
|
||||
- **WLAN-Schritt (M5) komplett ungetestet gegen echte Hardware** — nur
|
||||
Build+Unit-Tests grün. Unklar ob das Testgerät WLAN hat. Vor Vertrauen
|
||||
in diesen Schritt unbedingt gegen ein Gerät mit WLAN-Chip testen —
|
||||
sowohl den Legacy-`/interface wireless`-Pfad als auch die Erkennung
|
||||
von `wifi`-typisierten (neuerer Treiber, nicht unterstützt) Interfaces.
|
||||
- **Neuer RouterOS-WiFi-Treiber (`/interface wifi`, wifiwave2/802.11ax)
|
||||
nicht unterstützt** — wird erkannt und im UI erklärt, aber nicht
|
||||
konfiguriert. Eigener Umbau nötig (andere Menüstruktur), falls
|
||||
gebraucht.
|
||||
|
||||
## Stand der Milestones
|
||||
|
||||
@@ -132,18 +153,20 @@ selbst separat als `@ObservedObject` halten.
|
||||
- ✅ M2: Backup-Service, Sicherungen-Tab
|
||||
- ✅ M3: WAN + LAN/DHCP-Wizard, Anwenden-Logik mit Vorab-Backup
|
||||
- ✅ M4: VLAN-Schritt (separates virtuelles Netz, kein Port-Tagging)
|
||||
- ⬜ M5: WLAN-Schritt (SSID/Passwort, nur bei erkannter WLAN-Hardware)
|
||||
- ✅ M5: WLAN-Schritt (SSID/Passwort, echte `.set`-Operation im Befehlsmodell,
|
||||
nur bei erkanntem Legacy-Wireless; neuer WiFi-Treiber erkannt aber nicht
|
||||
unterstützt) — **gebaut, aber noch nicht gegen echte WLAN-Hardware getestet**
|
||||
- ⬜ M6: Firewall-Schritt (sicherer Standard: NAT/Masquerade, WAN→LAN blocken)
|
||||
- ⬜ M7: Härtung — SSH-Hostkey-TOFU, Fehlerzustände, Politur, ggf. REST-Schreibpfad
|
||||
gegen echtes Gerät mit aktivem `www-ssl` verifizieren
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
M5 (WLAN) oder M6 (Firewall) als Nächstes — Nutzer hat noch nicht
|
||||
festgelegt, was zuerst kommt. Vor Firewall-Arbeit besonders vorsichtig
|
||||
sein: falsch gesetzte Regeln können den Fernzugriff auf den Router kappen,
|
||||
unbedingt Backup-Pflicht vor Anwenden beibehalten und im Testgerät bleiben,
|
||||
nicht am Produktivrouter.
|
||||
Zuerst M5 gegen ein Gerät mit echtem WLAN-Chip testen, sobald verfügbar.
|
||||
Danach M6 (Firewall) — dort besonders vorsichtig sein: falsch gesetzte
|
||||
Regeln können den Fernzugriff auf den Router kappen, unbedingt
|
||||
Backup-Pflicht vor Anwenden beibehalten und im Testgerät bleiben, nicht
|
||||
am Produktivrouter.
|
||||
|
||||
Kein Gitea-Remote vorhanden — falls der Nutzer später eine Gitea-Instanz
|
||||
aufsetzt (z.B. selbst gehostet auf der vorhandenen OMV-NAS, wo bereits
|
||||
|
||||
Reference in New Issue
Block a user