using System.Security.Cryptography; using System.Text; namespace Shared.Excel; public static class ImportSourceSignature { public static string Create(IEnumerable columns) { var canonical = string.Join("|", columns.Select(Normalize).Order(StringComparer.Ordinal)); return Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(canonical))).ToLowerInvariant(); } private static string Normalize(string value) => new(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } public interface IImportMappingSuggester { Task> SuggestAsync( IReadOnlyList unmappedColumns, ImportDefinition definition, CancellationToken ct); } /// /// Safe default. A production AI adapter can replace this registration. The adapter must return /// only target fields present in ImportDefinition and never mutate data or persist a mapping by itself. /// public sealed class NoopImportMappingSuggester : IImportMappingSuggester { public Task> SuggestAsync( IReadOnlyList unmappedColumns, ImportDefinition definition, CancellationToken ct) => Task.FromResult>([]); }