Home / Vuejs / IA + Nuxt 3: plataforma de emergência em menos de 6h

IA + Nuxt 3: plataforma de emergência em menos de 6h

Imagem de capa para artigo do blog Vila do Silício com o título "IA + Nuxt 3: plataforma de emergência em menos de 6h". Ao fundo, uma foto de uma rua alagada em tom roxo com uma ilustração de um cérebro digital sobreposta à direita, simbolizando tecnologia. O texto descreve o caso de sucesso da SOS Ubá na centralização das informações e lista suas funcionalidades principais: cadastro de pedidos de ajuda, busca de desaparecidos, mapa de acolhimento, doações via PIX, alertas em tempo real, notícias da região e cadastro de voluntários. Abaixo, há um botão com o link sosuba.com.br.

No dia 24 de fevereiro de 2026, uma enchente devastou Ubá, Minas Gerais. Em menos de 6 horas, construí uma plataforma de apoio emergencial que alcançou mais de 2.000 usuários ativos, usando Nuxt 3, Supabase, Cloudflare e Claude Code.

A urgência que virou código

Ubá acordou debaixo d’água. Famílias desabrigadas, ruas interditadas, pessoas desaparecidas. Enquanto isso, as informações estavam espalhadas entre grupos de WhatsApp, stories do Instagram e posts do Facebook, dificultando buscas ou atualizações.

Faltava algo básico: um lugar centralizado com abrigos, pontos de doação, desaparecidos, instituições atingidas e telefones de emergência. Naquele mesmo dia nasceu o SOS Ubá, e em menos de 6 horas já estava no ar, recebendo cadastros.

A pergunta que todo mundo faz: como foi possível desenvolver isso tão rápido?

A resposta: com Claude Code e um background técnico sólido para direcioná-lo. Neste artigo, vou mostrar como essas ferramentas se complementam e por que essa combinação é especialmente poderosa para projetos de causa social.

Por que escolhi Nuxt 3

Em uma emergência, cada decisão precisa ser pragmática. Portanto, o Nuxt 3 foi a escolha natural, porque reúne tudo que eu precisava em um único framework.

SSR nativo para SEO. Primeiramente, o Google precisava indexar a plataforma rápido. Com Server-Side Rendering, cada página já chega renderizada ao crawler. Para uma plataforma de emergência, aparecer na busca salva vidas.

Server routes embutidas. Além disso, não precisei de um servidor Express, FastAPI ou qualquer backend separado. O Nuxt 3 usa o Nitro como engine server, basta criar um arquivo em server/api/ e o endpoint já existe:

// server/api/support-points.get.ts — e pronto, temos uma API
export default defineEventHandler(async () => {
  const supabase = createServiceClient()
  const { data } = await supabase
    .from('support_points')
    .select('id, name, address, coordinates, type, schedule')
    .eq('status', 'approved')
    .order('created_at', { ascending: false })
  return data ?? []
})

Cache inteligente sem infraestrutura. Outra vantagem é que uma única linha no nuxt.config.ts dá à página de desaparecidos um cache de 2 minutos com revalidação automática:

routeRules: {
  '/desaparecidos': { swr: 120 },  // Stale-While-Revalidate
}

Na prática, o usuário recebe a página instantaneamente do cache (~50ms) enquanto o servidor busca dados frescos em background. Sem Redis, sem CDN extra, sem nada para configurar.

Auto-imports e convenções. Por fim, ref(), computed(), useFetch(), useRoute(), tudo disponível sem import. Componentes em components/ são registrados automaticamente. Páginas em pages/ viram rotas. O sufixo .client.vue marca um componente como client-only (essencial para o Leaflet.

O resultado: 50 páginas, 99 endpoints de API, 194 componentes Vue em um único repositório.

Claude Code: IA como multiplicador, não substituto

Eu uso o Claude Code, a CLI da Anthropic, como ferramenta de desenvolvimento diário. Diferentemente de um copilot que autocompleta linhas, ele é um agente que lê seu projeto inteiro, entende a arquitetura, executa comandos e propõe soluções completas.

Contudo, aqui vai o ponto central deste artigo:

A IA não substitui o desenvolvedor. Ela amplifica o que um desenvolvedor experiente consegue fazer.

Sem background técnico, eu não saberia o que pedir. Não saberia avaliar se a sugestão é boa ou se vai criar dívida técnica. Consequentemente, não saberia direcionar a conversa para as decisões corretas.

Com esse background, a IA se torna um multiplicador de força absurdo. Aqui estão exemplos reais do projeto:

Scaffolding em segundos. Em vez de criar 50 páginas uma a uma, descrevi o padrão e pedi para replicar: “Crie a página /pontos-de-apoio com o mesmo padrão da /desaparecidos: useFetch, PageHeader, listagem com cards.” e 30 segundos depois, a página estava pronta e consistente com toda a arquitetura.

Auditoria de segurança proativa. Ao pedir para auditar as policies de RLS do Supabase, o Claude Code identificou que WITH CHECK (true) no INSERT permitia que qualquer pessoa definisse status = 'approved' dando bypass em toda a moderação. Como resultado, a vulnerabilidade foi corrigida antes de ir para produção.

A regra de ouro que aprendi nesse processo é simples:

Quanto mais contexto e direcionamento você dá, melhor o resultado. E para dar bom contexto, você precisa de experiência.

Automação: o site que se alimenta sozinho

Em uma emergência, ninguém tem tempo de ficar monitorando notícias manualmente para atualizar um site. Por essa razão, o SOS Ubá tem coleta automatizada de dados.

Cron de scraping via RSS. Um endpoint protegido por secret monitora feeds do Google News buscando notícias sobre pontos de coleta, abrigos e doações na região de Ubá. Quando encontra algo relevante, o sistema categoriza automaticamente (alimentos, higiene, roupas, medicamentos) e insere como ponto pendente para o admin aprovar:

// server/api/cron/scrape-collection.get.ts
export default defineEventHandler(async (event) => {
  const { cronSecret } = useRuntimeConfig()
  if (getQuery(event).secret !== cronSecret) {
    throw createError({ statusCode: 401 })
  }

  const keywords = ['doação ubá', 'coleta ubá mg', 'abrigo ubá']
  const results = await fetchRSSFeeds(keywords)
  const newPoints = deduplicateAndCategorize(results)

  // Sempre pendente - admin precisa aprovar
  await supabase.from('collection_points').insert(
    newPoints.map(p => ({ ...p, status: 'pending' }))
  )
  return { inserted: newPoints.length }
})

Dessa forma, o admin não precisa garimpar informações porque o sistema traz as sugestões e ele só valida. Isso foi essencial nos primeiros dias, quando novas informações surgiam a cada hora.

Mapa com dados de 3 fontes em tempo real. Além do scraping, o mapa interativo não é estático. Ele combina camadas WMS da Defesa Civil (áreas de inundação, risco de deslizamento), dados do Supabase (pontos de apoio, interdições de vias) e dados KML sincronizados (pontes, sentido de vias, unidades de saúde).

Tudo atualizado automaticamente conforme novos dados entram e com SWR cache para não sobrecarregar o banco:

// server/api/map-data.get.ts - 7 queries em paralelo
const [closures, collectionPoints, shelterPoints, vaccinationPoints,
       waterPoints, mealPoints, kmlPoints] = await Promise.all([
  getApprovedClosures().catch(() => []),
  getApprovedCollectionPoints().catch(() => []),
  getApprovedShelterPoints().catch(() => []),
  getApprovedVaccinationPoints().catch(() => []),
  getApprovedWaterPoints().catch(() => []),
  getApprovedMealPoints().catch(() => []),
  getVisibleKmlPoints().catch(() => []),
])

Cada .catch(() => []) garante que, se uma query falhar, as outras camadas continuam funcionando. Em emergência, resiliência importa mais que perfeição.

plataforma de emergência
plataforma de emergência

Segurança: não é opcional, mesmo na emergência

Um erro comum em projetos feitos às pressas é ignorar segurança. “Depois a gente ajusta.” No entanto, esse “depois” geralmente não vem e quando vem, já houve vazamento de dados.

No SOS Ubá, três camadas de proteção foram implementadas desde o dia 1:

Row Level Security (RLS). Toda tabela no Supabase tem RLS ativo. A anon key é pública por design então o que protege de verdade são as policies:

-- Público só vê aprovados, inserção força status pendente
CREATE POLICY "Public read" ON help_requests
  FOR SELECT USING (status = 'approved');

CREATE POLICY "Public insert" ON help_requests
  FOR INSERT WITH CHECK (status = 'pending');

Auth guard server-side. Todas as 58 rotas administrativas passam por requireAdmin() e se não for admin, recebe 403. Sem exceção.

Criptografia de dados sensíveis. O CPF (usado para evitar duplicatas em pedidos de ajuda) é criptografado com AES-256-GCM antes de ir para o banco. A chave fica em variável de ambiente, nunca no código. Dessa maneira, as queries públicas fazem SELECT explícito apenas de colunas seguras — o CPF nunca aparece.

A arquitetura completa

O SOS Ubá não é um site com informações estáticas. É uma aplicação completa com duas faces:

Para o cidadão: cadastro de desaparecidos com foto, pedido de ajuda, mapa interativo com 7+ camadas (risco de inundação, deslizamento, pontos de apoio), diretório de abrigos/coleta/vacinação, report de interdições com geolocalização e cadastro de voluntários.

Para o admin: dashboard com contadores em tempo real, moderação de conteúdo, gerenciamento de 15 categorias e autenticação com rate limiting.

Os números que importam

MétricaValor
Tempo do conceito ao deploy< 6 horas
Usuários ativos2.000+
Pontos de apoio cadastrados100+ (todo o Sudeste)
Tempo de resposta (cache hit)< 100ms
Páginas50
Endpoints de API99
Componentes Vue194
Linhas de código21.700+
Incidentes de segurança0

O que eu levaria para o próximo projeto social

Use o que você domina. Não é hora de aprender framework novo. Nuxt, Next, SvelteKit… qualquer um resolve. O importante é velocidade de execução.

A IA é sua aliada, não sua substituta. Ela transforma semanas em horas (mas só se você souber direcionar). Invista tempo em prompts específicos com contexto e restrições.

Segurança desde o minuto zero. RLS, criptografia, auth guards. Dados de pessoas em emergência são sensíveis. Não existe “depois a gente ajusta”.

Edge computing importa. Servir em 50ms ao invés de 500ms faz diferença quando milhares de pessoas desesperadas acessam seu site ao mesmo tempo. Serviços como Cloudflare Workers tornam isso acessível.

Projetos sociais merecem boa engenharia. As pessoas que dependem da plataforma merecem a mesma qualidade que um cliente pagante receberia. A IA torna isso viável mesmo para equipes de uma pessoa.


Acesse o projeto: sosuba.com.br

Stack completa

CamadaTecnologia
FrameworkNuxt 3 + Vue 3
UITailwind CSS + shadcn-vue
BackendNitro (server routes)
Banco de dadosSupabase (PostgreSQL + Auth + Storage)
DeployCloudflare Workers
MapaLeaflet + vue-leaflet
FormuláriosVeeValidate + Zod
CriptografiaAES-256-GCM
IAClaude Code (Anthropic)
Marcado:

Deixe um Comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *