diff --git a/Data.SeaHavenIndustries/Migrations/20260715180000_WoFlagColor.cs b/Data.SeaHavenIndustries/Migrations/20260715180000_WoFlagColor.cs new file mode 100644 index 0000000..e48600e --- /dev/null +++ b/Data.SeaHavenIndustries/Migrations/20260715180000_WoFlagColor.cs @@ -0,0 +1,33 @@ +using Data.SeaHavenIndustries; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Data.SeaHavenIndustries.Migrations +{ + /// + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260715180000_WoFlagColor")] + public partial class WoFlagColor : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "FlagColor", + table: "workOrders", + type: "nvarchar(7)", + maxLength: 7, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "FlagColor", + table: "workOrders"); + } + } +} diff --git a/SeaHaven.Services/Helpers/WorkOrderFlagColors.cs b/SeaHaven.Services/Helpers/WorkOrderFlagColors.cs new file mode 100644 index 0000000..6892bd8 --- /dev/null +++ b/SeaHaven.Services/Helpers/WorkOrderFlagColors.cs @@ -0,0 +1,50 @@ +namespace SeaHaven.Services.Helpers +{ + /// + /// Fixed board flag palette (must match FE FLAG_COLORS). Values stored as canonical #RRGGBB. + /// + public static class WorkOrderFlagColors + { + public static readonly HashSet Allowed = new(StringComparer.OrdinalIgnoreCase) + { + "#EF4444", + "#F97316", + "#F59E0B", + "#EAB308", + "#22C55E", + "#14B8A6", + "#3B82F6", + "#8B5CF6" + }; + + /// + /// Normalizes to # + 6 uppercase hex digits, or null if empty. + /// Returns false if the value is non-empty but not a valid hex color. + /// + public static bool TryNormalize(string? value, out string? canonical) + { + canonical = null; + if (string.IsNullOrWhiteSpace(value)) + return true; + + var trimmed = value.Trim(); + if (trimmed.Length == 6 && trimmed[0] != '#') + trimmed = "#" + trimmed; + + if (trimmed.Length != 7 || trimmed[0] != '#') + return false; + + for (var i = 1; i < 7; i++) + { + if (!Char.IsAsciiHexDigit(trimmed[i])) + return false; + } + + canonical = "#" + trimmed[1..].ToUpperInvariant(); + return true; + } + + public static bool IsAllowed(string? canonical) + => canonical != null && Allowed.Contains(canonical); + } +}