Testanleitung: eigenes X-Display je Projekt fuer Parallelbetrieb
CI / Build & Tests (Linux) (push) Canceled after 0s
CI / Plattformneutralität & Hygiene (push) Canceled after 0s

Damit mehrere Agenten gleichzeitig Oberflaechen testen koennen, bekommt jedes
Projekt eine feste Displaynummer (Vorgabe Richard):

  :99 PolyTrader, :98 Predictalytics, :97 ClawdDotNet, :96 IBKRTrader,
  :95 und absteigend fuer kuenftige Projekte.

Zwei Prozesse auf demselben Display sehen die Fenster des jeweils anderen -
Klicks landen im falschen Programm, Aufnahmen zeigen fremde Anwendungen.

Beim Durcharbeiten fielen zwei weitere Kollisionspunkte auf, die zum
Parallelbetrieb dazugehoeren und mit aufgenommen wurden:

- Screenshot- und Logdateien in /tmp brauchen ein Projektpraefix. /tmp/v_1.png
  ueberschreiben sich parallel laufende Projekte gegenseitig.
- "xvfb-run -a" darf NICHT mehr verwendet werden: Das -a sucht sich selbst ein
  freies Display und beginnt dabei bei :99 - ausgerechnet PolyTraders Nummer.
  Stattdessen "xvfb-run -n <nummer>".

Die Warnung ist nicht theoretisch: Auf der VM lag ein verwaister X98-Socket,
entstanden durch genau so einen "xvfb-run -a"-Aufruf beim smoke-ui-Test, als
:99 belegt war. Er blockierte Predictalytics' reservierte Nummer, ohne dass ein
Prozess lief. Entfernt, und die Anleitung erklaert jetzt, wie man verwaiste
Sockets erkennt (ls /tmp/.X11-unix/ gegen pgrep -a Xvfb lesen) und aufraeumt.

Weiter ergaenzt:
- pkill nie ohne Displaynummer - "pkill Xvfb" erschlaegt die Sitzungen aller
  anderen Projekte.
- DISPLAY in jedem Skript setzen, sonst landet man auf :0, dem echten Desktop.
- Die Skriptvorlage hat jetzt einen Kopf mit PROJEKT/DISP/FENSTER; das ist
  alles, was sich je Projekt unterscheidet. Praktisch gegengetestet.
- Aufraeumabschnitt und Belegungsliste um Displays und Verzeichnisse erweitert.

Nebenbei aufgefallen: Das PolyTrader-Publish lag unter ~/pt-test statt
~/polytrader-test und verletzte damit die eigene Verzeichniskonvention.
Umbenannt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-08-27 20:49:28 +02:00
co-authored by Claude Opus 5
parent 62570cfdd8
commit 9b2294cb4c
33 changed files with 979 additions and 244 deletions
@@ -449,7 +449,7 @@ einheitlich gelten. Zumal `server_settings.xml` auch den Watchdog-Token trägt.
**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.
[TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md) §4.8.
---
@@ -551,4 +551,88 @@ leer. **Korrektes Verhalten.**
Die Befunde B-11, B-13 und B-14 sind **Layoutarbeit an einer Stelle** und sollten zusammen
angegangen werden — am besten mit eingespielten Testdaten, weil sich Spaltenbreiten nur so
sinnvoll festlegen lassen. Das Verfahren ist reproduzierbar:
[TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md) §4.7 plus `testdaten-ui.sql`.
[TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md) §4.8 plus `testdaten-ui.sql`.
---
# Nachtrag 5: Behebung der offenen Befunde (27.08.2026)
Die Nacharbeit ist unter Windows entstanden und dort gebaut und geprüft
(`dotnet build -c Release`: 0 Fehler / 15 Warnungen wie zuvor; **484 Tests grün**, 8 davon neu;
`--smoke-ui` durchgängig `[OK]`). Die **Gegenprobe am Bild steht aus** — sie gehört auf die
Linux-VM, nach dem Verfahren aus [TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md) §4.8
mit `testdaten-ui.sql`.
## Behoben
| Befund | Was geändert wurde |
|---|---|
| **B-2** · zwei Datumsformate | `TerminalLogger` schreibt die `.log`-Dateien jetzt als `yyyy-MM-dd-<Level>.log` — dasselbe Format wie die `.jsonl`. Eine Logrotate-Regel mit **einem** Muster genügt künftig; die alte Regel mit zwei Mustern schadet nicht und darf stehen bleiben, solange noch alte Dateien da sind |
| **B-5** · Windows-Pfad unter Linux | `ServerSettings.DefaultMullvadCliPath` ist plattformabhängig (`/usr/bin/mullvad` bzw. der Windows-Pfad). Zusätzlich nennt die Fehlermeldung des `MullvadVpnService` jetzt den auf diesem System erwarteten Pfad — ein aus der Windows-Zeit übernommener Wert in `server_settings.xml` erklärt sich damit selbst |
| **B-6** · zu geringer Kontrast | **Es war kein Farbwert-, sondern ein Themenfehler.** Die Kachelfarbe wurde im Code über `ThemeManager.Brush(...)` aufgelöst und danach nie neu ausgewertet — beim Umschalten blieb die *helle* Positiv-Farbe (`#2F6B46`) auf dunklem Grund stehen, exakt die gemessenen 2,33 : 1. Jetzt kommt die Farbe über Klassen (`.positive` / `.negative`) und `DynamicResource`, folgt dem Themenwechsel also von selbst. Die eigentlichen Tokens erfüllen AA: dunkel **5,9 : 1**, hell **5,2 : 1** |
| **B-7** · „Gesamt" doppelt | Der Modulname steht nicht mehr im Textblock — die Kachel trägt ihn schon als Überschrift |
| **B-8** · zwölfmal „01.01." | Leerzustands-Fehler wie vermutet: ohne Trades nahm LiveCharts einen Standardbereich um 0 an, und Tick 0 ist der 01.01.0001. Die Achse spannt jetzt den **gewählten Zeitraum** auf, wenn keine Daten da sind; der Labeler prüft zusätzlich den gültigen `DateTime`-Bereich (sonst wirft `new DateTime(...)` bei Ticks außerhalb) |
| **B-11** · abgeschnittene Überschriften | Systematisch statt Spalte für Spalte: **132** feste Pixelbreiten in allen neun Ansichten sind jetzt `Width="Auto"` — das misst Überschrift *und* Werte. Die 19 `Width="*"`-Spalten haben eine `MinWidth`. Die Regel steht als Kommentar bei der `DataGrid`-Formatvorlage in `App.axaml` |
| **B-13** · Name unsichtbar | Im Master-Trader-Grid steht **Name** jetzt direkt hinter `#` mit `MinWidth="180"`; die Wallet-Adresse folgt gekürzt (`0x9e2b…3b95`, neuer `ShortAddressConverter`), die vollständige Adresse im Tooltip |
| **B-14** · mehrzeilige Texte | Neuer Feldtyp `MultilineTextSettingsField`; „Beschreibung" und „Begründung" sind am Modell mit `[DataType(DataType.MultilineText)]` ausgezeichnet und erscheinen als sechszeiliges Feld mit Umbruch |
| **B-15** · ein Datensatz legt das Modul lahm | Die Wertkonvertierung läuft über `AccountIdSetJson`: JSON-Array wie bisher, eine reine Zahlenliste (`"1,2"`) wird als Altformat noch verstanden, alles andere ergibt eine **leere** Zuordnung. Der Trader wird also geladen und kopiert auf kein Konto — die sichere Richtung. Die Hydration meldet Anzahl und letzten Rohwert als Warnung |
| **B-12** · Lizenzschlüssel im Klartext | **Ursache gefunden:** `LicenseCli` läuft vor dem Host-Aufbau und rief damit `SecretProtection.Protect` ohne geladenen Master-Key auf — der reicht den Klartext unverändert durch. Die CLI lädt den Master-Key jetzt selbst. Zusätzlich zieht der Start einen noch im Klartext liegenden Schlüssel einmalig verschlüsselt nach (selbstheilende Migration wie bei den DB-Secrets) |
## Nebenbefund aus der Nacharbeit — **alle Dezimal-Einstellungen waren nicht änderbar**
Beim Nachbauen von B-14 fiel auf: `SettingsModelBuilder.Create` kannte `bool`, `int`, `long`,
`string` und Enums — **`decimal`, `double` und `float` nicht**. Alle Dezimalwerte fielen still auf
`ReadOnlySettingsField` zurück und waren in der Oberfläche damit reine Anzeigen.
Betroffen war die **komplette Risikokonfiguration**: Positionsgrößen (`PerMarketLimit`,
`PerMasterLimit`), Preisgrenzen (`MaxBuyPrice`, `MaxPriceDifference`), SELL-Leiter (`SellFloorPct`,
`ProfitTarget`), Spread- und Verkaufsgrenzen sowie im ResolutionFarming `MinPrice`, `MaxPrice`,
`MinEdgePct`, `MaxPerMarketUsd` und der Tagesverlust-Kill-Switch. Unter WinForms waren sie im
PropertyGrid noch editierbar — die Regression kam mit dem Ersatz des PropertyGrid und ist seither
unbemerkt geblieben, weil ein nicht editierbares Feld genauso aussieht wie ein editierbares mit
grauem Rahmen.
Behoben durch `DecimalSettingsField` (nimmt „5,0" und „5.0" an; eine ungültige Eingabe lässt den
alten Wert stehen, statt still eine 0 zu schreiben). **Damit das nicht wiederkehrt**, prüft
`--smoke-ui` jetzt zusätzlich, dass in `CopyTradingAccountSettings`, `RfSettings` und
`ServerSettings` **kein beschreibbares Einzelfeld** als reine Anzeige landet:
```
[OK] Einstellungs-Editor (CopyTradingAccountSettings): alle beschreibbaren Felder sind auch bearbeitbar
[OK] Einstellungs-Editor (RfSettings): alle beschreibbaren Felder sind auch bearbeitbar
[OK] Einstellungs-Editor (ServerSettings): alle beschreibbaren Felder sind auch bearbeitbar
```
## Zusätzlich: Tooltip auf jeder Textzelle
Auch mit sauberen Breiten bleiben lange Marktfragen und Logmeldungen zwangsläufig abgeschnitten
(die Beobachtungen zur Account-Übersicht und zur Spalte „Nachricht" im Dashboard). Eine
Formatvorlage in `App.axaml` gibt deshalb **jeder** Textzelle ihren vollen Inhalt als Tooltip —
kein Spaltenziehen mehr nötig.
## Behoben, aber nur am Bild nachweisbar
**B-9 · Kalendersymbol.** Der wahrscheinliche Grund ist gefunden, aber unter Windows nicht
reproduzierbar: In Avalonia stechen die Formatvorlagen der Anwendung die Setter eines
`ControlTheme` aus. Unsere `Style Selector="Button"` setzte damit auch auf dem `PART_Button` des
`CalendarDatePicker` die Schriftliste „Barlow Condensed, …" — und verdrängte dort die
Symbolschrift, aus der das Kalenderzeichen stammt. Unter Windows findet die Schriftsuche das
Zeichen trotzdem, unter Linux setzt Fontconfig stillschweigend etwas anderes ein.
Die Schrift-Zuweisung gilt jetzt als `Button:not(#PART_Button)`; Fläche, Rahmen und Ecken bleiben
unverändert für alle Schaltflächen. **Bewusst so eng geschnitten:** Trifft die Vermutung nicht zu,
ändert sich nur die Schrift auf Vorlagen-Schaltflächen, nicht das Aussehen der Oberfläche.
> **Zu prüfen auf der VM:** Zeigt das Accounting-Fenster in den Feldern „Von" und „Bis" jetzt ein
> Kalendersymbol? Falls nicht, hilft ein Bildausschnitt der Stelle weiter — das Zeichen lässt sich
> aus dem Log nicht ermitteln.
## Bewusst nicht angefasst
| Befund | Grund |
|---|---|
| **B-3** · `--smoke-ui` verlangt eine Datenbank | Eigener Schnitt: Persistenz überspringen oder gegen EF-InMemory bauen. Betrifft fünf DbContexts und hängt daran, ob die CI diesen Modus nutzen soll — siehe A2 |
| **B-4** · `--smoke-ui` braucht einen X-Server | Zwei Wege (`xvfb-run` im Build-Image vs. `Avalonia.Headless` im Code). Gehört zu derselben Entscheidung wie B-3 |
| **§8** · Logs stempeln UTC, Oberfläche zeigt Ortszeit | Gehört zu **T2** (Umstellung auf `Microsoft.Extensions.Logging`). Ein sauberer Fix braucht `DateTimeOffset` statt `DateTime` in `LogMessageEventArgs` — das berührt jede Logzeile der Anwendung und ist kein Nebenbei-Schnitt |
| Leerzustände melden nichts | Betrifft rund vierzehn Grids und ist reine Zutat, kein Fehler. Sinnvoll zusammen mit der nächsten Sichtprüfung zu entscheiden |