Supervisor S-0c: Log Viewer im Terminal (JSONL menschenlesbar, CID-Forensik)

Terminal-Fenster jetzt mit TabControl (via Designer): Tab 'Live' = bisherige Anzeige,
Tab 'Log Viewer' = JSONL-Tagesdateien menschenlesbar aufbereitet:
- Filter: Datum (DateTimePicker), Level, CorrelationId (SignalId), Suchtext.
- Doppelklick auf eine CID laedt die komplette Signal-Kette ('zeig mir alles zu diesem Signal').
- LogJson.ParseLine (pur, Gegenstueck zu Format): tolerant gegen kaputte Zeilen (null statt Crash);
  Viewer ueberspringt sie. UI-Schutz bei sehr grossen Tagen (20k-Limit).

Tests: +5 (Parse-Roundtrip, kaputte Zeilen). Build 0 Fehler, 341 Tests gruen, --smoke-ui komplett gruen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-16 18:52:15 +02:00
co-authored by Claude Opus 4.8
parent bf3e012f8b
commit ca00977ea3
4 changed files with 369 additions and 7 deletions
@@ -37,6 +37,28 @@ namespace PolyTrader.Tests
Assert.False(doc.RootElement.TryGetProperty("cid", out _));
}
[Fact]
public void LogJson_parse_roundtrips_format()
{
var e = new LogMessageEventArgs("Nachricht äöü", LogLevel.Warning, "sig-9");
var p = LogJson.ParseLine(LogJson.Format(e));
Assert.NotNull(p);
Assert.Equal("Warning", p!.Level);
Assert.Equal("sig-9", p.Cid);
Assert.Equal("Nachricht äöü", p.Message);
}
[Theory]
[InlineData("")]
[InlineData(" ")]
[InlineData("kein json")]
[InlineData("{kaputt")]
public void LogJson_parse_returns_null_for_broken_lines(string line)
{
Assert.Null(LogJson.ParseLine(line));
}
// ----- Repos (EF InMemory) -----
private static InMemoryContextFactory<CoreDbContext> Factory() => new(o => new CoreDbContext(o));