namespace FinlyticCore.Dtos.TradeRepublic; using System; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; // 1. Der Response-Wrapper public record TradeRepublicAssetResponse( [property: JsonPropertyName("correlationId")] string CorrelationId, [property: JsonPropertyName("resultCount")] int ResultCount, [property: JsonPropertyName("results")] IList Results ); // 2. Das Tag-Objekt public record TradeRepublicTag { [JsonPropertyName("id")] public string Id { get; init; } = ""; [JsonPropertyName("name")] public string Name { get; init; } = ""; [JsonPropertyName("type")] public string Type { get; init; } = ""; } // 3. Die Basisklasse MIT UNSEREM CUSTOM CONVERTER [JsonConverter(typeof(TradeRepublicAssetConverter))] public record TradeRepublicAsset { [JsonPropertyName("isin")] public string Isin { get; init; } = ""; [JsonPropertyName("name")] public string Name { get; init; } = ""; [JsonPropertyName("type")] public string Type { get; init; } = ""; private readonly string _instrumentCategory = ""; [JsonPropertyName("instrumentCategory")] public string InstrumentCategory { get => _instrumentCategory; init => _instrumentCategory = value ?? ""; } [JsonPropertyName("hasCfd")] public bool HasCfd { get; init; } [JsonPropertyName("imageId")] public string? ImageId { get; init; } [JsonPropertyName("tags")] public IReadOnlyList Tags { get; init; } = Array.Empty(); } // 4. Die spezifischen Klassen public record TradeRepublicStock : TradeRepublicAsset { [JsonPropertyName("derivativeProductCategories")] public IReadOnlyList DerivativeProductCategories { get; init; } = Array.Empty(); } public record TradeRepublicCrypto : TradeRepublicAsset { [JsonPropertyName("subtitle")] public string Subtitle { get; init; } = ""; [JsonPropertyName("searchSubtitle")] public string SearchSubtitle { get; init; } = ""; } public record TradeRepublicEtf : TradeRepublicAsset { [JsonPropertyName("derivativeProductCategories")] public IReadOnlyList DerivativeProductCategories { get; init; } = Array.Empty(); [JsonPropertyName("etfDescription")] public string EtfDescription { get; init; } = ""; [JsonPropertyName("mappedEtfIndexName")] public string MappedEtfIndexName { get; init; } = ""; [JsonPropertyName("subtitle")] public string Subtitle { get; init; } = ""; [JsonPropertyName("searchSubtitle")] public string SearchSubtitle { get; init; } = ""; } public record TradeRepublicSynthetic : TradeRepublicAsset { [JsonPropertyName("derivativeProductCategories")] public IReadOnlyList DerivativeProductCategories { get; init; } = Array.Empty(); } // Anleihen public record TradeRepublicBond : TradeRepublicAsset { [JsonPropertyName("bondIssuerName")] public string BondIssuerName { get; init; } = ""; [JsonPropertyName("searchSubtitle")] public string SearchSubtitle { get; init; } = ""; } // Derivate (Hebeleffekte etc.) public record TradeRepublicDerivative : TradeRepublicAsset { [JsonPropertyName("derivativeProductCategories")] public IReadOnlyList DerivativeProductCategories { get; init; } = Array.Empty(); [JsonIgnore] public string? UnderlyingIsin { get { if (!string.IsNullOrEmpty(ImageId) && ImageId.StartsWith("logos/")) { var parts = ImageId.Split('/'); if (parts.Length >= 2) { return parts[1]; } } return null; } } } // 5. Custom Converter public class TradeRepublicAssetConverter : JsonConverter { public override TradeRepublicAsset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using var doc = JsonDocument.ParseValue(ref reader); var root = doc.RootElement; string? instrumentType = null; if (root.TryGetProperty("instrumentType", out var typeElement)) { instrumentType = typeElement.GetString(); } TradeRepublicAsset? result = instrumentType switch { "stock" => JsonSerializer.Deserialize(root.GetRawText(), options), "crypto" => JsonSerializer.Deserialize(root.GetRawText(), options), "fund" => JsonSerializer.Deserialize(root.GetRawText(), options), "synthetic" => JsonSerializer.Deserialize(root.GetRawText(), options), "bond" => JsonSerializer.Deserialize(root.GetRawText(), options), "derivative" => JsonSerializer.Deserialize(root.GetRawText(), options), _ => JsonSerializer.Deserialize(root.GetRawText(), options) }; return result ?? new TradeRepublicAssetFallback(); } public override void Write(Utf8JsonWriter writer, TradeRepublicAsset value, JsonSerializerOptions options) { JsonSerializer.Serialize(writer, value, value.GetType(), options); } } public record TradeRepublicAssetFallback : TradeRepublicAsset;