Capítulo 23 de 35

O Padrão Ouro do ISR: Supabase Triggers e Vercel Webhooks

Índice do Manual

O maior gargalo de infraestrutura do mundo corporativo acontece em dias de pico, como na Black Friday. Um E-commerce atinge 1 milhão de acessos simultâneos e o site sai do ar. O culpado? O Banco de Dados.

O erro primário que vejo no mercado é o desenvolvedor criar uma página de produto que, a cada vez que o cliente aperta F5, vai até o banco de dados perguntar: "Qual o preço atual desta camisa?". Se 1 milhão de pessoas apertarem F5, o banco recebe 1 milhão de requisições inúteis e colapsa.

A solução clássica é transformar a página em um "HTML Estático" para a leitura ser instantânea. Mas aí nasce outro problema: e se o lojista alterar o preço da camisa no sistema de estoque? A página estática continuará mostrando o preço antigo.

Este manual contém as instruções rígidas que devem ser adotadas em todo projeto público.


O Fluxo Arquitetural Inverso

Nós invertemos a lógica. O frontend nunca vai até o banco de dados perguntar se algo mudou. É o Banco de Dados que "grita" para o frontend quando há uma novidade.

  1. Vercel (O Cache Global): A página da camisa é servida como um HTML estático puro (latência zero).
  2. Supabase (O Cérebro): O gerente atualiza o preço da camisa no painel de administração, alterando o valor no banco de dados Postgres.
  3. Database Trigger (O Choque Elétrico): No exato milissegundo que a tabela de Produtos sofre um UPDATE, o Postgres dispara uma função automática (Trigger). Essa função manda uma mensagem invisível (Webhook) para a Vercel avisando: "A camisa ID 123 mudou".
  4. On-Demand Revalidation (A Reconstrução): A Vercel recebe o aviso, refaz o HTML da camisa ID 123 silenciosamente em background e troca o arquivo antigo pelo novo nos servidores globais. O próximo cliente que acessar a página já verá o novo preço.

Implementando o Padrão Ouro

Para que a mágica aconteça, precisamos configurar duas pontas: o Recebedor (Vercel) e o Gatilho (Supabase).

Passo 1: A Rota Webhook no Next.js (Recebedor)

No Next.js, criamos uma rota de API escondida que tem poder para limpar o cache de uma página específica.

// app/api/revalidate/route.ts
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  // 1. Lemos o segredo para garantir que só o Supabase consiga chamar essa rota
  const secret = request.headers.get('x-webhook-secret');
  if (secret !== process.env.REVALIDATION_SECRET) {
    return new NextResponse('Não Autorizado', { status: 401 });
  }

  const payload = await request.json();
  
  // 2. O Supabase manda o 'slug' ou 'id' do produto que mudou
  const produtoSlug = payload.record.slug;

  // 3. A mágica: Apagamos apenas o cache desta página específica
  if (produtoSlug) {
    revalidatePath(`/produto/${produtoSlug}`);
    return NextResponse.json({ revalidated: true, now: Date.now() });
  }

  return NextResponse.json({ revalidated: false, message: 'Slug não fornecido' });
}

Passo 2: O Database Trigger no Supabase Postgres (Gatilho)

No banco de dados, configuramos o PostgreSQL para usar a extensão pg_net (disponível no Supabase) e disparar um POST HTTP toda vez que a tabela de produtos for alterada.

-- 1. Criamos a função que faz a chamada para a Vercel
CREATE OR REPLACE FUNCTION notificar_vercel_produto_atualizado()
RETURNS TRIGGER AS $$
BEGIN
  -- Usamos a extensão net do Supabase para fazer um POST invisível
  PERFORM net.http_post(
    url := 'https://sua-empresa.com/api/revalidate',
    headers := '{"Content-Type": "application/json", "x-webhook-secret": "SEU_SEGREDO_AQUI"}'::jsonb,
    body := json_build_object('record', row_to_json(NEW))::jsonb
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- 2. Amarramos a função à tabela de produtos
CREATE TRIGGER trigger_produto_atualizado
AFTER INSERT OR UPDATE ON produtos
FOR EACH ROW EXECUTE FUNCTION notificar_vercel_produto_atualizado();

Conclusão: Escalabilidade Infinita e Custo Zero

Quando implementamos essa arquitetura, o seu Banco de Dados fica 100% ocioso durante um pico de tráfego. Ele só trabalha quando um gerente atualiza um preço ou quando um cliente finaliza um carrinho.

Enquanto isso, a Vercel entrega milhões de páginas estáticas com performance máxima, garantindo nota 100 no Google Lighthouse (SEO) e destruindo qualquer chance de queda no servidor.