StudentCard é um sistema para emissão e gerenciamento de carteirinhas estudantis e monitoramento em tempo real de rotas de ônibus. O frontend é uma SPA em React + TypeScript que consome uma API REST construída em Spring Boot. Atualizações de localização são transmitidas em tempo real via WebSocket/STOMP e a última localização é armazenada em Redis.
Principais conceitos:
- Autenticação stateless via JWT
- Perfis: STUDENT, DRIVER, ADMIN
- Monitoramento em tempo real: motoristas enviam GPS; estudantes e admins consomem
- Arquitetura backend: Hexagonal (Ports & Adapters) + DDD
- Cache de localização: Redis; broadcast: STOMP
- Stack: React 19, TypeScript, Vite, Tailwind CSS, Leaflet, axios, @stomp/stompjs + sockjs-client.
- Arquivos relevantes:
frontend/src/api.ts— instância axios e interceptor JWTfrontend/src/hooks/useWebSocket.ts— hook que encapsula STOMP/SockJSfrontend/src/App.tsx— rotas e proteção de páginasfrontend/src/storage.ts— helper que persiste dados por aba
- Fluxos principais:
- Login/Register → salva token + metadados em
storage ProtectedRoute: validatoken,userTypeeuserStatus- Motorista transmite localização (navigator.geolocation) para
/api/routes/{routeId}/location - Student/Admin assinam
/topic/route/{routeId}via STOMP para receber atualizações
- Login/Register → salva token + metadados em
- Observação: atualmente
frontend/src/api.tstembaseURLhardcoded (http://localhost:8080). Recomenda-se usarVITE_API_URLeVITE_WS_URL.
- Stack: Java + Spring Boot, Spring Security (JWT), Spring Data JPA (Postgres), spring-data-redis (Redis), WebSocket/STOMP (SimpMessagingTemplate).
- Organização (Hexagonal / DDD):
domain/— entidades, VOs, regrasapplication/— casos de uso e ports (inbound/outbound)infrastructure/— adapters (REST controllers, JPA, Redis, STOMP, JWT, BCrypt)
- Principais responsabilidades:
- Autenticação/Autorização: JWT stateless e
SecurityFilter - Rotas: criação, início, pausa, retomada, fim, e publicação de eventos
- Localização: motorista envia via REST; última posição salva em Redis e broadcast via STOMP
- Autenticação/Autorização: JWT stateless e
Backend (.env ou application.properties via import):
# JWT
jwt.secret=uma_chave_secreta_muito_segura
jwt.expiration=1440
# PostgreSQL
spring.datasource.url=jdbc:postgresql://localhost:5432/studentcard_db
spring.datasource.username=postgres
spring.datasource.password=postgres
# Redis
spring.redis.host=localhost
spring.redis.port=6379
# App
server.port=8080
Frontend (Vite .env):
VITE_API_URL=http://localhost:8080
VITE_WS_URL=http://localhost:8080/ws
Pré-requisitos: Java, Maven (ou use ./mvnw), PostgreSQL e Redis.
Passos:
# na raiz do backend
./mvnw clean package
./mvnw spring-boot:run
# ou
java -jar target/studentcard-0.0.1-SNAPSHOT.jarPré-requisitos: Node.js >= 18
Passos:
cd frontend
npm install
npm run devObservação: ajuste VITE_API_URL/VITE_WS_URL no frontend se o backend rodar em endpoint diferente.
- Auth:
POST /api/auth/login— login (retorna token JWT e metadados)POST /api/auth/register— registro
- Users (admin actions):
GET /api/users/{id}POST /api/users/authorize/{id}POST /api/users/block/{id}
- StudentCards:
POST /api/student-cards/issuePOST /api/student-cards/{id}/renewGET /api/student-cards(admin)
- Routes / Location:
POST /api/routes— criar rotaPOST /api/routes/{routeId}/start— iniciarPOST /api/routes/{routeId}/pause— pausarPOST /api/routes/{routeId}/resume— retomarPOST /api/routes/{routeId}/end— encerrarPOST /api/routes/{routeId}/location— motorista envia localizaçãoGET /api/routes/{routeId}/location— obter última localização
- Endpoint (SockJS):
/ws - Broker simple:
enableSimpleBroker("/topic", "/queue") - Prefixo de application destinations:
/app - Tópico para monitoramento de rota:
/topic/route/{routeId} - Autenticação: token JWT enviado no handshake (query param
?token=e/ouconnectHeaders.Authorization)
Exemplo de payload (location update):
{
"type": "location_update",
"latitude": -12.9714,
"longitude": -38.5014,
"timestamp": 1670000000000
}Aqui está a tela de login:
Aqui está a tela de cadastro:
Aqui está a tela de completar perfil (etapa 1):
Continuação do fluxo de completar perfil:
Tela indicando que o perfil está em análise:
Tela de acesso bloqueado / restrição:
















