WallpaperMachine
The wallpapers you love. A new home on your Mac.
Monitoramento de Linhas de Ônibus
Translation pending
LifestyleJavaScript · CSSGitHub @Mateus-SROnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
[FatecDSM-2026/2] Nova versão do Busca Bus, refeita em React
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Originalmente projetado para uso interno na Fatec Zona Leste, o projeto cresceu e agora atende qualquer instituição do município de São Paulo, em toda localidade onde os ônibus da SPTrans atuam. O sistema consulta a API Olho Vivo da SPTrans e mostra, em uma "exibição" (um painel pensado para ficar aberto numa tela), os ônibus que estão chegando a uma ou mais paradas, com o status de cada um (Normal, Atrasado ou Adiantado).
Este repositório é a versão refeita em React/Next.js do projeto original (Sistema-Monitoramento-Linhas-Onibus, feito com Jekyll, JavaScript puro e Supabase). A atualização das exibições agora é feita por WebSocket (Socket.IO), não mais por consultas repetidas do navegador.
https://www.sptrans.com.br/itinerarios/linha/?numero=<letreiro>, substituindo <letreiro> pelo letreiro completo de algum ônibus que passa pelo ponto (ex.: 273D-10).Parada&PID=. Navegador (apps/web) Servidor (apps/server) SPTrans
┌──────────────────────┐ WebSocket ┌──────────────────────────┐ HTTPS ┌────────────┐
│ Next.js + React 19 │◄──────────►│ Express + Socket.IO │──────────►│ Olho Vivo │
│ Exibição, mapa, etc. │ (REST só │ - poller (1 consulta por│ (token │ API v2.1 │
└──────────────────────┘ fallback) │ parada, compartilhada)│ no └────────────┘
│ - salas por exibição │ servidor)
│ - MongoDB (opcional) │
└──────────────────────────┘
COALESCING_MS)./v1/exibicoes/:codigo/radar como contingência (a cada 10 s, respondida do cache do servidor).tempoAtraso min → Atrasado; ≤ −tempoAdiantado min → Adiantado; senão Normal.Monorepo com npm workspaces (apps/* e packages/*).
.
├── apps/
│ ├── web/ # Site (Next.js 16, App Router, React 19, Tailwind CSS v4, Leaflet)
│ │ └── src/
│ │ ├── app/
│ │ │ ├── (site)/ # Páginas públicas: início, exibição, mapa, configuração, favoritos, sobre...
│ │ │ └── (auth)/ # login, cadastro, reset-senha (sem o cabeçalho do site)
│ │ ├── components/ # Por domínio: layout, ui, home, exibicao, configuracao, listas, mapa, auth
│ │ ├── contexts/ # Auth (mock), acessibilidade, loading, cabeçalho
│ │ ├── hooks/ # useExibicao, useRadarOnibus (conexão Socket.IO + fallback REST)
│ │ ├── lib/fixtures/ # Dados fictícios temporários (exibições, instituições, usuário, mapa)
│ │ └── store/ # Favoritos (Zustand)
│ ├── server/ # API REST + Socket.IO (Node.js, Express 5, MongoDB)
│ │ └── src/
│ │ ├── index.js # Ponto de entrada
│ │ ├── config.js # Leitura e validação das variáveis de ambiente
│ │ ├── db.js # Conexão e índices do MongoDB
│ │ ├── http/ # app.js + routes/ (health, auth, exibicoes, me)
│ │ ├── realtime/ # socket.js (salas, snapshots) e poller.js (consulta à SPTrans)
│ │ ├── sptrans/ # cliente.js (login/cookie/renovação), normalizar.js, simulador.js
│ │ └── repos/ # Acesso ao banco (exibições, usuários)
│ └── mobile/ # React Native (em preparação, ainda não executável)
├── packages/
│ └── core/ # Código compartilhado e sem dependência de plataforma:
│ # eventos do socket, cálculo de status, tempo, DTOs, validações, cliente da API, stores
├── render.yaml # Blueprint de hospedagem no Render (site estático + servidor)
├── CLAUDE.md / AGENTS.md # Convenções do projeto para agentes de IA
└── package.json # Scripts do monorepo
Regra de organização: código de navegador/Next.js fica em apps/web, código React Native em apps/mobile e lógica sem plataforma em packages/core.
git clone https://github.com/Mateus-SR/Busca-Bus-React.git e entre na pasta.npm install
.env* são ignorados pelo Git; nunca coloque credenciais no repositório)
.env na raiz do projeto:
# Token da API Olho Vivo (suficiente para o teste local)
SPTRANS_DEFAULT_TOKEN="<seu token da API Olho Vivo>"
apps/web/.env.local para o site falar com o servidor:
NEXT_PUBLIC_API_URL="http://localhost:4000"
Sem essa variável, o site funciona apenas com dados fictícios (fixtures), sem WebSocket.npm run dev:server
http://localhost:4000.JWT_SECRET e MONGODB_URI, o servidor sobe mesmo assim e avisa no console que login e banco estão desabilitados.npm run dev
http://localhost:3000.http://localhost:4000/v1/health deve responder {"ok":true,...}.http://localhost:3000/exibicao?codigo=dev para ver a exibição de teste local, que usa a parada 650004840. Ela só existe enquanto o MONGODB_URI não estiver configurado (o alias testes também é aceito pelo servidor). Digite a URL direto no navegador: o campo da tela inicial exige 6 caracteres.GET http://localhost:4000/v1/paradas/650004840/validar
GET http://localhost:4000/v1/exibicoes/dev/radar
Com
NEXT_PUBLIC_API_URLdefinida, a exibiçãodevusa a SPTrans real. As exibiçõesUpilXc,Busca1eFatec2(dados de demonstração do site) usam as paradas definidas emapps/web/src/lib/fixtures/exibicoesFixture.js, e a SPTrans pode não reconhecer todos esses códigos. Se existirem no MongoDB, os dados do banco substituem os da fixture.
Para ter exibições próprias e contas de usuário, acrescente ao .env da raiz:
MONGODB_URI="<sua string de conexão do MongoDB>"
MONGODB_DB="<nome do banco, ex.: Bus>"
JWT_SECRET="<um segredo longo e aleatório>"
O servidor cria os índices necessários ao iniciar. Veja o formato das exibições.
.env na raiz do repositório)| Variável | Obrigatória | Padrão | Descrição |
|---|---|---|---|
SPTRANS_DEFAULT_TOKEN | Para ônibus reais | — | Token da API Olho Vivo. Usado só pelo servidor. |
MONGODB_URI | Sim, em produção | — | String de conexão do MongoDB. Sem ela, as rotas de banco respondem 503 e só a exibição de teste local funciona. |
MONGODB_DB | Recomendada | (banco da MONGODB_URI; se não houver, test) | Nome do banco. Tem prioridade sobre o nome na MONGODB_URI. Sem ela e sem banco na URI, tudo é gravado no banco padrão test (o servidor avisa no log). O nome diferencia maiúsculas de minúsculas. |
JWT_SECRET | Sim, em produção | — | Segredo de assinatura dos tokens de login. Sem ele, a autenticação fica desabilitada. |
ALLOWED_ORIGINS | Sim, em produção | (qualquer origem) | Origens permitidas pelo CORS, separadas por vírgula, sem barra final (ex.: https://meu-site.onrender.com). |
NODE_ENV | Não | development | Em production, as três variáveis acima passam a ser obrigatórias. |
PORT / HOST | Não | 4000 / 0.0.0.0 | Porta e endereço do servidor. |
SPTRANS_BASE_URL | Não | https://api.olhovivo.sptrans.com.br/v2.1 | Endereço base da API Olho Vivo. |
SPTRANS_TIMEOUT_MS | Não | 10000 | Tempo limite das chamadas à SPTrans. |
POLL_INTERVALO_MS | Não | 5000 | Intervalo entre consultas por parada. |
COALESCING_MS | Não | 500 | Janela para juntar as paradas de uma exibição em um único snapshot. |
apps/web/.env.local, ou variável do ambiente de build)| Variável | Obrigatória | Descrição |
|---|---|---|
NEXT_PUBLIC_API_URL | Para tempo real | URL do servidor (ex.: http://localhost:4000). É embutida no build: depois de alterá-la, é preciso gerar o site de novo. |
Em qualquer exibição, o painel oculto "Detalhes técnicos" abre pelo botão abaixo do código da exibição ou com Ctrl + Shift + D. Ele só coleta diagnóstico enquanto está aberto, guarda os últimos 30 snapshots, nunca mostra o token ou o cookie da SPTrans e permite limpar o histórico ou forçar uma atualização. Com o Socket.IO conectado, mostra também clientes conectados, salas ativas, entradas/saídas, snapshots enviados e o histórico de quedas e reconexões.
Com o simulador de falhas habilitado (padrão fora de produção), o painel também permite injetar problemas entre o servidor e a SPTrans, que expiram sozinhos (padrão 60 s, máximo 10 min):
| Cenário | O que simula |
|---|---|
rede | Sem internet |
timeout | SPTrans não responde |
erro500 | SPTrans com erro 500 |
lenta | SPTrans lenta (+3 s) |
vazia | Resposta sem previsões |
json_invalido | HTML no lugar de JSON |
| queda do socket | Derruba só o WebSocket, para testar a reconexão |
O simulador afeta todas as salas do servidor. Em produção deixe-o desligado (não defina
SIMULACAO_FALHAS=1).
O repositório já traz um Blueprint do Render (render.yaml, na raiz) com dois serviços: o site estático (busca-bus-web) e o servidor (busca-bus-server, plano gratuito).
MONGODB_URI). Em Network Access, permita a conexão do Render: no plano gratuito os IPs de saída mudam, então costuma-se liberar 0.0.0.0/0. Nesse caso, use um usuário de banco com senha forte.render.yaml.sync: false:
MONGODB_URI: a string do passo 1, sem aspas.MONGODB_DB: já vem com o valor Bus pelo Blueprint; altere se o seu banco tiver outro nome (diferencia maiúsculas de minúsculas).SPTRANS_DEFAULT_TOKEN: seu token do Olho Vivo.ALLOWED_ORIGINS: a URL do site estático (ex.: https://busca-bus-web.onrender.com, sem barra final).ENCRYPTION_KEY, APP_URL, EMAIL_API_KEY: podem ficar em branco por enquanto (reservadas).JWT_SECRET é gerada automaticamente pelo Render.https://busca-bus-server.onrender.com) e, no serviço busca-bus-web, defina NEXT_PUBLIC_API_URL com essa URL.https://<seu-servidor>/v1/health (é o mesmo endereço usado pelo health check do Render).Observações do Blueprint:
rootDir: os serviços dependem de packages/core e do package-lock.json da raiz. O buildFilter evita deploys desnecessários.next.config.mjs usa output: "export", ou seja, gera um site 100% estático. Rode npm ci && npm run build com NEXT_PUBLIC_API_URL definida e publique a pasta apps/web/out em qualquer hospedagem estática (Netlify, Cloudflare Pages, Vercel, GitHub Pages...). Para publicar em um subcaminho (ex.: GitHub Pages de projeto) é preciso configurar basePath no next.config.mjs.npm ci e npm run start:server, com as variáveis de ambiente definidas e NODE_ENV=production.npx serve apps/web/out. npm run start não funciona neste projeto, porque o next start não aceita output: "export".| Quero mudar... | Onde mexer |
|---|---|
| Uma tela ou rota do site | apps/web/src/app/(site)/... (públicas) ou (auth)/... (login/cadastro) |
| Layout e componentes visuais | apps/web/src/components/<domínio>/ |
| Cores, fontes e animações | apps/web/src/app/globals.css (Tailwind v4 configurado via @theme; a cor da marca é sptrans) |
| Como o site recebe os ônibus (WebSocket e fallback REST) | apps/web/src/hooks/useRadarOnibus.js |
| Exibições de demonstração do site | apps/web/src/lib/fixtures/exibicoesFixture.js |
| Regras de status (atrasado/adiantado) | packages/core/src/status.js |
| Nomes dos eventos do socket | packages/core/src/eventos.js (usados por site e servidor) |
| Intervalo padrão de coleta | packages/core/src/intervalos.js (ou POLL_INTERVALO_MS) |
| Integração com a SPTrans | apps/server/src/sptrans/ |
| Consulta e cache por parada | apps/server/src/realtime/poller.js |
| Salas, limites e snapshots do WebSocket | apps/server/src/realtime/socket.js |
| Rotas REST | apps/server/src/http/routes/ |
Convenções (mais detalhes em CLAUDE.md):
codigo, erro, estaLogado, handleAcessar)."use client"; os demais são Server Components.@/* para importar de apps/web/src/*.next/dynamic e ssr: false..prettierrc: tabs, aspas simples, prettier-plugin-tailwindcss).As exibições ficam na coleção exibicoes (o banco é o definido em MONGODB_DB ou, se ela estiver vazia, na MONGODB_URI). Ainda não existe rota para criá-las: por enquanto, insira o documento manualmente (mongosh, Compass ou Atlas):
{
"codigo": "UpilXc",
"nome": "Fatec Zona Leste",
"paradas": ["650004840", "650004841"],
"config": {
"tempoAtraso": 2,
"tempoAdiantado": 2,
"distanciaMaxMin": 20,
"permitirMultiplosPorLinha": false
},
"ativo": true,
"criadoEm": "2026-01-01T00:00:00.000Z"
}
| Campo | Significado |
|---|---|
codigo | Código de acesso (letras, números, _ ou -; a tela inicial exige 6 caracteres) |
paradas | Códigos de parada da SPTrans (7 a 9 dígitos; no máximo 8 por exibição) |
tempoAtraso / tempoAdiantado | Minutos de diferença para marcar o ônibus como Atrasado / Adiantado (0 a 120) |
distanciaMaxMin | Só mostra ônibus que chegam em até X minutos (0 a 180) |
permitirMultiplosPorLinha | false: mostra só o próximo ônibus de cada linha; true: mostra todos |
ativo | false esconde a exibição sem apagá-la |
Para a exibição aparecer no site hospedado, o código também precisa estar em apps/web/src/lib/fixtures/exibicoesFixture.js (veja as limitações).
/v1)Limite geral de 120 requisições por minuto por IP; as rotas de autenticação têm limite próprio.
| Método e rota | Descrição |
|---|---|
GET /v1/health | Estado do servidor (versão, ambiente, banco, memória) |
GET /v1/paradas/:codigo/validar | Confere se a SPTrans responde para o código da parada |
GET /v1/exibicoes/:codigo | Dados de uma exibição |
GET /v1/exibicoes/:codigo/radar | Snapshot atual (contingência do WebSocket). Aceita ?diagnostico=1 e ?permitirMultiplosPorLinha=true|false |
POST /v1/auth/cadastro, POST /v1/auth/login | Criar conta e entrar (exigem MONGODB_URI e JWT_SECRET) |
/v1/auth/refresh, /v1/auth/reset-senha, /v1/me/* | Ainda não implementados (respondem 501) |
Os nomes dos eventos ficam em packages/core/src/eventos.js.
| Evento | Direção | Uso |
|---|---|---|
exibicao:entrar | cliente → servidor | Entra na sala: { codigo, paradas, config, diagnostico } |
exibicao:configurar | cliente → servidor | Altera a configuração da sala |
exibicao:diagnostico | cliente → servidor | Liga/desliga o bloco de diagnóstico para aquele navegador |
exibicao:simular | cliente → servidor | Aciona um cenário de falha (só com o painel aberto e o simulador ligado) |
exibicao:sair | cliente → servidor | Sai da sala |
heartbeat | cliente → servidor | Confirma que a conexão está viva |
exibicao:snapshot | servidor → cliente | Lista atual de ônibus, ponto(s), configuração e estado da conexão |
servidor:aviso | servidor → cliente | Avisos do servidor (ex.: reiniciando) |
Limites por conexão: 30 eventos a cada 10 s e mensagens de até 64 KB.
output: "export"), então qualquer código de exibição funciona sem gerar página nova: /exibicao?codigo=XXXXXX, /mapa?codigo=XXXXXX e /configuracao?editar=XXXXXX. As páginas leem o parâmetro com useSearchParams dentro de <Suspense>.AuthContext usa um usuário de mentira guardado no localStorage. A API de login existe no servidor, mas o site ainda não a usa.apps/web/src/lib/fixtures/). Sem NEXT_PUBLIC_API_URL, a exibição também mostra ônibus fictícios.apps/mobile é só um esqueleto (componentes e stores iniciais); ainda não há app para executar.Todos rodam a partir da raiz do repositório.
| Comando | O que faz |
|---|---|
npm install | Instala as dependências de todo o monorepo |
npm run dev | Site em modo de desenvolvimento (http://localhost:3000) |
npm run dev:server | Servidor em modo de desenvolvimento, com reinício automático (http://localhost:4000) |
npm run build | Gera o site estático em apps/web/out |
npm run build:server | Verifica a sintaxe do servidor (node --check; não há etapa de compilação) |
npm run start:server | Inicia o servidor (produção) |
npm run lint | ESLint do site |
Antes de abrir um pull request, rode npm run lint, npm run build e npm run build:server.
SIMULACAO_FALHAS |
| Não |
| ligada fora de produção |
1 liga e 0 desliga o simulador de falhas (veja abaixo). Em produção só liga se for 1. |
TEST_DISPLAY_CODE | Não | dev | Código da exibição de teste local (sem MongoDB). |
TEST_STOP_CODE / TEST_STOP_CODES | Não | 650004840 | Parada(s) da exibição de teste local; TEST_STOP_CODES aceita vários códigos separados por vírgula. |
ENCRYPTION_KEY, APP_URL | Não | — | Reservadas para recursos futuros; o servidor atual lê, mas ainda não usa. |