ワンクリックで
minimal-leaderboard-migration
Migrate leaderboard pages to htmxRazor by replacing badges only, preserving all backend and frontend contracts.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Migrate leaderboard pages to htmxRazor by replacing badges only, preserving all backend and frontend contracts.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Triage MCP test drift by separating stale assertions from real surface regressions after a partial metadata/tool refactor.
Render salary values with a stable dollar sign in Razor views without depending on host culture.
Generate PostgreSQL CREATE TABLE scripts directly from live SQLite metadata without hand-transcribing Lahman-style schemas.
Audit htmxRazor asset imports and cache behavior after a migration slice without breaking shell-owned runtime contracts.
Preserve the global search dropdown + all-results modal contracts while migrating Razor/htmx page markup around a shell-owned search surface.
Build Razor Page detail screens from projected records and dedicated view models instead of passing entities or PageModels into partials.
| name | minimal-leaderboard-migration |
| description | Migrate leaderboard pages to htmxRazor by replacing badges only, preserving all backend and frontend contracts. |
| domain | frontend-backend |
| confidence | high |
| source | earned |
Use this pattern when migrating leaderboard-style pages that already follow best practices: projection-first queries, expression-tree ordering, response caching, filter forms with htmx wiring, and pagination. The page works correctly and needs minimal htmxRazor adoption.
✅ Use this pattern for:
❌ Don't use this pattern for:
Look for Bootstrap badges that can be replaced with htmxRazor equivalents:
<!-- BEFORE -->
<span class="badge bg-light text-dark">@count players</span>
<span class="hof-badge">HOF</span>
<!-- AFTER -->
<rhx-badge rhx-variant="neutral">@count players</rhx-badge>
<rhx-badge rhx-variant="warning" rhx-size="sm">HOF</rhx-badge>
Badge Variant Guide:
neutral — Non-interactive metadata (counts, totals)warning — Achievements, awards, special status (HOF, All-Star)success — Active/positive statusbrand — Team/league affiliationDO NOT change:
/Stats/Batting)OnGetAsync parameters)stat, fromYear, toYear, league, minAb, singleSeason, page)[ResponseCache(Duration=3600, VaryByHeader="HX-Request")])batting_years, batting_leagues, hof_player_ids)DO NOT change:
#filter-form)#leaderboard, #loading-indicator)hx-get, hx-include, hx-target, hx-indicator, hx-push-url)hx-get="/Players/Modal/{id}" with hx-target="#modal-container")DO NOT add new tests unless you're changing behavior. Badge replacements are presentational only.
Run existing test suite:
dotnet build baseball-history.sln --no-restore
dotnet test baseball-history-tests --no-build
Expected: All tests pass (350+), no regressions.
Changed:
<span class="hof-badge"> → <rhx-badge rhx-variant="warning" rhx-size="sm"><span class="badge bg-light text-dark"> → <rhx-badge rhx-variant="neutral">Preserved:
Result: 350/350 tests passing, zero regressions
Changed:
<span class="hof-badge ms-1">HOF</span> → <rhx-badge rhx-variant="warning" rhx-size="sm" class="ms-1">HOF</rhx-badge><span class="badge bg-light text-dark"> → <rhx-badge rhx-variant="neutral">Preserved:
Result: 306/306 tests passing, zero regressions
Changes made:
_PitchingLeaders.cshtml: Replaced <span class="hof-badge ms-1"> with <rhx-badge rhx-variant="warning" rhx-size="sm" class="ms-1"><span class="badge bg-light text-dark"> with <rhx-badge rhx-variant="neutral">Preserved:
// WRONG — Don't extract shared expression tree helpers during migration
public static class SharedOrderingHelpers { ... }
// RIGHT — Preserve existing duplication, defer refactor to separate task
private static IOrderedQueryable<T> ApplyBattingOrder<T>(...) { ... }
<!-- WRONG — Don't consolidate or redesign filters during migration -->
<rhx-filter-group> ... </rhx-filter-group>
<!-- RIGHT — Keep existing filter form, only replace badges -->
<form id="filter-form">
<select class="form-select" name="stat" hx-get="..." ...>
<!-- WRONG — Don't add new filters, sorting modes, or export buttons -->
<button hx-get="/Stats/Batting/Export">Export CSV</button>
<!-- RIGHT — Migrate existing features only -->
<!-- WRONG — Don't remove existing loading behavior -->
<!-- (no loading indicator) -->
<!-- RIGHT — Preserve existing loading overlay and spinner -->
<div id="loading-indicator" class="htmx-indicator loading-overlay">
@await Html.PartialAsync("Components/_LoadingSpinner", "Loading stats...")
</div>
Before declaring migration complete:
## Issue #XX: [Page Name] Leaders Migration
**Changed:**
- Badge 1: [old markup] → `<rhx-badge rhx-variant="...">`
- Badge 2: [old markup] → `<rhx-badge rhx-variant="...">`
**Preserved:**
- N stat ordering expressions ([list])
- [Query mode descriptions]
- Filter form with N controls
- All backend contracts (routes, handlers, cache keys)
- All frontend contracts (targets, indicators, pagination)
**Result:** [N]/[N] tests passing, zero regressions
**Blockers for next page:** NONE
If you encounter any of these, do not use this minimal pattern:
.Include() without projection (refactor to projection-first first)VaryByHeader="HX-Request" (add it first)Principle: Only migrate pages that are already well-architected. Fix underlying issues before applying cosmetic htmxRazor adoption.