Merge pull request #133 from Sea-Haven-Industries/feat/ab/sh-348-dashboard-region
Some checks are pending
Validate and deploy / Validate deployable source bundle (push) Waiting to run
Validate and deploy / Deploy shoc-backend-dev through Terraform (push) Blocked by required conditions
Validate and deploy / Deploy shoc-backend-staging to Elastic Beanstalk (push) Blocked by required conditions

SH-348: Add dashboard region metrics
This commit is contained in:
Alexandre Brandizzi 2026-09-17 01:36:09 -03:00 • committed by GitHub
commit 782165a4cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 4 deletions

View file

@ -358,11 +358,17 @@ public class DashboardServiceTests
ctx.Locations.AddRange(
new Locations { Id = 1, State = "NY" },
new Locations { Id = 2, State = "ca" },
new Locations { Id = 3, State = "XX" });
new Locations { Id = 3, State = "XX" },
new Locations { Id = 4, State = "indiana" },
new Locations { Id = 5, State = "NEW YORK" },
new Locations { Id = 6, State = "California" });
ctx.workOrders.AddRange(
new WorkOrder { AccountId = 1, LocationId = 1 },
new WorkOrder { AccountId = 1, LocationId = 2 },
new WorkOrder { AccountId = 1, LocationId = 3 },
new WorkOrder { AccountId = 1, LocationId = 4 },
new WorkOrder { AccountId = 1, LocationId = 5 },
new WorkOrder { AccountId = 1, LocationId = 6 },
new WorkOrder { AccountId = 1, LocationId = null });
await ctx.SaveChangesAsync();
@ -371,7 +377,28 @@ public class DashboardServiceTests
result.Items.Select(row => row.Region).Should().Equal(
"East", "Central", "West", "California", "Unmapped/Other");
result.Items.Select(row => row.WorkOrderCount).Should().Equal(1, 0, 0, 1, 2);
// NY + "NEW YORK" -> East; "indiana" -> Central; "ca" + "California" -> California;
// "XX" + unassigned location -> Unmapped/Other. Full-name storage forms must not
// fall through to Unmapped/Other (SH-348 review).
result.Items.Select(row => row.WorkOrderCount).Should().Equal(2, 1, 0, 2, 2);
}
[Fact]
public void Resolve_MapsEveryUsStateAndItsFullNameToACanonicalBucket()
{
foreach (var code in UsStateCodes.All)
{
var byCode = DashboardRegions.Resolve(code);
byCode.Should().NotBe(
"Unmapped/Other",
$"state code {code} must belong to a canonical region");
var fullName = UsStateCodes.ExpandStorageValues(new[] { code })
.First(value => value != code);
DashboardRegions.Resolve(fullName).Should().Be(
byCode,
$"the full-name storage form of {code} must resolve to the same region as the code");
}
}
[Fact]

View file

@ -9,10 +9,11 @@ public static class DashboardRegions
public static string Resolve(string? state)
{
if (string.IsNullOrWhiteSpace(state))
var code = UsStateCodes.ToCode(state);
if (code is null)
return "Unmapped/Other";
return StateToRegion.TryGetValue(state.Trim().ToUpperInvariant(), out var region)
return StateToRegion.TryGetValue(code, out var region)
? region
: "Unmapped/Other";
}

View file

@ -56,8 +56,29 @@ namespace SeaHaven.Services.Helpers
["WY"] = "WYOMING"
};
private static readonly IReadOnlyDictionary<string, string> CodesByName =
Names.ToDictionary(pair => pair.Value, pair => pair.Key, StringComparer.Ordinal);
public static IReadOnlySet<string> All { get; } = new HashSet<string>(Names.Keys, StringComparer.Ordinal);
/// <summary>
/// Normalises a stored state value to its two-letter postal code. Accepts either a
/// postal code ("IN") or a full state name ("Indiana"), case-insensitively, matching
/// the storage forms produced by <see cref="ExpandStorageValues"/>. Returns null when
/// the value is blank or is not a recognised US state.
/// </summary>
public static string? ToCode(string? value)
{
if (string.IsNullOrWhiteSpace(value))
return null;
var normalized = value.Trim().ToUpperInvariant();
if (All.Contains(normalized))
return normalized;
return CodesByName.TryGetValue(normalized, out var code) ? code : null;
}
public static IReadOnlyCollection<string> ExpandStorageValues(IEnumerable<string> codes)
{
return codes