Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

189 linhas
8.5KB

  1. using System.Text.Json;
  2. using Campaign_Tracker.Server.LegacyData.Models;
  3. namespace Campaign_Tracker.Server.LegacyData;
  4. /// <summary>
  5. /// In-memory implementation of <see cref="ILegacyDataAccess"/> for use in
  6. /// development environments without an Access database, and as the test double
  7. /// for integration tests.
  8. ///
  9. /// Accepts seeded collections via constructor so tests can inject specific
  10. /// records without coupling to file-system or network state.
  11. /// </summary>
  12. public sealed class InMemoryLegacyDataAccess : ILegacyDataAccess
  13. {
  14. private readonly IReadOnlyList<LegacyJurisdiction> _jurisdictions;
  15. private readonly IReadOnlyList<LegacyContact> _contacts;
  16. private readonly IReadOnlyList<LegacyKit> _kits;
  17. private readonly IReadOnlyList<LegacyKitLabel> _kitLabels;
  18. public InMemoryLegacyDataAccess(
  19. IReadOnlyList<LegacyJurisdiction>? jurisdictions = null,
  20. IReadOnlyList<LegacyContact>? contacts = null,
  21. IReadOnlyList<LegacyKit>? kits = null,
  22. IReadOnlyList<LegacyKitLabel>? kitLabels = null)
  23. {
  24. _jurisdictions = jurisdictions ?? DefaultJurisdictions;
  25. _contacts = contacts ?? DefaultContacts;
  26. _kits = kits ?? DefaultKits;
  27. _kitLabels = kitLabels ?? DefaultKitLabels;
  28. }
  29. /// <summary>
  30. /// Creates an instance seeded from a JSON file produced by the development-data
  31. /// export script. Falls back to the hardcoded defaults if the file is absent.
  32. /// </summary>
  33. public static InMemoryLegacyDataAccess FromJsonSeedFile(string jsonPath)
  34. {
  35. if (!File.Exists(jsonPath))
  36. return new InMemoryLegacyDataAccess();
  37. try
  38. {
  39. var json = File.ReadAllText(jsonPath);
  40. var records = JsonSerializer.Deserialize<JsonJurisdiction[]>(
  41. json, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? [];
  42. var jurisdictions = records
  43. .Where(r => !string.IsNullOrWhiteSpace(r.JCode))
  44. .DistinctBy(r => r.JCode!.Trim(), StringComparer.OrdinalIgnoreCase)
  45. .Select(r => new LegacyJurisdiction(
  46. r.JCode!.Trim(),
  47. string.IsNullOrWhiteSpace(r.Name) ? null : r.Name.Trim(),
  48. string.IsNullOrWhiteSpace(r.MailingAddress) ? null : r.MailingAddress.Trim(),
  49. string.IsNullOrWhiteSpace(r.CityStateZip) ? null : r.CityStateZip.Trim(),
  50. string.IsNullOrWhiteSpace(r.Imb) ? null : r.Imb.Trim(),
  51. string.IsNullOrWhiteSpace(r.ImbDigits) ? null : r.ImbDigits.Trim()))
  52. .ToArray();
  53. return new InMemoryLegacyDataAccess(jurisdictions: jurisdictions);
  54. }
  55. catch (Exception ex)
  56. {
  57. Console.Error.WriteLine($"[InMemoryLegacyDataAccess] Failed to load seed file '{jsonPath}': {ex.Message}. Falling back to hardcoded defaults.");
  58. return new InMemoryLegacyDataAccess();
  59. }
  60. }
  61. private sealed class JsonJurisdiction
  62. {
  63. public string? JCode { get; set; }
  64. public string? Name { get; set; }
  65. public string? MailingAddress { get; set; }
  66. public string? CityStateZip { get; set; }
  67. public string? Imb { get; set; }
  68. public string? ImbDigits { get; set; }
  69. }
  70. // ── Jurisdiction ──────────────────────────────────────────────────────────
  71. public Task<LegacyJurisdiction?> GetJurisdictionAsync(
  72. string jCode, CancellationToken cancellationToken = default)
  73. {
  74. var result = _jurisdictions.FirstOrDefault(j =>
  75. string.Equals(j.JCode, jCode, StringComparison.OrdinalIgnoreCase));
  76. return Task.FromResult(result);
  77. }
  78. public Task<IReadOnlyList<LegacyJurisdiction>> GetAllJurisdictionsAsync(
  79. CancellationToken cancellationToken = default) =>
  80. Task.FromResult(_jurisdictions);
  81. // ── Contact ───────────────────────────────────────────────────────────────
  82. public Task<LegacyContact?> GetContactByIdAsync(
  83. int id, CancellationToken cancellationToken = default)
  84. {
  85. var result = _contacts.FirstOrDefault(c => c.Id == id);
  86. return Task.FromResult(result);
  87. }
  88. public Task<IReadOnlyList<LegacyContact>> GetContactsByJurisdictionAsync(
  89. string jCode, CancellationToken cancellationToken = default)
  90. {
  91. IReadOnlyList<LegacyContact> result = _contacts
  92. .Where(c => string.Equals(c.JurisCode, jCode, StringComparison.OrdinalIgnoreCase))
  93. .ToList();
  94. return Task.FromResult(result);
  95. }
  96. // ── Kit ───────────────────────────────────────────────────────────────────
  97. public Task<LegacyKit?> GetKitByIdAsync(
  98. int id, CancellationToken cancellationToken = default)
  99. {
  100. var result = _kits.FirstOrDefault(k => k.Id == id);
  101. return Task.FromResult(result);
  102. }
  103. public Task<IReadOnlyList<LegacyKit>> GetKitsByJurisdictionAsync(
  104. string jCode, CancellationToken cancellationToken = default)
  105. {
  106. IReadOnlyList<LegacyKit> result = _kits
  107. .Where(k => string.Equals(k.JCode, jCode, StringComparison.OrdinalIgnoreCase))
  108. .ToList();
  109. return Task.FromResult(result);
  110. }
  111. // ── KitLabel ──────────────────────────────────────────────────────────────
  112. public Task<IReadOnlyList<LegacyKitLabel>> GetKitLabelsByKitAsync(
  113. int kitId, CancellationToken cancellationToken = default)
  114. {
  115. IReadOnlyList<LegacyKitLabel> result = _kitLabels
  116. .Where(l => l.KitId == kitId)
  117. .ToList();
  118. return Task.FromResult(result);
  119. }
  120. // ── Default seed data (representative dev/test records) ──────────────────
  121. private static readonly IReadOnlyList<LegacyJurisdiction> DefaultJurisdictions =
  122. [
  123. new("FAIR01", "Fairview Borough", "100 Main St", "Fairview, PA 16415", null, null),
  124. new("LAKE02", "Lake Township", "200 Lake Rd", "Lake City, PA 16423", null, null),
  125. new("PINE03", "Pine County", "300 Pine Ave", "Edinboro, PA 16412", null, null),
  126. ];
  127. private static readonly IReadOnlyList<LegacyContact> DefaultContacts =
  128. [
  129. new(1, "FAIR01", "Jane Doe", "Election Director", "jdoe@fairview.gov",
  130. "814-555-0101", null,
  131. "100 Main St", null, "Fairview, PA 16415",
  132. null, null, null, "Fairview Borough", "01"),
  133. new(2, "LAKE02", "John Smith", "Clerk", "jsmith@laketownship.gov",
  134. "814-555-0202", "814-555-0203",
  135. "200 Lake Rd", null, "Lake City, PA 16423",
  136. null, null, null, "Lake Township", "02"),
  137. ];
  138. private static readonly IReadOnlyList<LegacyKit> DefaultKits =
  139. [
  140. new(101, "FAIR01", "JOB-2026-001", "Inkjet", "Active", "fair01_primary_2026.mdb",
  141. Cass: true, InkJetJob: true,
  142. CreatedOn: new DateTime(2026, 3, 1, 0, 0, 0, DateTimeKind.Utc),
  143. ExportedToSnailWorks: null, LabelsPrinted: null,
  144. OfficeCopiesAmount: 50, InboundStid: "STI001", OutboundStid: "STO001"),
  145. new(102, "LAKE02", "JOB-2026-002", "OfficeCopy", "Pending", null,
  146. Cass: false, InkJetJob: false,
  147. CreatedOn: new DateTime(2026, 3, 5, 0, 0, 0, DateTimeKind.Utc),
  148. ExportedToSnailWorks: null, LabelsPrinted: null,
  149. OfficeCopiesAmount: 25, InboundStid: null, OutboundStid: null),
  150. ];
  151. private static readonly IReadOnlyList<LegacyKitLabel> DefaultKitLabels =
  152. [
  153. new(201, KitId: 101,
  154. InBoundImb: "0041234500012345678", InBoundImbDigits: "01-234-56789-12",
  155. InBoundSerial: "SN001",
  156. OutboundImb: "0041234500098765432", OutboundImbDigits: "01-234-56789-98",
  157. OutboundSerial: "SN002", SetNumber: 1),
  158. new(202, KitId: 101,
  159. InBoundImb: "0041234500022345678", InBoundImbDigits: "01-234-56789-22",
  160. InBoundSerial: "SN003",
  161. OutboundImb: "0041234500088765432", OutboundImbDigits: "01-234-56789-88",
  162. OutboundSerial: "SN004", SetNumber: 2),
  163. ];
  164. }

Powered by TurnKey Linux.