# Befundbericht: Erster Linux-Lauf **Datum: 26.08.2026** · Prüfplan: [PRUEFPLAN-Linux-Betrieb.md](./PRUEFPLAN-Linux-Betrieb.md) · Roadmap: [A4a](../ROADMAP.md) **Testsystem:** Ubuntu 26.04 LTS, Kernel 7.0.0-30, x86_64, 31 GB RAM, 5 CPUs, Zeitzone `Europe/Berlin`. .NET SDK 10.0.111 mit Runtime 10.0.11 bereits vorhanden. Zugriff über SSH (WireGuard, Schlüssel-Authentifizierung). > **Kernaussage: PolyTrader läuft auf Linux — als Dienst, mit Datenbank, mit echten Marktdaten.** > Der Prüfplan ist **vollständig abgearbeitet** (Nachtrag ab Abschnitt 5). Drei Fehler gefunden, > einer davon behoben. Offen bleibt nur die Sichtprüfung der Oberfläche, die einen Menschen am > Bildschirm braucht. --- ## 1. Was funktioniert | Prüfpunkt | Ergebnis | |---|---| | **Build** | `dotnet build -c Release`: **0 Fehler**, 15 Warnungen — exakt dieselben wie unter Windows. Keine plattformbedingte Abweichung | | **Tests** | **476 von 476 grün**, 3 s Laufzeit — identisch zu Windows | | **Publish** | `linux-x64`, framework-abhängig: 121 Dateien, 41 MB. Ausführbare Datei trägt bereits das Ausführungsrecht | | **Start** | Die Anwendung startet mit `--headless` und durchläuft die komplette Startsequenz | | **Native Abhängigkeiten** | **Keine nötig.** Die Vermutung aus dem Prüfplan ist bestätigt: `--headless` ruft `BuildAvaloniaApp()` nie auf, Skia und HarfBuzz werden nie geladen. `libfontconfig1` & Co. mussten **nicht** installiert werden | | **Master-Key** | Wird beim ersten Start erzeugt und mit Rechten **`0600`** abgelegt — `FilePermissions` arbeitet unter Linux korrekt. AES-256-GCM meldet sich als aktiv | | **Zeitzone** | `Europe/Berlin` wird korrekt erkannt und gemeldet | | **Lizenz-Gate** | Verhält sich exakt wie dokumentiert: Warnung, „eingeschränkter Modus", **kein** Programmabbruch | | **Logging** | `Logs/` wird angelegt und beschrieben | **Bemerkenswert:** Zwischen Windows und Linux gibt es bei Build und Tests **keinen einzigen Unterschied** — weder in der Fehler- noch in der Warnungszahl. Die Portierungsarbeit hat gehalten. --- ## 2. Befunde ### B-1 · Absturz statt Fehlermeldung ohne Datenbank · **behoben** **Beobachtet:** Ohne konfigurierten Connection-String lief die Anwendung an und starb tief im DI-Aufbau: ``` Unhandled exception. System.ArgumentException: The string argument 'connectionString' cannot be empty. at Microsoft.EntityFrameworkCore.Utilities.Check.NullButNotEmpty(...) … rund 50 weitere Zeilen … EXITCODE: 134 (SIGABRT) ``` **Warum das mehr ist als Kosmetik:** Für einen Serverbetrieb ist das doppelt schlecht. Der Betreiber sieht nicht, *was* fehlt, und systemd startet den Dienst wegen `Restart=on-failure` alle zehn Sekunden neu — im Journal stehen dann endlose Startversuche statt der Ursache. Und genau dieser Zustand ist bei einer **Erstinstallation der wahrscheinlichste**: Software liegt da, Zugangsdaten sind noch nicht gesetzt. Das betrifft direkt Schnitt D-5 (`setup.json`). **Behoben** (Commit `Verstaendlicher Abbruch statt Absturz…`): - `Program.Main` prüft die Verbindung, **bevor** der Host gebaut wird, und nennt Schlüssel, Datei, Pfad und ein Beispiel — dazu den Hinweis, dass das Schema per `dotnet ef database update` entsteht, weil die Anwendung nicht selbst migriert. - Rückgabewert **78** (`EX_CONFIG` aus den BSD-sysexits) statt eines Absturzes. - `deploy/polytrader.service` bekam **`RestartPreventExitStatus=78`** — ein Konfigurationsfehler repariert sich durch Neustarts nicht, er wird dadurch nur unsichtbar. - `AddCorePersistence` wirft als zweite Verteidigungslinie eine `InvalidOperationException` mit derselben Aussage. **Gegengeprüft auf der VM:** Verständliche Meldung, Exitcode 78, kein Stacktrace. ### B-2 · Zwei verschiedene Datumsformate in Logdateinamen · offen, klein Im selben Lauf entstanden nebeneinander: ``` 2026-08-26.jsonl ← ISO, yyyy-MM-dd 26-08-2026-Info.log ← dd-MM-yyyy 26-08-2026-Warning.log ``` Zwei Logger-Pfade mit unterschiedlicher Namenskonvention. Praktische Folgen: Eine Logrotate-Regel braucht zwei Muster, und beim Sortieren im Dateimanager landen die `.log`-Dateien in willkürlicher Reihenfolge, weil der Tag vorn steht. Kein Fehler, aber ein Stolperstein im Betrieb — sinnvollerweise mit **T2** (TerminalLogger-Umbau) zusammen zu erledigen. ### B-3 · `--smoke-ui` verlangt jetzt eine Datenbank · offen, entscheidungsbedürftig Die neue Prüfung aus B-1 läuft vor dem Host-Aufbau und trifft damit **auch** die Konstruktionsprüfung `--smoke-ui`. Die ist als CI-Werkzeug gedacht, und ein Build-Server hat typischerweise keine Datenbank. **Wichtig: Das ist keine Verschlechterung.** Vorher scheiterte `--smoke-ui` ohne Datenbank genauso — nur mit dem Stacktrace aus B-1 statt mit einer Meldung. Der Befund war vorher bloß unsichtbar. Sauber lösen ließe sich das, indem `--smoke-ui` die Persistenzschicht überspringt oder gegen EF-InMemory baut (wie die Tests). Das ist ein eigener Schnitt und hängt daran, ob die CI diesen Modus überhaupt nutzen soll — deshalb hier nur vermerkt, nicht gebaut. --- ## 3. Nicht geprüft — und warum > **Überholt.** Dieser Abschnitt beschreibt den Zwischenstand, bevor MariaDB und `sudo` > verfügbar waren. Alles hier Aufgeführte wurde im **Nachtrag ab Abschnitt 5** nachgeholt — > bis auf die Sichtprüfung der Oberfläche. Der Abschnitt bleibt als Verlaufsspur stehen. | Prüfpunkt | Fehlt | |---|---| | Betrieb **mit** Datenbank, Migrationen | Auf der VM läuft **keine** MySQL; der Datenbankhost ist nicht bekannt | | systemd-Dienst, `WorkingDirectory`-Falle (D-11) | Braucht `sudo`; Passwörter gebe ich nicht ein | | SIGTERM-Shutdown, `Restart=on-failure` | Setzt den laufenden Dienst voraus | | **Zeitzonen-Nachweis (T2)** | Die VM steht auf `Europe/Berlin`; der Effekt zeigt sich erst unter **UTC**. Umstellen braucht `sudo` | | Logrotate | Braucht `sudo` | | Oberfläche unter Linux | Braucht eine Datenbank (siehe B-3) — die VM hat aber einen Desktop, der Test ist also möglich | **Zum Weitermachen wird gebraucht:** 1. Eine **Testdatenbank** — entweder Adresse und Zugang zu einer bestehenden MySQL, oder MariaDB lokal auf der VM installieren (`sudo`). **Nicht die Produktivdatenbank:** Der `MarketSyncService` schreibt als Hintergrunddienst hinein. 2. Für die `sudo`-Schritte: Entweder Richard führt sie aus, oder er richtet für die Dauer des Tests passwortloses `sudo` für sein Konto ein. --- ## 4. Nebenbefunde - **Rider-Konfiguration im Repo:** Mit einem `git add -A` waren vier `.idea/`-Dateien in einen Commit gerutscht. Sie blockierten den `git pull` auf der VM, wo Rider dieselben Dateien lokal anlegt. Entfernt, `.idea/` steht jetzt in `.gitignore`. - **Verbindungs-Multiplexing (`ControlMaster`) funktioniert nicht** — Windows-OpenSSH unterstützt es nicht. Aus der SSH-Konfiguration entfernt; stattdessen werden mehrere Prüfschritte pro Aufruf gebündelt. - **Speicher ist reichlich vorhanden** (31 GB, davon 25 GB frei). Die Vermutung, der Claude-Desktop-Absturz auf der VM könnte an Speichermangel liegen, ist damit **widerlegt**. --- # Nachtrag: vollständiger Durchgang Nach Einrichtung von MariaDB und befristetem passwortlosem `sudo` wurde der Rest des Prüfplans abgearbeitet. ## 5. Betrieb mit Datenbank | Prüfpunkt | Ergebnis | |---|---| | **MariaDB** | 11.8.6 installiert — **genau die Version**, die in `DatabaseServerVersion` gepinnt ist. Datenbank `polytrader_test` mit eigenem Benutzer angelegt | | **Migrationen** | Alle fünf DbContexts (Core, CopyTrading, ResolutionFarming, Supervisor, Accounting) melden „Done.". **21 Tabellen** mit den Präfixen `core_`, `ct_`/`mod_copytrading_`, `rf_`, `acc_` | | **Start mit Datenbank** | Läuft vollständig durch: Core-Hydration abgeschlossen, `MarketSyncService` gestartet | | **Echter Datenverkehr** | **100 Märkte von der Polymarket-API geholt und geschrieben**, beim zweiten Lauf 100 aktualisiert. HTTP, TLS, JSON-Verarbeitung und Datenbankzugriff funktionieren unter Linux | > Das ist der eigentliche Beweis: Die Anwendung *arbeitet* auf Linux, sie startet nicht nur. ## 6. Dienstbetrieb (systemd) | Prüfpunkt | Ergebnis | |---|---| | **Dienst** | `active (running)`, 71,6 MB Speicher, 20 Tasks. Startet automatisch mit dem System | | **`WorkingDirectory`-Falle (D-11)** | ✅ **Kein Problem.** Gezielt geprüft: `server_settings.xml` in `/opt/polytrader` mit Testzeitzone `America/New_York` angelegt — die Anwendung meldete genau diese Zone. Eine `find`-Suche über das gesamte Dateisystem fand **keine zweite** Datei. Die Unit setzt `WorkingDirectory` korrekt | | **Nebenbefund** | `server_settings.xml` wird beim Start **nicht angelegt** — erst beim Speichern von Einstellungen. Ein frisch installierter Dienst läuft also mit Standardwerten und ohne Konfigurationsdatei | | **Shutdown (SIGTERM)** | ✅ **0,08 Sekunden** — weit unter `TimeoutStopSec=45`. „Deactivated successfully", **kein `SIGKILL`** im gesamten Journal | | **Neustart nach Absturz** | ✅ `kill -9` auf den Hauptprozess → `Restart=on-failure` greift, neue PID nach ~10 s | | **Neustartschutz bei Konfigurationsfehler** | ✅ Verbindung entfernt → Status `failed`, **Exit-Code 78**, systemd meldet ihn als `78/CONFIG`. **Keine Neustartschleife.** Die verständliche Meldung steht im Journal. Damit wirkt der Fix aus B-1 im Dienstbetrieb nachweislich | | **Dateirechte** | `master.key` `0600`, Eigentümer `polytrader` | ## 7. Logrotate Regel mit **zwei Mustern** (wegen B-2) und `copytruncate` eingerichtet. Erzwungener Lauf: alle drei Logdateien rotiert und komprimiert, Originale auf 0 Bytes gesetzt, **Dienst schreibt ohne Unterbrechung weiter**. `copytruncate` ist hier zwingend: Die Anwendung hält die Logdatei offen und bekommt ein Umbenennen nicht mit — sie würde sonst in die rotierte Datei weiterschreiben. ## 8. Zeitzonen-Befund T2 — **belegt** Bisher nur behauptet, jetzt bewiesen. Systemzeitzone auf UTC gestellt, App-Anzeigezone auf `Europe/Berlin`: ``` System UTC : 2026-08-26 20:04:51 Berlin : 2026-08-26 22:04:51 Logzeile: [20:04:39] [Info] Anzeige-Zeitzone: Europe/Berlin JSON-Zeile: {"ts":"2026-08-26T20:04:39.398+00:00", …} ``` **Der Widerspruch steht in derselben Zeile:** Die Anwendung meldet Berlin als Anzeigezone und stempelt gleichzeitig mit UTC. **Betriebliche Folge:** Auf einem UTC-Server — dem Normalfall — zeigen alle Logs UTC, während die Oberfläche Berliner Zeit anzeigt. Wer einen Vorfall von „22:30" sucht, findet ihn unter 20:30, und zwischen Mitternacht und 2 Uhr sogar in der Datei des **Vortags**. Das macht Fehlersuche im Ernstfall unnötig schwer. **Nicht behoben** — gehört zu T2 (Umstellung auf `Microsoft.Extensions.Logging`) und ist ein eigener Schnitt. Die Systemzeitzone wurde nach dem Test auf `Europe/Berlin` zurückgestellt. ## 9. Oberfläche unter Linux **Alle Fenster konstruieren fehlerfrei** (`--smoke-ui` unter `xvfb-run`): ``` [OK] core.start, core.dashboard, core.settings, core.jobs, core.terminal [OK] copytrading.main, resolutionfarming.main, supervisor.main, accounting.main [OK] ShellWindow konstruiert [OK] ShutdownConfirmWindow konstruiert [OK] Einstellungs-Editor: 7 Abschnitte, 17 Felder [OK] Farbschema „Light": alle 27 Farben vorhanden [OK] Farbschema „Dark": alle 27 Farben vorhanden ``` ### B-4 · `--smoke-ui` braucht einen X-Server · offen Ohne Display scheitert die Konstruktionsprüfung mit `System.Exception: XOpenDisplay failed` aus `AvaloniaX11Platform.Initialize`. Sie ist aber als **CI-Werkzeug** gedacht, und ein Build-Server hat typischerweise keinen Bildschirm. **Zwei Wege:** 1. **`xvfb-run -a` vorschalten** — funktioniert nachweislich (siehe oben), erfordert nur das Paket `xvfb` im Build-Image. Ein Einzeiler im CI-Workflow. 2. `Avalonia.Headless` verwenden statt des X11-Backends. Sauberer, aber eine Codeänderung. Empfehlung: Weg 1, wenn A2 (CI-Runner) wieder aufgenommen wird — dann `xvfb` ins Image und `--smoke-ui` als zusätzlichen Prüfschritt aufnehmen. Der Nutzen wäre erheblich: Die Konstruktionsprüfung deckt neun Views und beide Farbschemata ab. ### Noch offen: Sichtprüfung Die Anwendung wurde **nicht mit sichtbarem Fenster** geprüft — das braucht jemanden am Bildschirm der VM. Schriftrendering, Spaltenbreiten und Dunkelmodus sehen unter GTK erfahrungsgemäß anders aus als unter Windows. Das ist der verbleibende Rest von A1 auf der Zielplattform. --- ## 10. Zustand der VM nach dem Durchgang **Bewusst stehen geblieben** (damit weitergetestet werden kann): - MariaDB 11.8.6 mit Datenbank `polytrader_test` - Dienst `polytrader.service` unter `/opt/polytrader`, aktiv - Logrotate-Regel `/etc/logrotate.d/polytrader` - Xvfb (allgemein nützlich) - Anleitung `~/TESTUMGEBUNG.md` **Zurückgestellt:** Systemzeitzone wieder `Europe/Berlin`. **Noch offen:** Die befristete `sudo`-Freigabe `/etc/sudoers.d/99-testing` ist **aktiv** und sollte entfernt werden, sobald nicht mehr getestet wird: ```bash sudo rm /etc/sudoers.d/99-testing ``` Vollständige Aufräumbefehle: [TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md) §7. --- # Nachtrag 2: Sichtprüfung der Oberfläche Durchgeführt **ohne Bildschirm**: Die Anwendung lief unter `Xvfb` (virtuelles Display 1600×1000), Navigation per `xdotool`, Aufnahmen mit `import`. Damit ist die Sichtprüfung reproduzierbar und ohne Anwesenheit möglich. ⚠️ **Erst vier von neun Ansichten geprüft.** Ohne Lizenzschlüssel deaktiviert die Anwendung **alle Module** (`BuildHost`: `if (!licensed) foreach (var m in allModules) disabled.Add(...)`), sodass Copytrading, ResolutionFarming, Supervisor und Accounting in der Seitenleiste ausgegraut bleiben. Für deren Prüfung wird ein Lizenzschlüssel gebraucht. ## Was gut aussieht | | | |---|---| | **Schriftrendering** | Sauber und vollständig — Umlaute, typografische Anführungszeichen („…") und sogar Emoji werden korrekt dargestellt. Im Terminal auch die Monospace-Schrift. Unter Linux mit Fontconfig keineswegs selbstverständlich | | **Diagramme (Skia)** | LiveCharts2 rendert: Achsen, Gitternetz, Beschriftungen, Rahmen | | **Layout** | Keine Überlappungen, keine abgeschnittenen Texte, keine zerbrochenen Werkzeugleisten. Die Einfenster-Shell mit Seitenleiste sitzt | | **Symbole** | Die nach `Assets/` verschobenen PNGs werden korrekt angezeigt — der Umzug beim Frühjahrsputz hat gehalten | | **Dunkelmodus** | Durchgängig konsistent über alle geprüften Ansichten | | **Einstellungs-Editor** | Der `PropertyGrid`-Ersatz funktioniert wie vorgesehen: Kategorie-Überschrift, Label links, Feld rechts, Hinweis darunter | ## Befunde ### B-5 · Windows-Pfad als Standardwert unter Linux · offen Im Einstellungsfenster steht bei **Mullvad CLI Path**: ``` C:\Program Files\Mullvad VPN esources\mullvad.exe ``` Auf einem Linux-System ist das sinnlos — dort liegt die ausführbare Datei üblicherweise unter `/usr/bin/mullvad`. Der Standardwert stammt aus der Windows-Zeit und wurde bei der Portierung nicht mitgezogen. Folge: Wer die VPN-Rotation auf dem Zielserver einschaltet, ohne den Pfad von Hand zu korrigieren, bekommt einen Fehler, dessen Ursache nicht offensichtlich ist. **Empfehlung:** Standardwert plattformabhängig setzen — unter Linux `/usr/bin/mullvad`, unter Windows der bisherige Pfad. ### B-6 · Zu geringer Textkontrast in den KPI-Kacheln · offen Der grüne Text in den Modul-KPI-Kacheln erreicht gegen den Kachelhintergrund nur ``` Textfarbe RGB(46, 104, 68) Hintergrund RGB(35, 37, 39) Kontrast 2,33 : 1 ``` **WCAG AA verlangt 4,5:1** für normalen Text (3:1 erst ab 18,7 px fett). Der Wert liegt also deutlich darunter — auf einem hellen Bildschirm oder aus normalem Sitzabstand sind die Zahlen schwer zu lesen. Betrifft die gedämpfte „positiv"-Farbe des Dunkelmodus. Anzuheben, ohne die Signalwirkung (grün = positiv, rot = negativ) aufzugeben. ### B-7 · „Gesamt" erscheint doppelt in der KPI-Kachel · offen, klein Die Kachel trägt die Überschrift **Gesamt** und darunter als erste Textzeile noch einmal **Gesamt**. Sieht wie ein Darstellungsfehler aus; vermutlich wird der Modulname sowohl als Titel als auch im Textblock gerendert. ### B-8 · Datumsachse der Equity-Kurve zeigt zwölfmal „01.01." · offen Bei eingestelltem Zeitraum „30 Tage" trägt die X-Achse der Equity-Kurve **zwölf identische Beschriftungen „01.01."**. Erwartet wären fortlaufende Daten über den Zeitraum. Vermutlich werden die Achsen-Ticks nicht auf echte Datumswerte abgebildet, sondern auf einen Standardwert — bei leerem Datenbestand fällt das besonders auf. **Nicht Linux-spezifisch:** Der Fehler dürfte unter Windows genauso auftreten, ist dort nur nie jemandem aufgefallen. Zu prüfen, sobald echte Trades vorliegen — falls die Achse dann korrekte Daten zeigt, ist es ein reiner Leerzustands-Fehler und weniger dringend. ## Noch zu prüfen Die vier **Modulfenster** (Copytrading, ResolutionFarming, Supervisor, Accounting). Genau dort liegen laut A5 die interessanten Punkte: Splitter-Positionen, Spaltenbreiten der Grids und die Frage, ob die acht KPI-Kacheln im Accounting sinnvoll umbrechen. **Voraussetzung:** ein Lizenzschlüssel auf der VM. Das Deploymentcenter ist von dort erreichbar (HTTP/2 302), und die Lizenz-CLI läuft bereits — sie meldet eine **HWID v2 auf Basis der Linux-machine-id**. Ein Aktivierungsversuch wäre damit zugleich die Live-Abnahme von **D-2** (Roadmap A3). --- # Nachtrag 3: Modulfenster (nach Lizenzaktivierung) Richard hat den Lizenzschlüssel auf der VM hinterlegt. Die Anwendung meldet **„Lizenz gültig (online geprüft)"**, `--license-status` zeigt `Cache: valid`, Statusleiste **„Module: 4"**. > **Damit ist D-2 live abgenommen** — Lizenzaktivierung gegen das echte Deploymentcenter, > einschließlich HWID v2 auf Basis der Linux-`machine-id`. Ein Stück von Roadmap **A3** ist > nebenbei erledigt. ## B-9 · Kalendersymbol wird als sinnlose Zahl dargestellt · offen In den Datumsfeldern des Accounting-Fensters erscheint rechts statt eines Kalendersymbols ein Artefakt, das wie **„26" mit einem Punkt darüber** aussieht — in beiden Feldern („Von", „Bis"). **Ursache:** Das Symbol stammt aus einer Icon-Schriftart, die unter Linux fehlt. Fontconfig ersetzt sie stillschweigend durch eine andere Schrift, in der derselbe Zeichencode etwas ganz anderes bedeutet. Ein typischer Portierungsfehler: Es gibt keine Fehlermeldung, das Zeichen ist einfach falsch. **Nur im Bild zu sehen, nie im Log.** Unter Windows sieht dieselbe Stelle korrekt aus. ## B-10 · Kein einziges DataGrid wurde gerendert · **behoben** · **schwerwiegend** **Der wichtigste Befund dieses Durchgangs.** **Beobachtet:** Sämtliche Tabellen der Anwendung waren leer — keine Zeilen, keine Spaltenköpfe, nur eine leere Fläche. Betroffen: Master-Trader, Offene Trades, Geschlossene Trades, Account-Übersicht, Ledger, Jobs, schlicht alle. **Ursache:** `Avalonia.Controls.DataGrid` liegt in einem **eigenen Paket** und bringt sein Theme **nicht** über `` mit. In `App.axaml` fehlte: ```xml ``` Die vorhandenen Anpassungen für `DataGrid` und `DataGridColumnHeader` in derselben Datei bauen auf diesem Basis-Theme auf und liefen bisher ins Leere. **Warum das monatelang unbemerkt blieb** — drei Gründe, die zusammenkamen: 1. **Keine Fehlermeldung, keine Bindungswarnung.** Das Steuerelement existiert, es zeichnet nur nichts. 2. **Die Konstruktionsprüfung bleibt grün**, weil das Fenster ja aufgebaut wird — sie prüft Konstruktion, nicht Darstellung. 3. **Die Abnahme mit echten Daten (A5) stand noch aus.** Ohne Daten sieht eine leere Tabelle aus wie fehlende Daten, nicht wie ein Fehler. **Der Fehler war nicht linuxspezifisch** — er bestand unter Windows genauso. Er ist nur hier aufgefallen, weil zum ersten Mal jemand systematisch hingesehen hat. **Behoben und gegengeprüft:** Nach dem Fix erscheinen die Spaltenköpfe („#", „Wallet", „Kategorie", „Trades", „Winrate", „PnL", „Copy-PnL" …). Vorher war die Fläche komplett leer. ## B-11 · Spaltenüberschriften werden abgeschnitten · offen Direkt sichtbar, sobald B-10 behoben war — und **genau der A5-Punkt „Spaltenbreiten"**: ``` Trades (7 statt Trades (7T) Winrate ' statt Winrate % Copy-PnL statt Copy-PnL (30T) ``` Die letzten drei Spalten (Profit-Faktor, Ø PnL/Trade, Copy-Trades) zeigen **gar keinen Text mehr** — für sie reicht die Breite des Fensterbereichs nicht. **Ursache:** Die festen Pixelbreiten in [`CopyTradingWindow.axaml`](../../src/PolyTrader.App.Avalonia/Views/Modules/CopyTradingWindow.axaml) (50, 170, \*, 110, 50, 90, 90, 100, 110, 100, 100, 90) stammen aus der WinForms-Fassung. Die dort verwendete Schrift war schmaler als die Avalonia-Standardschrift, sodass dieselben Werte jetzt nicht mehr ausreichen. **Nicht behoben** — Spaltenbreiten lassen sich sinnvoll erst mit echten Daten festlegen, sonst optimiert man auf leere Zellen. Gehört zur A5-Abnahme. ## B-12 · Lizenzschlüssel liegt im Klartext · offen, klein `--license-status` meldet: **„Gespeicherter Schlüssel (server_settings.xml): gesetzt (Klartext)"**. Die Projektkonvention ist Verschlüsselung at-rest über den Master-Key (`enc:v1:` …), und der Code unterstützt beides — `SecretProtection.Unprotect` reicht Klartext unverändert durch. `--license-set-key` verschlüsselt aber offenbar nicht. Ein Lizenzschlüssel wiegt weniger schwer als ein Wallet-Schlüssel, aber die Konvention sollte einheitlich gelten. Zumal `server_settings.xml` auch den Watchdog-Token trägt. ## Bewertung der Modulfenster | Fenster | Beobachtung | |---|---| | **Accounting** | **Die acht KPI-Kacheln brechen sinnvoll um** — sieben in einer Reihe, die achte darunter. Eine der offenen A5-Fragen ist damit beantwortet. Tabs, Datumswahl, Währungswahl und die drei Schaltflächen sitzen sauber | | **Copytrading** | Alle vier Tabs vorhanden, die in A3 nachgerüsteten Schaltflächen „Neu" und „Löschen" sind da. Splitter funktioniert. Der rechte Bereich wirkt im Leerzustand zerrissen: „Zugewiesene Accounts" klebt am unteren Rand, weil es fest auf `DockPanel.Dock="Bottom"` mit `Height="220"` steht, während das Detailformular darüber leer bleibt. **Mit Daten neu zu beurteilen** | | **ResolutionFarming, Supervisor** | Aufgenommen, aber im Leerzustand ohne Aussagekraft — beide leben von Tabellen, die vor B-10 ohnehin unsichtbar waren | **Empfehlung:** Die Sichtprüfung der Modulfenster **mit echten Daten wiederholen**, sobald B-10 ausgeliefert ist. Erst dann lassen sich Spaltenbreiten (B-11), Splitter-Positionen und Leerzustände sinnvoll beurteilen. Das Verfahren dafür ist dokumentiert und wiederholbar: [TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md) §4.7.