From 9256c65a63fcd94ea482f26252f0e79114c222b2 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 09:40:12 -0300 Subject: [PATCH 01/22] Subindo ajuste de CICD --- .github/workflows/cicd.yml | 54 ++++++++++++++------------------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 6463c16..0aeb094 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -1,46 +1,32 @@ -name: CI/CD Docker +name: CI/CD Spring Boot com SQL on: push: - branches: [ "main" ] + pull_request: jobs: - build-and-push: + build-test: runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 + env: + SPRING_DATASOURCE_URL: ${{ secrets.DATABASE_URL }} + SPRING_DATASOURCE_USERNAME: ${{ secrets.DB_USER }} + SPRING_DATASOURCE_PASSWORD: ${{ secrets.DB_PASSWORD }} + TOKEN_API: ${{ secrets.TOKEN_API }} - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + steps: + - name: Checkout do código + uses: actions/checkout@v4 - - name: Login to Docker Hub - uses: docker/login-action@v2 + - name: Configurar JDK 17 + uses: actions/setup-java@v4 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + java-version: '17' + distribution: 'temurin' + cache: maven - # Build e push da imagem Java - - name: Build and push Java image - uses: docker/build-push-action@v4 - with: - context: . - file: ./Dockerfile - target: java - push: true - tags: | - ${{ secrets.DOCKERHUB_USERNAME }}/apisaveit-java:latest - ${{ secrets.DOCKERHUB_USERNAME }}/apisaveit-java:${{ github.sha }} + - name: Build com Maven + run: mvn clean package --no-transfer-progress - # Build e push da imagem Python (exemplo) - - name: Build and push Python image - uses: docker/build-push-action@v4 - with: - context: . - file: ./Dockerfile - target: python - push: true - tags: | - ${{ secrets.DOCKERHUB_USERNAME }}/apisaveit-python:latest - ${{ secrets.DOCKERHUB_USERNAME }}/apisaveit-python:${{ github.sha }} + - name: Rodar testes + run: mvn test --no-transfer-progress \ No newline at end of file From 29fa78b36519e52f522d1d1865d19ea54ae94259 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 09:46:45 -0300 Subject: [PATCH 02/22] =?UTF-8?q?Ajuste=20de=20skipar=20teste,=20pois=20n?= =?UTF-8?q?=C3=A3o=20h=C3=A1=20testes=20no=20repo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 0aeb094..58dee9c 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -26,7 +26,7 @@ jobs: cache: maven - name: Build com Maven - run: mvn clean package --no-transfer-progress + run: mvn clean package -DskipTests --no-transfer-progress - name: Rodar testes run: mvn test --no-transfer-progress \ No newline at end of file From cc25ed2089f08c0bf4ee41ecd8053241fe4a2db7 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:02:10 -0300 Subject: [PATCH 03/22] Subindo ajuste de cicd para tests --- .github/workflows/cicd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 58dee9c..965c07f 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -26,7 +26,7 @@ jobs: cache: maven - name: Build com Maven - run: mvn clean package -DskipTests --no-transfer-progress + run: mvn clean package --no-transfer-progress - name: Rodar testes - run: mvn test --no-transfer-progress \ No newline at end of file + run: mvn test --no-transfer-progress From a1bd02f3c5498891270f486405e11f192baad25b Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:02:28 -0300 Subject: [PATCH 04/22] Adicionando application-test --- src/test/resources/application-test.properties | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/resources/application-test.properties diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties new file mode 100644 index 0000000..7474d8d --- /dev/null +++ b/src/test/resources/application-test.properties @@ -0,0 +1,6 @@ +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration +spring.jpa.hibernate.ddl-auto=none +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= From 62b3958d587efde4f597d5de3e4ff76e82f77f6a Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:02:48 -0300 Subject: [PATCH 05/22] Ajustando o applicationTests --- src/test/java/com/api/ApiApplicationTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/api/ApiApplicationTests.java b/src/test/java/com/api/ApiApplicationTests.java index e3d517d..d6a491a 100644 --- a/src/test/java/com/api/ApiApplicationTests.java +++ b/src/test/java/com/api/ApiApplicationTests.java @@ -3,11 +3,11 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest +@SpringBootTest(properties = "spring.profiles.active=test") class ApiApplicationTests { @Test void contextLoads() { + // Apenas valida se o contexto carrega com H2 } - } From a57394ebb85f190c224f68a02b5dc44104c97ca0 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:03:00 -0300 Subject: [PATCH 06/22] Ajustando o pom --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 501e693..34c4179 100644 --- a/pom.xml +++ b/pom.xml @@ -85,6 +85,11 @@ firebase-admin 9.3.0 + + com.h2database + h2 + test + From ec4f6975fc76f1db1740d1b389352f0e89734717 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:09:42 -0300 Subject: [PATCH 07/22] Ajustando o firebase para pipeline --- src/main/java/com/api/Configuration/FirebaseConfig.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/api/Configuration/FirebaseConfig.java b/src/main/java/com/api/Configuration/FirebaseConfig.java index 72112c7..4bb3513 100644 --- a/src/main/java/com/api/Configuration/FirebaseConfig.java +++ b/src/main/java/com/api/Configuration/FirebaseConfig.java @@ -6,11 +6,13 @@ import com.google.firebase.FirebaseOptions; import jakarta.annotation.PostConstruct; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import java.io.ByteArrayInputStream; import java.util.Base64; @Configuration +@Profile("!test") // não carrega este bean se o profile for "test" public class FirebaseConfig { @Value("${firebase.credentials.b64:}") From e30464074f2afdda671f0e147f8a58a9eabcbde4 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:19:53 -0300 Subject: [PATCH 08/22] Tests --- src/test/java/com/api/ApiApplicationTests.java | 3 ++- src/test/java/com/api/SecurityTestConfig.java | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/api/SecurityTestConfig.java diff --git a/src/test/java/com/api/ApiApplicationTests.java b/src/test/java/com/api/ApiApplicationTests.java index d6a491a..4007c71 100644 --- a/src/test/java/com/api/ApiApplicationTests.java +++ b/src/test/java/com/api/ApiApplicationTests.java @@ -2,10 +2,11 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; @SpringBootTest(properties = "spring.profiles.active=test") +@Import(SecurityTestConfig.class) class ApiApplicationTests { - @Test void contextLoads() { // Apenas valida se o contexto carrega com H2 diff --git a/src/test/java/com/api/SecurityTestConfig.java b/src/test/java/com/api/SecurityTestConfig.java new file mode 100644 index 0000000..e397236 --- /dev/null +++ b/src/test/java/com/api/SecurityTestConfig.java @@ -0,0 +1,14 @@ +package com.api; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.security.authentication.AuthenticationManager; + +@TestConfiguration +public class SecurityTestConfig { + + @Bean + public AuthenticationManager authenticationManager() { + return authentication -> authentication; // simples mock + } +} From 123f74df74370e51f6936f3a69f88e8926fe0dcf Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:25:54 -0300 Subject: [PATCH 09/22] Ajuste pipeline --- src/test/java/com/api/SecurityTestConfig.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/api/SecurityTestConfig.java b/src/test/java/com/api/SecurityTestConfig.java index e397236..e4bcaf4 100644 --- a/src/test/java/com/api/SecurityTestConfig.java +++ b/src/test/java/com/api/SecurityTestConfig.java @@ -1,14 +1,18 @@ package com.api; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; @TestConfiguration public class SecurityTestConfig { @Bean - public AuthenticationManager authenticationManager() { - return authentication -> authentication; // simples mock + @ConditionalOnMissingBean(AuthenticationManager.class) + public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { + return config.getAuthenticationManager(); } + } From 12a5301c302acc130407ee4e845e02320cb0060a Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:33:40 -0300 Subject: [PATCH 10/22] Ajuste de Application --- src/test/java/com/api/ApiApplicationTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/api/ApiApplicationTests.java b/src/test/java/com/api/ApiApplicationTests.java index 4007c71..01368bc 100644 --- a/src/test/java/com/api/ApiApplicationTests.java +++ b/src/test/java/com/api/ApiApplicationTests.java @@ -5,10 +5,10 @@ import org.springframework.context.annotation.Import; @SpringBootTest(properties = "spring.profiles.active=test") -@Import(SecurityTestConfig.class) class ApiApplicationTests { @Test void contextLoads() { // Apenas valida se o contexto carrega com H2 } } + From 37ea03959ee91fdadd794212fbfb0d50b6ff5c10 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:34:00 -0300 Subject: [PATCH 11/22] Ajuste de testconfig --- src/test/java/com/api/SecurityTestConfig.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/api/SecurityTestConfig.java b/src/test/java/com/api/SecurityTestConfig.java index e4bcaf4..1ce38bb 100644 --- a/src/test/java/com/api/SecurityTestConfig.java +++ b/src/test/java/com/api/SecurityTestConfig.java @@ -3,16 +3,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; @TestConfiguration +@Profile("test") public class SecurityTestConfig { - @Bean - @ConditionalOnMissingBean(AuthenticationManager.class) public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); } - } From eaa7952c21085e25533e7d6b8152e5b58e0ac2c3 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:43:09 -0300 Subject: [PATCH 12/22] =?UTF-8?q?Cria=C3=A7=C3=A3o=20de=20TestSecurityConf?= =?UTF-8?q?ig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/com/api/TestSecurityConfig.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/java/com/api/TestSecurityConfig.java diff --git a/src/test/java/com/api/TestSecurityConfig.java b/src/test/java/com/api/TestSecurityConfig.java new file mode 100644 index 0000000..bb16d4f --- /dev/null +++ b/src/test/java/com/api/TestSecurityConfig.java @@ -0,0 +1,23 @@ +package com.api; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.security.authentication.AuthenticationManager; + +import static org.mockito.Mockito.mock; + +/** + * Configuração falsa de segurança só para os testes. + * Impede o erro de AuthenticationConfiguration ausente. + */ +@TestConfiguration +public class TestSecurityConfig { + + @Bean + @Primary + public AuthenticationManager authenticationManager() { + // Retorna um mock para não carregar segurança real + return mock(AuthenticationManager.class); + } +} From df9e9126cf28494ea4ff92778b59c89086ffbf94 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Tue, 28 Oct 2025 11:46:43 -0300 Subject: [PATCH 13/22] =?UTF-8?q?Cria=C3=A7=C3=A3o=20de=20ApiApplicationTe?= =?UTF-8?q?sts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/com/api/ApiApplicationTests.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/api/ApiApplicationTests.java b/src/test/java/com/api/ApiApplicationTests.java index 01368bc..3674b75 100644 --- a/src/test/java/com/api/ApiApplicationTests.java +++ b/src/test/java/com/api/ApiApplicationTests.java @@ -1,14 +1,16 @@ package com.api; +import com.api.TestSecurityConfig; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Import; -@SpringBootTest(properties = "spring.profiles.active=test") +@SpringBootTest +@Import(TestSecurityConfig.class) class ApiApplicationTests { + @Test void contextLoads() { - // Apenas valida se o contexto carrega com H2 + // Só verifica se o contexto carrega corretamente } } - From 75a0dbdb9bd2e3915e66948f198eb0668f121293 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:40:10 -0300 Subject: [PATCH 14/22] Adicionando criptografia SHA --- .../com/api/Util/SHA256PasswordEncoder.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/main/java/com/api/Util/SHA256PasswordEncoder.java diff --git a/src/main/java/com/api/Util/SHA256PasswordEncoder.java b/src/main/java/com/api/Util/SHA256PasswordEncoder.java new file mode 100644 index 0000000..6dae5e6 --- /dev/null +++ b/src/main/java/com/api/Util/SHA256PasswordEncoder.java @@ -0,0 +1,18 @@ +package com.api.Util; + +import com.api.Util.PasswordUtils; +import org.springframework.security.crypto.password.PasswordEncoder; + +public class SHA256PasswordEncoder implements PasswordEncoder { + + @Override + public String encode(CharSequence rawPassword) { + return PasswordUtils.hashPassword(rawPassword.toString()); + } + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + String hashed = PasswordUtils.hashPassword(rawPassword.toString()); + return hashed.equals(encodedPassword); + } +} From b199df54404c9f166b7f13a844dfeeea2e77e0fd Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:41:22 -0300 Subject: [PATCH 15/22] Ajuste na securityConfig para SHA --- src/main/java/com/api/security/SecurityConfig.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/api/security/SecurityConfig.java b/src/main/java/com/api/security/SecurityConfig.java index 3904bc8..1839458 100644 --- a/src/main/java/com/api/security/SecurityConfig.java +++ b/src/main/java/com/api/security/SecurityConfig.java @@ -1,5 +1,6 @@ package com.api.security; +import com.api.Util.SHA256PasswordEncoder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,7 +11,6 @@ import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.web.cors.CorsConfiguration; @@ -28,13 +28,16 @@ public class SecurityConfig { @Autowired private TokenFilter tokenFilter; + @Autowired + private UserDetailService userDetailService; + @Bean public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); + return new SHA256PasswordEncoder(); } @Bean - public AuthenticationProvider authenticationProvider(UserDetailService userDetailService) { + public AuthenticationProvider authenticationProvider() { DaoAuthenticationProvider provider = new DaoAuthenticationProvider(); provider.setUserDetailsService(userDetailService); provider.setPasswordEncoder(passwordEncoder()); @@ -49,7 +52,7 @@ public AuthenticationManager authenticationManager(AuthenticationConfiguration c @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); - configuration.setAllowedOrigins(List.of("http://localhost:5173", "https://react-save-it.vercel.app")); + configuration.setAllowedOriginPatterns(List.of("http://localhost:5173", "https://react-save-it.vercel.app")); configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")); configuration.setAllowCredentials(true); configuration.setAllowedHeaders(List.of("*")); @@ -64,6 +67,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti http .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) + .authenticationProvider(authenticationProvider()) .authorizeHttpRequests(auth -> auth .requestMatchers("/api/auth/login", "/api/auth/logout").permitAll() .requestMatchers("/login", "/error").permitAll() From c1a6109713340750a53d62e1ab3083015766e97c Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:41:44 -0300 Subject: [PATCH 16/22] =?UTF-8?q?Autentica=C3=A7=C3=A3o=20Customizada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CustomAuthenticationProvider.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/main/java/com/api/security/CustomAuthenticationProvider.java diff --git a/src/main/java/com/api/security/CustomAuthenticationProvider.java b/src/main/java/com/api/security/CustomAuthenticationProvider.java new file mode 100644 index 0000000..6963c62 --- /dev/null +++ b/src/main/java/com/api/security/CustomAuthenticationProvider.java @@ -0,0 +1,44 @@ +package com.api.security; + +import com.api.Util.PasswordUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.*; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.userdetails.*; +import org.springframework.stereotype.Component; + +@Component +public class CustomAuthenticationProvider implements AuthenticationProvider { + + private final UserDetailsService userDetailsService; + + @Autowired + public CustomAuthenticationProvider(UserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + String email = authentication.getName(); + String rawPassword = authentication.getCredentials().toString(); + + UserDetails userDetails = userDetailsService.loadUserByUsername(email); + + boolean senhaCorreta = PasswordUtils.verifyPassword(rawPassword, userDetails.getPassword()); + if (!senhaCorreta) { + throw new BadCredentialsException("Credenciais inválidas"); + } + + return new UsernamePasswordAuthenticationToken( + userDetails.getUsername(), + userDetails.getPassword(), + userDetails.getAuthorities() + ); + } + + @Override + public boolean supports(Class authentication) { + return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); + } +} From 83a84a71e45454cfdbf7311f73e02d2c2abe3fd6 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:42:46 -0300 Subject: [PATCH 17/22] =?UTF-8?q?Dele=C3=A7=C3=A3o=20do=20CICD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cicd.yml | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 .github/workflows/cicd.yml diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml deleted file mode 100644 index 965c07f..0000000 --- a/.github/workflows/cicd.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: CI/CD Spring Boot com SQL - -on: - push: - pull_request: - -jobs: - build-test: - runs-on: ubuntu-latest - - env: - SPRING_DATASOURCE_URL: ${{ secrets.DATABASE_URL }} - SPRING_DATASOURCE_USERNAME: ${{ secrets.DB_USER }} - SPRING_DATASOURCE_PASSWORD: ${{ secrets.DB_PASSWORD }} - TOKEN_API: ${{ secrets.TOKEN_API }} - - steps: - - name: Checkout do código - uses: actions/checkout@v4 - - - name: Configurar JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - - name: Build com Maven - run: mvn clean package --no-transfer-progress - - - name: Rodar testes - run: mvn test --no-transfer-progress From 2ed703fe3433d22f991940d03e3cdb85a671f2ac Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:43:19 -0300 Subject: [PATCH 18/22] Ajuste do adminOpenAPi erro de cors --- src/main/java/com/api/openapi/AdminOpenApi.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/api/openapi/AdminOpenApi.java b/src/main/java/com/api/openapi/AdminOpenApi.java index 0f2e8f9..174bc5f 100644 --- a/src/main/java/com/api/openapi/AdminOpenApi.java +++ b/src/main/java/com/api/openapi/AdminOpenApi.java @@ -46,10 +46,11 @@ public interface AdminOpenApi { ResponseEntity updateAdmin(Long id, AdminRequestDTO adminAtualizado); @Operation(summary = "Atualizar parcialmente um admin pelo ID") @ApiResponses({ - @ApiResponse(responseCode = "200", description = "Admin atualizado com sucesso"), + @ApiResponse(responseCode = "200", description = "Admin atualizado parcialmente com sucesso"), @ApiResponse(responseCode = "400", description = "Dados inválidos fornecidos"), @ApiResponse(responseCode = "404", description = "Admin não encontrado"), @ApiResponse(responseCode = "500", description = "Erro interno do servidor") }) - ResponseEntity atualizarAdminParcial(Long id, Map updates); + ResponseEntity atualizarAdminParcial(Long id,Map updates); + } From c6905d6abb9da143e5ffc07abfd335aeed173897 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:44:03 -0300 Subject: [PATCH 19/22] AJuste de controller --- src/main/java/com/api/controller/AdminController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/api/controller/AdminController.java b/src/main/java/com/api/controller/AdminController.java index 8978a1e..a349581 100644 --- a/src/main/java/com/api/controller/AdminController.java +++ b/src/main/java/com/api/controller/AdminController.java @@ -51,7 +51,7 @@ public ResponseEntity updateAdmin(@PathVariable Long id, @Valid @RequestBody return ResponseEntity.ok("Admin atualizado com sucesso!"); } @PatchMapping("/atualizarParcial/{id}") - public ResponseEntity atualizarAdminParcial(@PathVariable Long id, @Valid @RequestBody Map updates) { + public ResponseEntity atualizarAdminParcial(@PathVariable Long id,@RequestBody Map updates) { adminService.updateAdminPartial(id, updates); return ResponseEntity.ok("Admin atualizado parcialmente com sucesso!"); } From 4ab0996bb0503876285f9b09b432ff65cc276f87 Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:44:30 -0300 Subject: [PATCH 20/22] =?UTF-8?q?Adi=C3=A7=C3=A3o=20de=20endpoint=20novo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/controller/ShowcaseController.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/com/api/controller/ShowcaseController.java b/src/main/java/com/api/controller/ShowcaseController.java index 5074dc5..8f22dc9 100644 --- a/src/main/java/com/api/controller/ShowcaseController.java +++ b/src/main/java/com/api/controller/ShowcaseController.java @@ -1,7 +1,9 @@ package com.api.controller; +import com.api.dto.product.ProductResponseDTO; import com.api.exception.GlobalException; import com.api.openapi.ShowcaseOpenApi; +import com.api.service.ProductService; import com.api.service.ShowcaseService; import com.api.dto.showcase.ShowcaseListDTO; import com.api.dto.showcase.ShowcaseRequestDTO; @@ -12,6 +14,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.time.LocalDateTime; import java.util.List; import java.util.Map; @@ -21,6 +24,8 @@ public class ShowcaseController implements ShowcaseOpenApi { private final ShowcaseService showCaseService; private GlobalException ge; + @Autowired + private ProductService productService; @Autowired public ShowcaseController(ShowcaseService showCaseService) { this.showCaseService = showCaseService; @@ -75,5 +80,23 @@ public ResponseEntity updateShowcasePartial(@PathVariable Long id, @RequestBo return ResponseEntity.ok("Vitrine atualizado parcialmente com sucesso!"); } + @GetMapping("/novos") + public ResponseEntity getProdutosNovos(@RequestParam(required = false) String ultimoCheck) { + try { + LocalDateTime checkTime; + + if (ultimoCheck == null || ultimoCheck.isBlank()) { + checkTime = LocalDateTime.now().minusDays(1); + } else { + checkTime = LocalDateTime.parse(ultimoCheck); + } + List novasVitrines = showCaseService.listNewShowcases(checkTime); + return ResponseEntity.ok(novasVitrines); + + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body("Formato de data inválido. Use o formato: yyyy-MM-dd'T'HH:mm:ss"); + } + } } From 957f2a01f6f36502bd1590c8227f40474fe9adbe Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:44:59 -0300 Subject: [PATCH 21/22] =?UTF-8?q?Cria=C3=A7=C3=A3o=20de=20query=20no=20rep?= =?UTF-8?q?ository?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/api/repository/ShowcaseRepository.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/api/repository/ShowcaseRepository.java b/src/main/java/com/api/repository/ShowcaseRepository.java index 8db30c2..d471aef 100644 --- a/src/main/java/com/api/repository/ShowcaseRepository.java +++ b/src/main/java/com/api/repository/ShowcaseRepository.java @@ -1,10 +1,12 @@ package com.api.repository; +import com.api.model.Product; import com.api.model.Showcase; import com.api.dto.showcase.ShowcaseListDTO; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import java.time.LocalDateTime; import java.util.List; public interface ShowcaseRepository extends JpaRepository { @@ -38,5 +40,7 @@ public interface ShowcaseRepository extends JpaRepository { WHERE e.id = :enterpriseId """) List findShowcaseWithProductByEnterpriseId(long enterpriseId); + List findAllByEntranceDateAfter(LocalDateTime entranceDate); + } From 1d6319abc4015c26c5fa42dfbf343f7c4336ff5c Mon Sep 17 00:00:00 2001 From: NathanFGerminare Date: Thu, 30 Oct 2025 10:45:39 -0300 Subject: [PATCH 22/22] Ajuste de ShowcaseService para endpoint novo --- src/main/java/com/api/service/ShowcaseService.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/api/service/ShowcaseService.java b/src/main/java/com/api/service/ShowcaseService.java index 487c168..49bac17 100644 --- a/src/main/java/com/api/service/ShowcaseService.java +++ b/src/main/java/com/api/service/ShowcaseService.java @@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -132,4 +133,15 @@ public ShowcaseResponseDTO updateShowcasePartial(Long id, Map up showcaseRepository.save(showcase); return mapToDTO(showcase); } + public List listNewShowcases(LocalDateTime lastCheck) { + List novasVitrines = showcaseRepository.findAllByEntranceDateAfter(lastCheck); + List resposta = new ArrayList<>(); + + for (Showcase s : novasVitrines) { + resposta.add(mapToDTO(s)); + } + + return resposta; + } + }