finish ton→gram migration: slug aliasing + overlay reconciliation - #708
Merged
Conversation
Diagnostic: after PR #705 (chain slug ton → gram), /chains/gram 404s and /benchmarks/network-fees still renders 'TON' in chain headings. Two root causes: 1. getBenchmarksForChain('gram') filters results[].slug === 'gram', but the materialize worker's KV snapshots still hold the legacy results[].slug === 'ton' (worker on Railway runs from the private mobula-api repo; it hasn't redeployed with the renamed YAML yet). → 0 matches → notFound() at chains/[slug]/page.tsx:90. 2. ChainHeadingsSummary renders r.name verbatim. Stored snapshots still carry name='TON', so the heading reads 'TON native transfer fee usd' even though chains.ts now says label='Gram'. Fix: introduce a chain-slug alias system so the canonical layer absorbs the rebrand without waiting on the harness. - src/lib/chains.ts: - CHAIN_SLUG_ALIASES { ton: 'gram' } — single source of truth. - canonicalChainSlug(slug) and chainLabelForSlug(slug) helpers. - getBenchmarksForChain now matches on the canonical slug + any legacy alias, so /chains/gram surfaces benches whose stored results still carry slug='ton'. - src/lib/spec.ts: - overlayEditorial reconciles stale stored results against the current spec. For each result whose slug is a known legacy alias (e.g. 'ton'), look up the spec provider by canonical slug ('gram'), rewrite result.slug + result.name to match. Downstream surfaces (leaderboard table, search dialog, ChainHeadings) all see the canonical identity without any per-component patch. - Cache keys bumped bench-unfiltered v12 → v13 and all-benchmarks v16 → v17 so the unstable_cache regenerates through the new reconciliation path on deploy. - src/components/chain-headings-summary.tsx: - Anchor id, link URL, and explainer lookup go through canonicalChainSlug so a stale 'ton' result still hits the renamed 'gram' explainer + lands at /benchmarks/<bench>/gram. - Display name resolves through chainLabelForSlug, with the bench result name as a fallback. Renders 'Gram' the moment chains.ts is updated — no wait on the materialize worker. Test plan: - /chains/gram → 200 with l1-finality + network-fees in the list. - /benchmarks/network-fees → chain heading reads 'Gram transaction fee usd', anchor id='gram', link to /benchmarks/network-fees/gram. - /api/citable still returns rows for both old + new slug surfaces (no impact on machine-readable consumers). - Harness on Railway can stay on chain='ton' label; the existing Prom regex straddle (PR #705) keeps queries hitting both labels.
This was referenced Jun 25, 2026
Flotapponnier added a commit
that referenced
this pull request
Jun 25, 2026
Follow-up to #708 / #711. The alias system was added but only applied to getBenchmarksForChain + ChainHeadingsSummary + overlayEditorial. Every other place that did a strict-equality chain-slug match still 404'd or rendered wrong when called with the canonical slug ('gram') while the YAML dimension / result row still held the legacy slug ('ton'). The user hit /benchmarks/wallet-labels-coverage/gram and got a 404. This PR pushes matchesChainSlug into every site that does a slug === match on a chain. New helper in src/lib/chain-aliases.ts: - matchesChainSlug(a, b) — both args optional, case-insensitive, resolves both sides through canonicalChainSlug. Replaces every '=== chain' on a chain-slug. - chainSlugSiblings(slug) — returns the set { canonical, ...legacy } for use as a filter Set. Patched 9 surfaces: - src/app/benchmarks/[slug]/[chain]/page.tsx — perChainExplainer lookup, results.find (row shape), dimensions.find (dimension shape), region variant fetch. /benchmarks/wallet-labels-coverage/gram now resolves. - src/app/api/badge/[slug]/[provider]/route.ts — chainLabel + cell param resolution. Badge endpoint accepts ?chain=gram. - src/app/api/bench/[slug]/variant/route.ts — variant filter validation. ?chain=gram no longer returns 'unknown chain'. - src/app/benchmarks/[slug]/share-card/route.tsx — OG share card chain pill resolution. - src/components/benchmark-body.tsx — client-side initial tab selection from ?chain= URL param. - src/app/chains/[slug]/page.tsx — per-bench dimension/result/route detection on the chain hub. - src/app/benchmarks/[slug]/opengraph-image.tsx — chain label on OG image. - src/app/benchmarks/[slug]/twitter-image.tsx — same for Twitter cards. - src/app/sitemap.ts — emits canonical slug URLs (/gram) instead of legacy (/ton) so crawlers don't waste budget on 308s. Per-chain explainer filter uses canonical comparison. What is NOT in this PR (deliberately): - Schema change to dimensions (value/prom_value/aliases) — too much surface, deferred to a separate refactor once harness rotates. - Harness Go code update (chain='ton' → 'gram' label) — separate Railway redeploy. - middleware-level URL canonicalization — next.config.ts redirects already cover the legacy /ton URLs; middleware adds nothing right now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the leftovers from #705 that the user spotted on staging/prod:
Bug 1:
/chains/gramreturns 404 becausegetBenchmarksForChain('gram')filtersresults[].slug === 'gram'but the materialize worker's Upstash snapshots still holdresults[].slug === 'ton'(the worker on Railway runs from a separate private repo and hasn't redeployed with the renamed YAML).Bug 2:
/benchmarks/network-feesstill renders 'TON native transfer fee usd' in the chain headings — ChainHeadingsSummary takesr.nameverbatim from the stale snapshot.Fix
Single source of truth:
CHAIN_SLUG_ALIASES = { ton: 'gram' }inchains.tsplus two helpers (canonicalChainSlug,chainLabelForSlug). Anywhere we have a slug we can resolve it to the canonical form + look up the registry label.spec.ts overlay reconciliation:
overlayEditorialnow rewrites stale stored results against the current spec. For each result whose slug is a known legacy alias, look up the spec provider by canonical slug, rewriteresult.slug+result.name. The whole downstream surface (leaderboard, search, ChainHeadings) sees the canonical identity without per-component patches.ChainHeadingsSummary: anchor id, link URL, explainer lookup, and display name all go through the new helpers. Renders 'Gram' the moment chains.ts is updated — no wait on the materialize worker.
Cache keys bumped: bench-unfiltered v12 → v13 and all-benchmarks v16 → v17 so unstable_cache regenerates through the new reconciliation path on deploy.
What I deliberately did NOT do
chain=~"ton|gram") keeps queries hitting whichever label the harness emits.Test plan