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
@@ -46,19 +46,19 @@
<dd class="col-7">@Model.EntityType</dd>
<dt class="col-5 text-muted">Entity ID</dt>
<dd class="col-7">@(Model.EntityId ?? "")</dd>
<dd class="col-7">@(Model.EntityId ?? "&mdash;")</dd>
<dt class="col-5 text-muted">Description</dt>
<dd class="col-7">@(Model.EntityDescription ?? "")</dd>
<dd class="col-7">@(Model.EntityDescription ?? "&mdash;")</dd>
<dt class="col-5 text-muted">User</dt>
<dd class="col-7">@Model.UserName</dd>
<dt class="col-5 text-muted">Company</dt>
<dd class="col-7">@(Model.CompanyName ?? (Model.CompanyId?.ToString() ?? ""))</dd>
<dd class="col-7">@(Model.CompanyName ?? (Model.CompanyId?.ToString() ?? "&mdash;"))</dd>
<dt class="col-5 text-muted">IP Address</dt>
<dd class="col-7">@(Model.IpAddress ?? "")</dd>
<dd class="col-7">@(Model.IpAddress ?? "&mdash;")</dd>
</dl>
</div>
</div>
@@ -95,8 +95,8 @@
var newVal = newData.ValueKind == JsonValueKind.Object && newData.TryGetProperty(key, out var nv) ? nv.ToString() : null;
<tr>
<td class="fw-medium">@key</td>
<td class="text-danger font-monospace">@(oldVal ?? "")</td>
<td class="text-success font-monospace">@(newVal ?? "")</td>
<td class="text-danger font-monospace">@(oldVal ?? "&mdash;")</td>
<td class="text-success font-monospace">@(newVal ?? "&mdash;")</td>
</tr>
}
}
@@ -55,7 +55,7 @@
<form method="get" class="row g-2 align-items-end">
<div class="col-md-3">
<input name="search" value="@ViewBag.Search" class="form-control form-control-sm"
placeholder="User, entity name, ID" />
placeholder="User, entity name, ID&hellip;" />
</div>
<div class="col-md-2">
<select name="entityType" class="form-select form-select-sm">
@@ -145,7 +145,7 @@
</table>
</div>
<!-- Mobile card view shown on screens < 992px (table-responsive hidden by mobile-cards.css) -->
<!-- Mobile card view &mdash; shown on screens < 992px (table-responsive hidden by mobile-cards.css) -->
<div class="mobile-card-view">
<div class="mobile-card-list">
@if (!Model.Any())
@@ -196,7 +196,7 @@
{
<div class="card-footer d-flex align-items-center justify-content-between py-2">
<small class="text-muted">
Showing @((page - 1) * pageSize + 1)@Math.Min(page * pageSize, totalCount) of @totalCount.ToString("N0")
Showing @((page - 1) * pageSize + 1)&ndash;@Math.Min(page * pageSize, totalCount) of @totalCount.ToString("N0")
</small>
<nav>
<ul class="pagination pagination-sm mb-0">