Contexto
O convite de sala é o loop de aquisição nº1 do CodeRacer: sem login, a única forma de alguém chegar
ao produto por indicação é receber um /room/<code> de um amigo. A frota já construiu as duas pontas
do gesto — copyLink() em src/components/Lobby.tsx:60-65 e o chip "copiar link" em
src/components/RoomView.tsx:265-269 — e a chegada é ótima (o NameGate em
src/components/RoomView.tsx:178-215 já diz "você foi convidado", mostra o código e pré-preenche o
nick do localStorage). O elo fraco é o meio do caminho: como esse link aparece no chat.
Dois defeitos independentes, ambos conferidos na produção (2026-08-01):
1. O robots.txt bloqueia o próprio unfurl. src/app/robots.ts:13 publica Disallow: /room/.
Vários unfurlers respeitam robots.txt antes de buscar a página (Slackbot e Twitterbot são os casos
documentados; Discord e WhatsApp normalmente não). O comentário em src/app/robots.ts:4-6 justifica o
bloqueio por indexação — mas indexação já está impedida pelo robots: { index: false, follow: false }
de src/app/room/[id]/page.tsx:12, que é o mecanismo certo para isso. O Disallow não acrescenta
proteção de índice e custa o preview do convite nos clientes que o respeitam.
2. Quando o unfurl acontece, o card não fala da sala. A rota define title/description próprios
(src/app/room/[id]/page.tsx:9-14) mas nenhum openGraph, então herda a imagem genérica da home.
O convite vira mais um card institucional do CodeRacer em vez de "sala ABC123, entra aí".
Ordem sugerida: puxar depois da #117. Enquanto a origem pública estiver errada, o og:image
aponta para um host 503 e nenhum card renderiza — o efeito desta issue não seria observável.
Não é bloqueio de código: os diffs não se sobrepõem.
Escopo
src/app/robots.ts — parar de bloquear o fetch de /room/, mantendo as salas fora do índice pela
meta noindex que já existe na rota. Atualizar o comentário para registrar a distinção entre
"não indexar" e "não deixar buscar". /harness/ continua bloqueado.
- Imagem OG por sala, derivada exclusivamente do código presente na URL — sem nenhuma leitura de
banco: código em destaque, marca, e uma chamada curta ("entre na corrida"). Espelhar o shape de
src/app/opengraph-image.tsx em vez de inventar um novo.
openGraph/twitter na metadata da rota da sala, para o card usar o título específico que ela já
monta (Sala <CODE> — entre na corrida) em vez do título do layout raiz.
Restrição de segurança (deliberada): a imagem não pode consultar rooms nem qualquer estado —
nada de "3 jogadores esperando", nome do líder ou linguagem. Um endpoint público que devolve estado de
sala a partir do código seria um vetor de enumeração novo, exatamente o problema que a #103 (policy
using(true), sala privada enumerável) está tratando, e um alvo de abuso sem custo como o da #104
(POST /api/rooms sem rate limit). Tudo que a imagem mostra já é conhecido por quem tem o link.
Acceptance criteria (verificáveis)
Dica de abordagem
opengraph-image.tsx é uma convenção de arquivo do App Router e funciona dentro de app/room/[id]/,
recebendo os mesmos params da página — é por aí, sem rota de API nova. Reaproveite as cores de
src/lib/site.ts (themeColor, accentColor) para o card ficar coerente com o da home. Sobre o
robots.txt: a mudança é de uma linha, mas escreva no PR por que noindex na rota já cobre a
preocupação original de src/app/robots.ts:4-6 — é o ponto que um revisor vai querer ver defendido.
Contexto
O convite de sala é o loop de aquisição nº1 do CodeRacer: sem login, a única forma de alguém chegar
ao produto por indicação é receber um
/room/<code>de um amigo. A frota já construiu as duas pontasdo gesto —
copyLink()emsrc/components/Lobby.tsx:60-65e o chip "copiar link" emsrc/components/RoomView.tsx:265-269— e a chegada é ótima (oNameGateemsrc/components/RoomView.tsx:178-215já diz "você foi convidado", mostra o código e pré-preenche onick do
localStorage). O elo fraco é o meio do caminho: como esse link aparece no chat.Dois defeitos independentes, ambos conferidos na produção (2026-08-01):
1. O
robots.txtbloqueia o próprio unfurl.src/app/robots.ts:13publicaDisallow: /room/.Vários unfurlers respeitam
robots.txtantes de buscar a página (Slackbot e Twitterbot são os casosdocumentados; Discord e WhatsApp normalmente não). O comentário em
src/app/robots.ts:4-6justifica obloqueio por indexação — mas indexação já está impedida pelo
robots: { index: false, follow: false }de
src/app/room/[id]/page.tsx:12, que é o mecanismo certo para isso. ODisallownão acrescentaproteção de índice e custa o preview do convite nos clientes que o respeitam.
2. Quando o unfurl acontece, o card não fala da sala. A rota define
title/descriptionpróprios(
src/app/room/[id]/page.tsx:9-14) mas nenhumopenGraph, então herda a imagem genérica da home.O convite vira mais um card institucional do CodeRacer em vez de "sala ABC123, entra aí".
Escopo
src/app/robots.ts— parar de bloquear o fetch de/room/, mantendo as salas fora do índice pelameta
noindexque já existe na rota. Atualizar o comentário para registrar a distinção entre"não indexar" e "não deixar buscar".
/harness/continua bloqueado.banco: código em destaque, marca, e uma chamada curta ("entre na corrida"). Espelhar o shape de
src/app/opengraph-image.tsxem vez de inventar um novo.openGraph/twitterna metadata da rota da sala, para o card usar o título específico que ela jámonta (
Sala <CODE> — entre na corrida) em vez do título do layout raiz.Restrição de segurança (deliberada): a imagem não pode consultar
roomsnem qualquer estado —nada de "3 jogadores esperando", nome do líder ou linguagem. Um endpoint público que devolve estado de
sala a partir do código seria um vetor de enumeração novo, exatamente o problema que a #103 (policy
using(true), sala privada enumerável) está tratando, e um alvo de abuso sem custo como o da #104(POST /api/rooms sem rate limit). Tudo que a imagem mostra já é conhecido por quem tem o link.
Acceptance criteria (verificáveis)
GET /robots.txtem produção não contémDisallow: /room/;/harness/segue bloqueado.GET /room/<code>continua servindo<meta name="robots" content="noindex, nofollow">(ouequivalente) — a mudança do
robots.txtnão pode tornar salas indexáveis. Cole o HTML no PR.GET /room/<code>publicaog:imagepróprio (não o da home) eog:titlecom o código da sala.200 image/pngcom 1200×630 e mostra o código pedido; dois códigosdiferentes produzem imagens diferentes. Cole as duas URLs/screenshots no PR.
rooms— verificável por leitura dodiff; declare isso explicitamente no PR.
aplique o mesmo saneamento que a rota já usa (
params.id.toUpperCase().slice(0, 6),src/app/room/[id]/page.tsx:8).pnpm typecheck·pnpm build·pnpm testverdes.Dica de abordagem
opengraph-image.tsxé uma convenção de arquivo do App Router e funciona dentro deapp/room/[id]/,recebendo os mesmos
paramsda página — é por aí, sem rota de API nova. Reaproveite as cores desrc/lib/site.ts(themeColor,accentColor) para o card ficar coerente com o da home. Sobre orobots.txt: a mudança é de uma linha, mas escreva no PR por quenoindexna rota já cobre apreocupação original de
src/app/robots.ts:4-6— é o ponto que um revisor vai querer ver defendido.