using Microsoft.Extensions.Logging; namespace SVSim.EmulatedEntrypoint.Services; /// /// Reads the static card-master blob from the app's output directory once at startup and /// hands the cached base64 string to ImmutableDataController. Singleton because the /// file is ~1.27 MB and gzip-decoding it on every request would burn CPU for no benefit. /// public interface ICardMasterPayloadProvider { /// True when the blob loaded successfully and serving is enabled. bool IsAvailable { get; } /// The verbatim base64 string ready for data.card_master. string Base64Blob { get; } } public sealed class CardMasterPayloadProvider : ICardMasterPayloadProvider { // Filename is pinned to the captured snapshot's date. When swapping the blob, update // this constant AND the hash in CardMasterConfig in the same change. private const string BlobFileName = "card_master_2026-06-03.txt"; public bool IsAvailable { get; } public string Base64Blob { get; } public CardMasterPayloadProvider(ILogger log) { var path = Path.Combine(AppContext.BaseDirectory, "Data", BlobFileName); if (!File.Exists(path)) { log.LogWarning("Card-master blob missing at {Path} — /immutable_data/card_master will 503.", path); Base64Blob = ""; IsAvailable = false; return; } Base64Blob = File.ReadAllText(path).Trim(); IsAvailable = Base64Blob.Length > 0; log.LogInformation("Loaded card-master blob ({Bytes} base64 chars).", Base64Blob.Length); } }