using Aetheria.State; using Aetheria.State.Documents; var root = args.Length > 0 ? Path.GetFullPath(args[0]) : Directory.GetCurrentDirectory(); var statePath = args.Length > 1 ? Path.GetFullPath(args[1]) : AetheriaStatePaths.ResolveDefaultStatePath(root); await using var node = await AetheriaStateNode.OpenAsync(statePath, "aetheria-state-verify"); var ledger = await node.GetMigrationLedgerAsync() ?? throw new InvalidOperationException("Missing typed migration ledger."); var quarantine = await node.GetLegacyCatalogQuarantineAsync() ?? throw new InvalidOperationException("Missing legacy catalog quarantine document."); var items = node.Cache.GetAll().ToArray(); var corporations = node.Cache.GetAll().ToArray(); var nameFiles = node.Cache.GetAll().ToArray(); RequireCount(ledger, "aetheria.item_definition.v1", items.Length); RequireCount(ledger, "aetheria.corporation.v1", corporations.Length); RequireCount(ledger, "aetheria.name_file.v1", nameFiles.Length); if (items.Length == 0) { throw new InvalidOperationException("Typed state has no item definitions."); } if (corporations.Length == 0) { throw new InvalidOperationException("Typed state has no corporations."); } if (nameFiles.Length == 0) { throw new InvalidOperationException("Typed state has no name files."); } await RequireLegacyLookupAsync( items[0].LegacyId, () => node.GetItemDefinitionByLegacyIdAsync(items[0].LegacyId), "item definition"); await RequireLegacyLookupAsync( corporations[0].LegacyId, () => node.GetCorporationByLegacyIdAsync(corporations[0].LegacyId), "corporation"); await RequireLegacyLookupAsync( nameFiles[0].LegacyId, () => node.GetNameFileByLegacyIdAsync(nameFiles[0].LegacyId), "name file"); if (string.IsNullOrWhiteSpace(quarantine.CatalogFingerprint)) { throw new InvalidOperationException("Legacy catalog quarantine has no catalog fingerprint."); } Console.WriteLine($"Aetheria typed state verify passed: {statePath}"); Console.WriteLine($"Catalog fingerprint: {quarantine.CatalogFingerprint}"); Console.WriteLine($"Item definitions: {items.Length}"); Console.WriteLine($"Corporations: {corporations.Length}"); Console.WriteLine($"Name files: {nameFiles.Length}"); static void RequireCount(AetheriaMigrationLedger ledger, string documentType, int actual) { var expected = ledger.Counts.FirstOrDefault(count => count.DocumentType == documentType)?.Count; if (expected == null) { throw new InvalidOperationException($"Migration ledger is missing count for {documentType}."); } if (expected.Value != actual) { throw new InvalidOperationException( $"Migration ledger count mismatch for {documentType}: ledger={expected.Value}, actual={actual}."); } } static async Task RequireLegacyLookupAsync( string legacyId, Func> lookup, string label) where T : class { if (string.IsNullOrWhiteSpace(legacyId)) { throw new InvalidOperationException($"Cannot verify {label}: legacy id is empty."); } var value = await lookup().ConfigureAwait(false); if (value == null) { throw new InvalidOperationException($"Typed legacy-id lookup failed for {label} {legacyId}."); } }