Sweep all .cshtml files for encoding corruption; add pre-commit guard

Replace all corruption variants with HTML entities across 226 view files:
- 3-char UTF-8-as-Win1252 sequences (ae-corruption)
- Standalone smart/curly quotes that break C# Razor expressions
- Partially re-corrupted variants where the 3rd byte was normalised to ASCII

tools/Fix-Encoding.ps1: re-runnable sweep; uses [char] code points so the
script itself never contains a literal non-ASCII character; supports -DryRun

.githooks/pre-commit: blocks commits containing the ae-corruption byte
signature (xc3xa2xe2x82xac); git core.hooksPath = .githooks so the
hook is repo-committed and active for all future work on this machine.

Build clean; 225 unit tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-20 21:37:10 -04:00
parent 21b39161a3
commit a0bdd2b5b4
252 changed files with 1785 additions and 1633 deletions
@@ -87,7 +87,7 @@
{
<div class="card border-0 shadow-sm">
<div class="card-header bg-transparent">
<h6 class="mb-0"><i class="bi bi-box-seam me-2"></i>Powder Demand vs. Stock Active Jobs</h6>
<h6 class="mb-0"><i class="bi bi-box-seam me-2"></i>Powder Demand vs. Stock &mdash; Active Jobs</h6>
</div>
<div class="table-responsive">
<table class="table table-hover mb-0">
@@ -115,7 +115,7 @@
<td class="text-end fw-semibold">@item.CurrentStockLbs.ToString("0.##") lbs</td>
<td class="text-end">@item.ScheduledDemandLbs.ToString("0.##") lbs</td>
<td class="text-end @(item.ShortfallLbs > 0 ? "text-danger fw-bold" : "text-muted")">
@(item.ShortfallLbs > 0 ? $"{item.ShortfallLbs:0.##} lbs" : "")
@(item.ShortfallLbs > 0 ? $"{item.ShortfallLbs:0.##} lbs" : "&mdash;")
</td>
<td class="text-center">@item.ActiveJobCount</td>
<td class="text-center">
@@ -157,7 +157,7 @@
else if (!Model.EfficiencyBySku.Any())
{
<div class="text-center py-5 text-muted">
<p>No efficiency data yet record actual powder usage on completed jobs to see this chart.</p>
<p>No efficiency data yet &mdash; record actual powder usage on completed jobs to see this chart.</p>
</div>
}
else
@@ -192,7 +192,7 @@
}
@if (!eff.HasEnoughData)
{
<br /><small class="text-muted fst-italic">Low confidence need 5+ samples</small>
<br /><small class="text-muted fst-italic">Low confidence &mdash; need 5+ samples</small>
}
</td>
<td class="text-end">@eff.CatalogCoverageSqFtPerLb.ToString("0.#") sq ft/lb</td>
@@ -238,9 +238,9 @@
<div class="alert alert-info alert-permanent text-start">
<h6 class="alert-heading"><i class="bi bi-lightbulb me-2"></i>What unlocks here</h6>
<ul class="mb-0 small">
<li><strong>Smart reorder suggestions</strong> quantity recommendations based on your actual usage history + scheduled job pipeline</li>
<li><strong>Waste pattern detection</strong> identifies jobs and powder types that consistently over-consume</li>
<li><strong>Per-powder efficiency corrections</strong> suggests updating coverage defaults based on real data</li>
<li><strong>Smart reorder suggestions</strong> &mdash; quantity recommendations based on your actual usage history + scheduled job pipeline</li>
<li><strong>Waste pattern detection</strong> &mdash; identifies jobs and powder types that consistently over-consume</li>
<li><strong>Per-powder efficiency corrections</strong> &mdash; suggests updating coverage defaults based on real data</li>
</ul>
</div>
</div>
@@ -258,7 +258,7 @@
</div>
@if (!Model.ReorderSuggestions.Any())
{
<div class="card-body text-muted text-center py-4">No reorder suggestions stock levels look good for upcoming pipeline.</div>
<div class="card-body text-muted text-center py-4">No reorder suggestions &mdash; stock levels look good for upcoming pipeline.</div>
}
else
{
@@ -311,7 +311,7 @@
@* Waste Patterns *@
<div class="card border-0 shadow-sm">
<div class="card-header bg-transparent">
<h6 class="mb-0"><i class="bi bi-exclamation-triangle me-2 text-warning"></i>Waste Patterns <small class="text-muted fw-normal"> coats that used &gt;20% more than estimated</small></h6>
<h6 class="mb-0"><i class="bi bi-exclamation-triangle me-2 text-warning"></i>Waste Patterns <small class="text-muted fw-normal">&mdash; coats that used &gt;20% more than estimated</small></h6>
</div>
@if (!Model.WastePatterns.Any())
{
@@ -344,7 +344,7 @@
<br /><small class="text-muted">@w.CoatName</small>
</td>
<td class="text-muted small">@(w.InventoryItemName ?? "Custom")</td>
<td>@(w.Complexity ?? "")</td>
<td>@(w.Complexity ?? "&mdash;")</td>
<td class="text-end">@w.EstimatedLbs.ToString("0.##") lbs</td>
<td class="text-end">@w.ActualLbs.ToString("0.##") lbs</td>
<td class="text-end text-danger fw-bold">+@w.OveragePct.ToString("0.#")%</td>