Skip to content

finish ton→gram migration: slug aliasing + overlay reconciliation - #708

Merged
Flotapponnier merged 1 commit into
mainfrom
chore/ton-gram-finish-migration
Jun 25, 2026
Merged

finish ton→gram migration: slug aliasing + overlay reconciliation#708
Flotapponnier merged 1 commit into
mainfrom
chore/ton-gram-finish-migration

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

Fixes the leftovers from #705 that the user spotted on staging/prod:

Bug 1: /chains/gram returns 404 because getBenchmarksForChain('gram') filters results[].slug === 'gram' but the materialize worker's Upstash snapshots still hold results[].slug === 'ton' (the worker on Railway runs from a separate private repo and hasn't redeployed with the renamed YAML).

Bug 2: /benchmarks/network-fees still renders 'TON native transfer fee usd' in the chain headings — ChainHeadingsSummary takes r.name verbatim from the stale snapshot.

Fix

Single source of truth: CHAIN_SLUG_ALIASES = { ton: 'gram' } in chains.ts plus 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: overlayEditorial now 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, rewrite result.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

Test plan

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.
@Flotapponnier
Flotapponnier changed the base branch from dev to main June 25, 2026 13:33
@Flotapponnier
Flotapponnier merged commit 524bc3c into main 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.
@Flotapponnier
Flotapponnier deleted the chore/ton-gram-finish-migration branch July 17, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant