using System.Text.Json; namespace QuantEngine.Core.Infrastructure { public sealed class OperationalReportData { public string SchemaVersion { get; init; } = "n/a"; public string SourceJson { get; init; } = "n/a"; public string GeneratedAt { get; init; } = "n/a"; public int SectionCount { get; init; } public List Sections { get; init; } = new(); } public sealed record OperationalReportSection(string Name, string Title, string Preview); public static class OperationalReportLoader { public static OperationalReportData Load(string path) { if (!File.Exists(path)) { return new OperationalReportData(); } using var stream = File.OpenRead(path); using var doc = JsonDocument.Parse(stream); var root = doc.RootElement; var sections = new List(); if (root.TryGetProperty("sections", out var sectionArray) && sectionArray.ValueKind == JsonValueKind.Array) { foreach (var section in sectionArray.EnumerateArray()) { var name = section.TryGetProperty("name", out var nameProp) ? nameProp.GetString() ?? string.Empty : string.Empty; var title = section.TryGetProperty("title", out var titleProp) ? titleProp.GetString() ?? string.Empty : string.Empty; var markdown = section.TryGetProperty("markdown", out var markdownProp) ? markdownProp.GetString() ?? string.Empty : string.Empty; sections.Add(new OperationalReportSection(name, title, Preview(markdown))); } } return new OperationalReportData { SchemaVersion = root.TryGetProperty("schema_version", out var schema) ? schema.GetString() ?? "n/a" : "n/a", SourceJson = root.TryGetProperty("source_json", out var sourceJson) ? sourceJson.GetString() ?? "n/a" : "n/a", GeneratedAt = root.TryGetProperty("generated_at", out var generatedAt) ? generatedAt.GetString() ?? "n/a" : "n/a", SectionCount = root.TryGetProperty("section_count", out var count) ? count.GetInt32() : sections.Count, Sections = sections }; } private static string Preview(string markdown) { if (string.IsNullOrWhiteSpace(markdown)) { return "n/a"; } var trimmed = markdown.Replace("\r", " ").Replace("\n", " ").Trim(); return trimmed.Length <= 80 ? trimmed : trimmed[..80] + "..."; } } }