SEO generator: derive market list from on-chain registry (replaces dead Supabase)#92
Open
krandder wants to merge 1 commit into
Open
SEO generator: derive market list from on-chain registry (replaces dead Supabase)#92krandder wants to merge 1 commit into
krandder wants to merge 1 commit into
Conversation
The build-time SEO generator (scripts/generate-seo.mjs) read the market list from the Supabase market_event table and AI blurbs from ai_prompts via OpenAI. The Supabase project is deleted, so the script could not run at all and src/config/markets.js was frozen at 29 hardcoded entries — new markets never got a canonical /markets/<address> static page (getStaticPaths uses fallback: false with static export). The generator now fetches the same Checkpoint registry indexer the frontend runtime uses (https://api.futarchy.fi/registry/graphql, aggregator 0xC5eB...4Fc1) with the same three flat queries as useAggregatorProposals.js, using plain fetch — no new dependencies, no Supabase, no OpenAI. - src/config/legacy-seo.json: checked-in snapshot of the 29 Supabase/OpenAI-era entries. Their URLs and meta content are preserved verbatim; lifecycle status (isActive, resolution) is refreshed from the registry when the market is still listed there. - New registry markets get template SEO built from displayNameQuestion/Event, proposal description, org metadata (logo/coverImage) and mapped-seo.json image overrides. Archived and hidden (staging/test) entries are skipped, matching frontend list behaviour; duplicate metadata entities for one proposalAddress are deduped deterministically. - Fail-loud policy: unreachable endpoint, GraphQL errors, missing aggregator, zero orgs/proposals, or an output smaller than the legacy snapshot all exit non-zero, so a build can never silently ship with an empty market list. - Regenerated markets.js: 38 markets (29 legacy + 9 new from the registry). - Removed scripts/test-market-events.js (dead Supabase debug script; its dependency was dropped in PR #90). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
✅ Deploy Preview for futarchy ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
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 free
to 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.
What
Rewrites
scripts/generate-seo.mjsso the static-page market list comes from the on-chain registry (the Checkpoint indexer athttps://api.futarchy.fi/registry/graphql, aggregator0xC5eB43D53e2FE5FddE5faf400CC4167e5b5d4Fc1) instead of the deleted Supabase project (nvhqdqtlsdboctqjcelq.supabase.co). No Supabase, no OpenAI, no new dependencies — plainfetchwith the same three flat GraphQL queries the runtime already uses insrc/hooks/useAggregatorProposals.js.Why
generate-seo.mjswas the only thing that could updatesrc/config/markets.js, which drivesgetStaticPaths(fallback: false, static export) insrc/pages/markets/[address].js. With Supabase gone the script could not run at all, so the market list was frozen at 29 entries and new markets never got a canonical/markets/<address>static page or OG/Twitter meta. Now any market in the registry is picked up automatically at the nextgenerate-seo+ build, with no manual list edit.Data-source swap
market_eventtable (deleted)aggregator→organizations→proposalentitiesai_promptsprompt template)displayNameQuestion/displayNameEvent, proposaldescription, proposal/org metadata JSONmapped-seo.jsonmapped-seo.jsonoverride → proposalmetadata.seo.image→ orgcoverImage/logo→ generic fallbackRegistry today: 7 organizations, 22 proposal entities, 20 unique market addresses (duplicate metadata entities for one
proposalAddressare deduped deterministically: non-archived > has-SEO > smallest entity id). Archived andvisibility: hiddenentries are skipped for new pages, matching the frontend list behaviour — they get pages automatically once made public.Legacy content
The AI blurbs had no registry equivalent, so the 29 existing entries' generated content (titles, descriptions, images, keywords) is snapshotted verbatim into a new checked-in file,
src/config/legacy-seo.json. The generator merges it first:isActive/resolution status is refreshed from registry metadata.isActive: false(they're not shown in the registry-fed frontend list anyway)./markets/<address>links.Fail-loud policy
The generator exits non-zero (aborting
build-with-seo) on: unreachable endpoint, HTTP/GraphQL errors, missing aggregator, zero organizations, zero proposals, or an output smaller than the legacy snapshot. A silent empty market list can never ship. Output is deterministic (no AI, no timestamps; two consecutive runs are byte-identical).Verified
node scripts/generate-seo.mjs→ 38 markets written (29 legacy + 9 new), byte-identical on re-run; bogus endpoint → exit 1.npm run build→ static export succeeds, 38/markets/<address>.htmlpages with correct OG meta (spot-checked GIP-151).npm run auto-qa:test:unit→ 692/692 pass, including the@supabase/supabase-jsimport ratchet at 0. Also deletedscripts/test-market-events.js, the last file anywhere importing@supabase/supabase-js(dead since PR Remove remaining Supabase clients and drop @supabase/supabase-js #90 dropped the dependency).Build wiring recommendation (not done in this PR)
generate-seostill only runs via the optionalbuild-with-seoscript; plainbuilduses whatevermarkets.jsis checked in. Recommendation: makebuild-with-seothe defaultbuildin CI/Netlify — the generator is now dependency-free, fast (3 GraphQL queries), deterministic, and fail-loud, so the historical reasons to keep it out of the default path (Supabase creds, OpenAI cost/nondeterminism) are gone. Left unwired here to avoid unilaterally changing deploy behaviour; it's a one-line change ("build": "npm run generate-seo && next build") once ops signs off. Until then, committing the regeneratedmarkets.js(as this PR does) keeps plain builds correct.🤖 Generated with Claude Code