Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

80 Zeilen
3.3KB

  1. namespace Campaign_Tracker.Server.ExtensionData;
  2. /// <summary>
  3. /// Implements <see cref="ILegacyLinkIntegrityCheck"/> by scanning every record supplied
  4. /// by the registered <see cref="ILegacyLinkedRecordProvider"/> implementations and
  5. /// validating each one's legacy link through <see cref="ILegacyLinkValidator"/> (AC #4).
  6. /// When no providers are registered (i.e. no extension records exist yet), the report
  7. /// reflects zero records and 100% consistency.
  8. /// </summary>
  9. public sealed class LegacyLinkIntegrityService : ILegacyLinkIntegrityCheck
  10. {
  11. private readonly IEnumerable<ILegacyLinkedRecordProvider> _providers;
  12. private readonly ILegacyLinkValidator _validator;
  13. private readonly TimeProvider _timeProvider;
  14. public LegacyLinkIntegrityService(
  15. IEnumerable<ILegacyLinkedRecordProvider> providers,
  16. ILegacyLinkValidator validator,
  17. TimeProvider timeProvider)
  18. {
  19. _providers = providers;
  20. _validator = validator;
  21. _timeProvider = timeProvider;
  22. }
  23. public async Task<LegacyLinkIntegrityReport> CheckAsync(CancellationToken cancellationToken = default)
  24. {
  25. var failures = new List<LegacyLinkIntegrityFailure>();
  26. var seenLinks = new Dictionary<string, ILegacyLinkedRecord>(StringComparer.OrdinalIgnoreCase);
  27. var providers = _providers.ToArray();
  28. int total = 0;
  29. foreach (var provider in providers)
  30. {
  31. var records = await provider.GetAllAsync(cancellationToken);
  32. foreach (var record in records)
  33. {
  34. total++;
  35. var result = await _validator.ValidateAsync(record.LegacyLink, cancellationToken);
  36. if (!result.IsValid)
  37. {
  38. failures.Add(new LegacyLinkIntegrityFailure(
  39. record.RecordType,
  40. record.RecordId,
  41. record.LegacyLink,
  42. result.Error ?? "Unknown validation error"));
  43. }
  44. var linkKey = $"{record.LegacyLink.Type}:{record.LegacyLink.Value}";
  45. if (seenLinks.TryGetValue(linkKey, out var existing) &&
  46. (!string.Equals(existing.RecordType, record.RecordType, StringComparison.OrdinalIgnoreCase) ||
  47. !string.Equals(existing.RecordId, record.RecordId, StringComparison.OrdinalIgnoreCase)))
  48. {
  49. failures.Add(new LegacyLinkIntegrityFailure(
  50. record.RecordType,
  51. record.RecordId,
  52. record.LegacyLink,
  53. $"Legacy reference is also linked by {existing.RecordType} '{existing.RecordId}', creating an ambiguous active-record join."));
  54. }
  55. else
  56. {
  57. seenLinks[linkKey] = record;
  58. }
  59. }
  60. }
  61. int consistent = total - failures.Count;
  62. double pct = total == 0 ? 100.0 : (consistent / (double)total) * 100.0;
  63. return new LegacyLinkIntegrityReport(
  64. CheckedAt: _timeProvider.GetUtcNow(),
  65. ProviderCount: providers.Length,
  66. TotalRecords: total,
  67. ConsistentRecords: consistent,
  68. FailedRecords: failures.Count,
  69. ConsistencyPercentage: Math.Round(pct, 4),
  70. Failures: failures);
  71. }
  72. }

Powered by TurnKey Linux.