Backend desenvolvido em Spring Boot Java 21, arquitetura Maven.
- Sobre a Disaster Pulse
- Integrantes
- Estrutura do Projeto
- Dependências Utilizadas
- Endpoints
- Enums Utilizados
- Documentação da API - Swagger - Render
- Instruções de Execução e Deploy
- Modelo Relacional Oracle
- Modelo Relacional MySQL
- Demonstração Implantação dos contêineres
- Demonstração Testes de Endpoints no Render
O Disaster Pulse é uma plataforma de monitoramento e alerta para eventos catastróficos. A proposta é conectar cidadãos e entidades governamentais ou sociais em uma rede ágil de resposta a desastres ambientais, biológicos e climáticos.
- André Geraldi Marcolongo - RM555285 - 2TDSPV
- Felipe Gabriel Lopes Pinheiro Clarindo - RM554547 - 2TDSPX
- Humberto de Souza Silva - RM558482 - 2TDSPX
src
├── main
│ ├── java
│ │ └── disaster
│ │ └── pulse
│ │ └── api
│ │ ├── config
│ │ │ ├── AuthFilter.java
│ │ │ ├── CorsConfig.java
│ │ │ ├── DataInitializer.java
│ │ │ ├── SecurityConfig.java
│ │ │ └── SwaggerConfig.java
│ │ ├── controller
│ │ │ ├── AlertaController.java
│ │ │ ├── AuthController.java
│ │ │ ├── CivilController.java
│ │ │ ├── EntidadeController.java
│ │ │ ├── EventoController.java
│ │ │ ├── PedidoSosController.java
│ │ │ └── TipoEventoController.java
│ │ ├── DisasterPulseBackendApplication.java
│ │ ├── dto
│ │ │ ├── DadosUsuario.java
│ │ │ ├── JwtDto.java
│ │ │ ├── LoginDto.java
│ │ │ ├── request
│ │ │ │ ├── AlertaRequestDTO.java
│ │ │ │ ├── CivilRequestDTO.java
│ │ │ │ ├── EntidadeRequestDTO.java
│ │ │ │ ├── EventoRequestDTO.java
│ │ │ │ └── PedidoSosRequestDTO.java
│ │ │ └── response
│ │ │ ├── AlertaResponseDTO.java
│ │ │ ├── CivilResponseDTO.java
│ │ │ ├── CivilResumoResponseDTO.java
│ │ │ ├── EntidadeResponseDTO.java
│ │ │ ├── EntidadeResumoResponseDTO.java
│ │ │ ├── EventoResponseDTO.java
│ │ │ ├── EventoResumoResponseDTO.java
│ │ │ ├── PedidoSosResponseDTO.java
│ │ │ ├── PedidoSosResumoResponseDTO.java
│ │ │ └── TipoEventoResponseDTO.java
│ │ ├── mapper
│ │ │ ├── AlertaMapper.java
│ │ │ ├── CivilMapper.java
│ │ │ ├── EntidadeMapper.java
│ │ │ ├── EventoMapper.java
│ │ │ ├── PedidoSosMapper.java
│ │ │ └── TipoEventoMapper.java
│ │ ├── model
│ │ │ ├── Alerta.java
│ │ │ ├── Civil.java
│ │ │ ├── Entidade.java
│ │ │ ├── enums
│ │ │ │ ├── Risco.java
│ │ │ │ └── Status.java
│ │ │ ├── Evento.java
│ │ │ ├── PedidoSOS.java
│ │ │ ├── TipoEvento.java
│ │ │ └── Usuario.java
│ │ ├── repository
│ │ │ ├── AlertaRepository.java
│ │ │ ├── CivilRepository.java
│ │ │ ├── EntidadeRepository.java
│ │ │ ├── EventoRepository.java
│ │ │ ├── PedidoSosRepository.java
│ │ │ ├── TipoEventoRepository.java
│ │ │ └── UsuarioRepository.java
│ │ └── service
│ │ ├── AlertaService.java
│ │ ├── AuthService.java
│ │ ├── CivilService.java
│ │ ├── EntidadeService.java
│ │ ├── EventoService.java
│ │ ├── JwtService.java
│ │ └── PedidoSosService.java
│ └── resources
│ ├── application-mysql.properties // Perfil para persistência de dados em Banco MySQL
│ ├── application-oracle.properties // Perfil para persistência de dados em Banco Oracle
│ └── application.properties // Contém propriedades e configurações universais do projeto, tão como a escolha do perfil para persitência
└── test
└── java
└── disaster
└── pulse
└── api
└── DisasterPulseBackendApplicationTests.java<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>3.0.0-M3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.5</version>
</dependency>
</dependencies>Os endpoints:
/api/sos- Métodos (POST,PUTeDELETE)/api/eventos- Métodos (POST,PUTeDELETE)
Exigem autenticação, respectivamente para usuário do tipo CIVIL e usuário do tipo ENTIDADE.
O identificador de Login respectivamente para ambos são: CPF (CIVIL) e CNPJ (ENTIDADE).
Use o endpoint /api/login para obter um token válido.
Endpoint de login. Retorna token JWT de validação. Necessário login antes de realizar operações POST (PedidoSOS para Civil e Evento para Entidade)
POST /api/login- Realiza login e gera token JWT de autenticação
Corpo do request:
{
"login": "12345678901 ou 12345678000199 (cpf para civil, cnpj para entidade)",
"senha": "senha"
}Corpo do response:
{
"jwt": "string",
"type": "bearer"
}POST /api/cadastro/entidade– Cadastra uma nova entidadePUT /api/cadastro/entidade/{id}– Atualiza os dados de uma entidade existenteGET /api/cadastro/entidade/{id}– Retorna os dados de uma entidade específica
{
"nomeFantasia": "Defesa Civil de São Paulo",
"email": "defesacivilsp@sp.gov.br",
"telefone": "11 99123-4567",
"cnpj": "12345678000195",
"senha": "senha123" // é serializada e cadastrada na tabela 'DP_USUARIO'
}{
"id": 1,
"nomeFantasia": "Defesa Civil de São Paulo",
"email": "defesacivilsp@sp.gov.br",
"telefone": "11 99123-4567",
"cnpj": "12345678000195",
"eventos": [
{
"idEvento": 1,
"titulo": "Temporal e risco de enchentes no Butantã",
"risco": "ALTO",
"dataInicio": "2025-06-02T17:14:04.676Z"
}
]
}POST /api/eventos- Cadastra um novo evento. Requer autenticação de um usuário com perfil de Entidade devidamente cadastrado.PUT /api/eventos/{id}- Atualiza os dados de um evento existente. Requer autenticação de um usuário com perfil de Entidade.GET /api/eventos/{id}- Retorna os dados detalhados de um evento específico, identificado pelo seuid.GET /api/eventos- Retorna todos os eventos cadastrados. Suporta paginação, filtros por entidade e ordenação.DELETE /api/eventos/{id}- Remove um evento existente. Requer autenticação de um usuário com perfil de Entidade.
{
"idTipoEvento": 1,
"titulo": "Temporal e risco de enchentes no Butantã",
"descricao": "Previsão de fortes chuvas acompanhadas de risco elevado de enchentes na região do Butantã. Moradores devem permanecer atentos a possíveis alagamentos, quedas de árvores e interrupções no trânsito.",
"dataInicio": "2025-06-02T17:11:41.528Z",
"latitude": -23.55052,
"longitude": -46.633308,
"risco": "ALTO"
}{
"id": 1,
"nomeFantasia": "Defesa Civil de São Paulo",
"email": "defesacivilsp@sp.gov.br",
"telefone": "11 99123-4567",
"cnpj": "12345678000195",
"eventos": [
{
"idEvento": 1,
"titulo": "Tempestade com risco de enchente",
"risco": "ALTO",
"dataInicio": "2025-06-02T17:11:41.528Z"
}
]
}Retorna uma lista paginada de eventos cadastrados.
| Nome | Tipo | Local | Descrição |
|---|---|---|---|
entidadeId |
integer |
query | (opcional) ID da entidade para filtrar os eventos |
page |
integer |
query | Índice da página (base 0). Padrão: 0 |
size |
integer |
query | Número de elementos por página. Padrão: 20 |
sort |
string[] |
query | Critério(s) de ordenação: `propriedade,(asc |
/api/eventos?entidadeId=1&page=0&size=10&sort=dataInicio,desc
{
"totalPages": 1,
"totalElements": 1,
"size": 10,
"content": [
{
"idEvento": 1,
"titulo": "Temporal e risco de enchentes no Butantã",
"descricao": "Previsão de fortes chuvas acompanhadas de risco elevado de enchentes na região do Butantã. Moradores devem permanecer atentos a possíveis alagamentos, quedas de árvores e interrupções no trânsito.",
"dataInicio": "2025-06-02T17:11:41.528Z",
"latitude": -23.55052,
"longitude": -46.633308,
"risco": "ALTO",
"tipoEvento": {
"idTipoEvento": 1,
"tipo": "Climático"
},
"entidade": {
"id": 1,
"nomeFantasia": "Defesa Civil de São Paulo"
}
}
],
"number": 0,
"sort": [
{
"direction": "DESC",
"nullHandling": "NATIVE",
"ascending": false,
"property": "dataInicio",
"ignoreCase": false
}
],
"numberOfElements": 1,
"pageable": {
"offset": 0,
"sort": [
{
"direction": "DESC",
"nullHandling": "NATIVE",
"ascending": false,
"property": "dataInicio",
"ignoreCase": false
}
],
"unpaged": false,
"paged": true,
"pageNumber": 0,
"pageSize": 10
},
"first": true,
"last": true,
"empty": false
}POST /api/alertas- Cadastra um alerta relacionado a um evento.PUT /api/alertas/{id}- Atualiza os dados de um alerta existenete.GET /api/alertas/{id}- Retorna os dados detalhados de um alerta específico, identificado pelo seuid.GET /api/alertas- Retorna todos os alertas cadastrados em um evento.DELETE /api/alertas/{id}- Remove um alerta existente.
{
"idEvento": 1,
"mensagem": "Risco de alagamento na região do Butantã. Evacuar pontos de risco.",
"dataHora": "2025-06-02T17:37:14.176Z"
}[
{
"idAlerta": 1,
"evento": {
"idEvento": 1,
"titulo": "Fortes chuvas previstas para a região do Butantã, com risco de alagamentos.",
"risco": "ALTO",
"dataInicio": "2025-06-02T17:18:21.222Z"
},
"mensagem": "Risco de alagamento na região do Butantã. Evacuar pontos de risco.",
"dataHora": "2025-06-02T17:37:14.176Z"
}
]GET /api/tipo-evento- Retorna todos os tipos de eventos cadastrados. O arquivo../api/config/DataInitializer.javajá cadastra os tipos de evento na inicialização do projeto
// Exemplo - retorna os 5 tipos cadastrados na inicialização do projeto
[
{
"idTipoEvento": 1,
"tipo": "Climático"
},
{
"idTipoEvento": 2,
"tipo": "Geográfico"
},
{
"idTipoEvento": 3,
"tipo": "Biológico"
},
{
"idTipoEvento": 4,
"tipo": "Ambiental"
},
{
"idTipoEvento": 5,
"tipo": "Epidêmico"
}
]POST /api/cadastro/civil– Cadastra um novo usuário do tipo CivilPUT /api/cadastro/civil/{id}– Atualiza os dados de usuário do tipo CivilGET /api/cadastro/civil/{id}– Retorna os dados de um usuário do tipo Civil
{
"nomeCompleto": "José da Silva",
"email": "jose.silva@example.com",
"cpf": "12345678901",
"telefone": "11 91234-1234",
"senha": "senha123"
}{
"id": 2,
"nomeCompleto": "José da Silva",
"email": "jose.silva@example.com",
"cpf": "12345678901",
"telefone": "11 91234-1234",
"sos": [
{
"idSos": 1,
"comentario": "Ilhado na região do Butantã"
}
]
}POST /api/sos- Cadastra um novo pedido de SOS vinculado a um evento existente. Requer autenticação de um usuário com perfil de Civil devidamente cadastrado.PUT /api/sos/{id}- Atualiza os dados de um pedido de SOS existente. Requer autenticação de um usuário com perfil de Civil.GET /api/sos/{id}- Retorna os dados detalhados de um pedido de SOS específico, identificado pelo seuid.GET /api/sos- Retorna todos os pedidos de SOS cadastrados.DELETE /api/sos/{id}- Remove um pedido de SOS existente. Requer autenticação de um usuário com perfil de Civil.
{
"idEvento": 1, // Evento relacionado ao SOS
"comentario": "Ilhado na região do Butantã.",
"status": "ABERTO"
}{
"idSos": 1,
"civil": {
"id": 2,
"nomeCompleto": "José da Silva"
},
"dataHora": "2025-06-02T17:37:14.176Z",
"comentario": "Ilhado na região do Butantã.",
"status": "ABERTO"
}A API utiliza enums para padronizar estados e classificações importantes.
-
Risco (usado em EVENTO)
Valores possíveis:BAIXO,MEDIO,ALTO,CRITICO -
Status (usado em PEDIDO_SOS)
Valores possíveis:ABERTO,RESOLVIDO,PENDENTE,CONCLUIDO,CANCELADO
/swagger-ui/index.html
O projeto está implantado no Render.
A documentação da API pode ser acessada através do link abaixo:
Documentação: Swagger UI - Disaster Pulse API
O projeto implantado no Render faz persistência no Oracle interno da faculdade.
-
Os endpoints estão organizados em categorias distintas para facilitar o uso: Civil e Entidade

-
Autenticação do usuário (Civil ou Entidade) com o JWT gerado:

Basta colar o token gerado após o envio das credenciais pelo endpoint /api/login:
git clone https://github.com/andremarko/disaster-pulse-api-rest
cd disaster-pulse-api-restCaso queira via script docker-script.sh
user disaster-pulse-api-rest$ ./docker-script.sh
# [...]
# Siga as instruções do script.Persistência Externa
docker build -t disaster-pulse-backend-image .
docker run -d --name disaster-pulse-backend -p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=oracle \
-e DB_USER=seu_usuario \
-e DB_PASS=sua_senha\
disaster-pulse-backend-image\Persistência interna (MySQL)
docker network create disaster-pulse-network
docker volume create disaster-pulse-db-data
docker run --name disaster-pulse-mysql --network disaster-pulse-network \
-e MYSQL_ROOT_PASSWORD=suasenharoot \
-e MYSQL_DATABASE=disaster_pulse \
-e MYSQL_USER=disasterpersist \
-e MYSQL_PASSWORD=senhadoschema \
-v disaster-pulse-db-data:/var/lib/mysql \
-p 3306:3306 \
-d mysql:8.0
docker build -t disaster-pulse-backend-image .
docker run -d --name disaster-pulse-backend --network disaster-pulse-network -p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=mysql \
-e DB_USER=disasterpersist \
-e DB_PASS=senhadoschema \
disaster-pulse-backend-image

Implantação Modular com Docker - Backend Java Spring Boot e MySQL em Contêineres

Implantação Modular com Docker - Backend Java Spring Boot e MySQL em Contêineres


