From a9b43cc09ed02b4b598cbe997e073f54abd8c901 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 28 Mar 2026 14:08:29 +0000
Subject: [PATCH 1/3] Initial plan
From 8c91f4df6ce08c5c0a75544886718919d1a5ed49 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sat, 28 Mar 2026 14:17:45 +0000
Subject: [PATCH 2/3] Changes before error encountered
Agent-Logs-Url: https://github.com/fiap-tech-challenge-java/vigisus/sessions/d77cddbd-c0f0-4a8e-9fa8-d2d267a88ba8
Co-authored-by: rebecanonato89 <38442994+rebecanonato89@users.noreply.github.com>
---
.../busca/BuscaCompletaUseCase.java | 6 +
.../fiap/vigisus/config/SecurityConfig.java | 7 +-
.../controller/AdminDashboardController.java | 156 ++++++++++++++++++
.../vigisus/service/AdminMetricsService.java | 135 +++++++++++++++
.../fiap/vigisus/service/TriagemService.java | 3 +
backend/src/main/resources/application.yml | 5 +-
.../busca/BuscaCompletaUseCaseTest.java | 5 +-
.../AdminDashboardControllerTest.java | 121 ++++++++++++++
.../vigisus/service/TriagemServiceTest.java | 3 +-
9 files changed, 435 insertions(+), 6 deletions(-)
create mode 100644 backend/src/main/java/br/com/fiap/vigisus/controller/AdminDashboardController.java
create mode 100644 backend/src/main/java/br/com/fiap/vigisus/service/AdminMetricsService.java
create mode 100644 backend/src/test/java/br/com/fiap/vigisus/controller/AdminDashboardControllerTest.java
diff --git a/backend/src/main/java/br/com/fiap/vigisus/application/busca/BuscaCompletaUseCase.java b/backend/src/main/java/br/com/fiap/vigisus/application/busca/BuscaCompletaUseCase.java
index d298cc5..d03f40b 100644
--- a/backend/src/main/java/br/com/fiap/vigisus/application/busca/BuscaCompletaUseCase.java
+++ b/backend/src/main/java/br/com/fiap/vigisus/application/busca/BuscaCompletaUseCase.java
@@ -8,6 +8,7 @@
import br.com.fiap.vigisus.exception.MunicipioNotFoundException;
import br.com.fiap.vigisus.exception.RecursoNaoEncontradoException;
import br.com.fiap.vigisus.model.Municipio;
+import br.com.fiap.vigisus.service.AdminMetricsService;
import br.com.fiap.vigisus.service.EncaminhamentoService;
import br.com.fiap.vigisus.service.IaService;
import br.com.fiap.vigisus.service.MunicipioService;
@@ -34,12 +35,15 @@ public class BuscaCompletaUseCase {
private final PrevisaoRiscoService previsaoRiscoService;
private final EncaminhamentoService encaminhamentoService;
private final MunicipioService municipioService;
+ private final AdminMetricsService adminMetricsService;
public BuscaCompletaResponse buscarPorPergunta(String pergunta) {
+ adminMetricsService.registrarBuscaIa(pergunta);
IntencaoDTO intencao = iaService.interpretarPergunta(pergunta);
Municipio municipio = encontrarMunicipio(intencao.getMunicipio(), intencao.getUf());
String coIbge = municipio.getCoIbge();
intencao.setCoIbge(coIbge);
+ adminMetricsService.registrarBusca(municipio.getNoMunicipio(), municipio.getSgUf());
BuscaCompletaResponse response = buscarPorCoIbge(
coIbge,
@@ -56,6 +60,8 @@ public BuscaCompletaResponse buscarDireto(String municipio, String uf, String do
.findFirst()
.orElseThrow(() -> new MunicipioNotFoundException(municipio.trim() + " / " + uf.trim()));
+ adminMetricsService.registrarBusca(municipioEncontrado.getNoMunicipio(), municipioEncontrado.getSgUf());
+
return buscarPorCoIbge(
municipioEncontrado.getCoIbge(),
resolverDoenca(doenca),
diff --git a/backend/src/main/java/br/com/fiap/vigisus/config/SecurityConfig.java b/backend/src/main/java/br/com/fiap/vigisus/config/SecurityConfig.java
index 147644a..a653c11 100644
--- a/backend/src/main/java/br/com/fiap/vigisus/config/SecurityConfig.java
+++ b/backend/src/main/java/br/com/fiap/vigisus/config/SecurityConfig.java
@@ -14,9 +14,11 @@
* Por serem dados abertos, todos os endpoints de consulta são públicos.
* Não há dados pessoais de pacientes — apenas estatísticas agregadas.
*
+ * NOTA: /actuator/** e /admin/** são servidos exclusivamente na porta 9090
+ * (management.server.port), portanto não precisam de regras aqui.
+ *
* ROADMAP v2.0:
- * Endpoints administrativos (/api/admin/**, /actuator/**) receberão
- * autenticação JWT para operadores de saúde pública.
+ * Endpoints administrativos receberão autenticação JWT para operadores de saúde pública.
*/
@Configuration
@EnableWebSecurity
@@ -28,7 +30,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configure(http))
.authorizeHttpRequests(auth -> auth
- .requestMatchers("/actuator/**").permitAll()
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
.requestMatchers("/api/**").permitAll()
.anyRequest().authenticated()
diff --git a/backend/src/main/java/br/com/fiap/vigisus/controller/AdminDashboardController.java b/backend/src/main/java/br/com/fiap/vigisus/controller/AdminDashboardController.java
new file mode 100644
index 0000000..032b4dd
--- /dev/null
+++ b/backend/src/main/java/br/com/fiap/vigisus/controller/AdminDashboardController.java
@@ -0,0 +1,156 @@
+package br.com.fiap.vigisus.controller;
+
+import br.com.fiap.vigisus.service.AdminMetricsService;
+import io.swagger.v3.oas.annotations.Hidden;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.Instant;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Dashboard administrativo do VigiSUS.
+ *
+ *
Este controller é servido exclusivamente na porta 9090
+ * (management.server.port), nunca exposto na porta pública 8080.
+ * A anotação @Hidden impede que apareça no Swagger público.
+ */
+@Hidden
+@RestController
+@RequestMapping("/admin")
+@RequiredArgsConstructor
+public class AdminDashboardController {
+
+ private final AdminMetricsService adminMetricsService;
+
+ @GetMapping("/resumo")
+ public ResponseEntity