using System.Text.Json; using Flaro.Core.Library; using Flaro.Data; using Microsoft.EntityFrameworkCore; namespace Flaro.Api; /// Die saisonalen Anlässe, aus den Einstellungen. /// /// /// Als JSON in einer Zeile und nicht als Tabelle. Das hier ist /// Konfiguration, kein Bestand: eine Handvoll Einträge, die zusammen /// gelesen und zusammen geschrieben werden. Eine Tabelle dafür hiesse eine /// Migration für etwas, das niemand einzeln abfragt. /// public sealed class Saisoneinstellungen(FlaroContext db) { public const string Schluessel = "startseite.saisonal.anlaesse"; private IReadOnlyList? _gemerkt; public async Task> AnlaesseAsync(CancellationToken ct = default) { if (_gemerkt is { } fertig) return fertig; var zeile = await db.Settings.AsNoTracking() .FirstOrDefaultAsync(s => s.Key == Schluessel, ct); return _gemerkt = Lesen(zeile?.Value); } /// Liest die gespeicherte Liste — oder gibt die Vorgabe zurück. /// /// /// Unlesbares ist kein Grund, die Startseite zu verlieren. Steht /// dort Unsinn, gilt die Vorgabe; eine Ausnahme hier nähme dem Server /// die ganze Reihe und nicht nur den falschen Eintrag. /// public static IReadOnlyList Lesen(string? roh) { if (string.IsNullOrWhiteSpace(roh)) return Saisonanlass.Vorgabe; try { var gelesen = JsonSerializer.Deserialize>( roh, new JsonSerializerOptions(JsonSerializerDefaults.Web)); // Eine leere Liste ist eine Entscheidung — „keine saisonalen // Reihen" — und nicht dasselbe wie „nichts eingestellt". return gelesen is null ? Saisonanlass.Vorgabe : gelesen.Where(a => a.Brauchbar).ToList(); } catch (JsonException) { return Saisonanlass.Vorgabe; } } public static string Schreiben(IEnumerable anlaesse) => JsonSerializer.Serialize( anlaesse.Where(a => a.Brauchbar).ToList(), new JsonSerializerOptions(JsonSerializerDefaults.Web)); }