Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
257146f
Merge pull request #2 from MarcioCosta013/develop
MarcioCosta013 Nov 20, 2025
0c1abb4
Merge pull request #3 from MarcioCosta013/develop
MarcioCosta013 Nov 24, 2025
2f0cada
Merge pull request #4 from MarcioCosta013/develop
MarcioCosta013 Nov 26, 2025
737bc7d
Update CI workflow to use JDK 21 and develop branch
MarcioCosta013 Dec 13, 2025
5e97d22
Add CD workflow for main branch with Docker build
MarcioCosta013 Dec 13, 2025
4bf034a
Rename cd-main.yml to cicd-main.yml
MarcioCosta013 Dec 13, 2025
69738fe
Specify working directory for Maven verify
MarcioCosta013 Dec 13, 2025
dc5851f
Change Docker build context to VemProFutApi directory (#7)
MarcioCosta013 Dec 14, 2025
e8d0f28
Fix Maven command to run Spotless and verify
MarcioCosta013 Dec 14, 2025
41ce06b
Update CI workflow to apply Spotless before verify
MarcioCosta013 Dec 14, 2025
b1b028b
Develop merge (#11)
MarcioCosta013 Dec 14, 2025
a60eea7
Atualiza develop com últimas alterações e deleções
MarcioCosta013 Dec 16, 2025
75f2392
merge branch develop
MarcioCosta013 Dec 16, 2025
b649173
Clean up comments in CI Develop workflow (#14)
MarcioCosta013 Dec 16, 2025
1f8b02c
Feature/create testes unitarios (#15) (#16)
MarcioCosta013 Jan 2, 2026
db8e73c
feat(Codigo base async):
MarcioCosta013 Jan 2, 2026
5d59ae8
refactore(primeiro grupo de async):
MarcioCosta013 Jan 4, 2026
8531f9e
refactore(transicao para assicrono):
MarcioCosta013 Jan 6, 2026
d0a3919
Merge branch 'develop' into feature/transformando-em-multithreading
MarcioCosta013 Jan 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/ci-develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI Develop

on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Run Maven verify (tests + Spotless + SpotBugs)
run: mvn spotless:apply && mvn -B clean verify
working-directory: ./VemProFutApi
47 changes: 47 additions & 0 deletions .github/workflows/cicd-main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: CI/CD Main (Prod)

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven

- name: Run Maven verify (tests + Spotless + SpotBugs)
run: mvn spotless:apply && mvn -B clean verify
working-directory: ./VemProFutApi

docker:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

- name: Build Docker image
run: docker build -t vemprofut-api:latest ./VemProFutApi

- name: Tag Docker image
run: docker tag vemprofut-api:latest ${{ secrets.DOCKER_USERNAME }}/vemprofut-api:latest

- name: Push Docker image
run: docker push ${{ secrets.DOCKER_USERNAME }}/vemprofut-api:latest


Binary file added Diagramas/Fluxograma_BPMN/criarListPartida.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion VemProFutApi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.7</version>
<version>3.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.com.vemprofut</groupId>
Expand Down Expand Up @@ -85,6 +85,7 @@
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>10.20.0</version>
</dependency>

<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class VemProFutApplication {

private static final Logger log = LoggerFactory.getLogger(VemProFutApplication.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package br.com.vemprofut.configs;

import java.util.concurrent.Executor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "defaultExecutor")
public Executor defaultExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("async-");
executor.initialize();
return executor;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package br.com.vemprofut.configs;

import br.com.vemprofut.mappers.IHistoricoPeladeiroMapper;
import br.com.vemprofut.models.DTOs.HistoricoPeladeiroDTO;
import br.com.vemprofut.models.PeladeiroModel;
import br.com.vemprofut.models.enuns.PeDominante;
import br.com.vemprofut.repositories.PeladeiroRepository;
Expand Down Expand Up @@ -56,20 +55,30 @@ public void onAuthenticationSuccess(

if (usuario == null) {
log.info("Usuario inesxistente, cadastrando novo usuario...");
HistoricoPeladeiroDTO historicoPeladeiro = historicoPeladeiroService.create();
usuario = new PeladeiroModel();
usuario.setEmail(email);
usuario.setNome(name);
usuario.setApelido(name);
usuario.setDescricao("Usuário criado via OAuth2");
usuario.setWhatsapp("000000000");
usuario.setPeDominante(PeDominante.DESTRO); // escolha padrão
usuario.setAuthProvider(provider);
usuario.setFotoUrl(picture);
usuario.setHistoricoPeladeiro(historicoPeladeiroMapper.toModel(historicoPeladeiro));
peladeiroRepository.save(usuario);

log.info("Usuário salvo no banco com ID {}", usuario.getId());
historicoPeladeiroService
.create()
.thenAccept(
historicoPeladeiroDTO -> {
PeladeiroModel usuario2 = new PeladeiroModel();
usuario2.setEmail(email);
usuario2.setNome(name);
usuario2.setApelido(name);
usuario2.setDescricao("Usuário criado via OAuth2");
usuario2.setWhatsapp("000000000");
usuario2.setPeDominante(PeDominante.DESTRO); // escolha padrão
usuario2.setAuthProvider(provider);
usuario2.setFotoUrl(picture);
usuario2.setHistoricoPeladeiro(
historicoPeladeiroMapper.toModel(historicoPeladeiroDTO));
peladeiroRepository.save(usuario2);
log.info("Usuário salvo no banco com ID {}", usuario2.getId());
})
.exceptionally(
ex -> {
log.error("Erro ao criar histórico do peladeiro", ex);
return null;
});
} else {
log.info("Usuario encontrado! ID: {}", usuario.getId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import br.com.vemprofut.controllers.request.*;
import br.com.vemprofut.controllers.response.*;
import br.com.vemprofut.models.FutModel;
import br.com.vemprofut.services.IFutService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
Expand All @@ -26,37 +26,37 @@ public class FutController {
@Operation(
summary = "Cadastra um novo Fut",
tags = {"FutController - CRUD Básico"})
public ResponseEntity<SaveFutResponseDTO> create(
public CompletableFuture<ResponseEntity<SaveFutResponseDTO>> create(
@Valid @RequestBody final SaveFutRequestDTO requestDTO) {
var response = futService.create(requestDTO);
return ResponseEntity.status(HttpStatus.CREATED).body(response);
return futService
.create(requestDTO)
.thenApply(obj -> ResponseEntity.status(HttpStatus.CREATED).body(obj));
}

@GetMapping("{id}")
@Operation(
summary = "Busca um Fut pelo ID",
tags = {"FutController - CRUD Básico"})
public ResponseEntity<FutDetailsResponse> findByFut(@PathVariable final Long id) {
return ResponseEntity.ok(futService.findById(id));
public CompletableFuture<ResponseEntity<FutDetailsResponse>> findByFut(
@PathVariable final Long id) {
return futService.findById(id).thenApply(v -> ResponseEntity.ok().build());
}

@PutMapping("{id}")
@Operation(
summary = "Altera um Fut já cadastrado, informando o id",
tags = {"FutController - CRUD Básico"})
public ResponseEntity<UpdateFutResponseDTO> update(
public CompletableFuture<ResponseEntity<UpdateFutResponseDTO>> update(
@PathVariable final Long id, UpdateFutRequestDTO dto) {
var obj = futService.update(id, dto);
return ResponseEntity.ok(obj);
return futService.update(id, dto).thenApply(obj -> ResponseEntity.ok(obj));
}

@DeleteMapping("{id}")
@Operation(
summary = "Apaga um Fut por meio do id, cuidado! ",
tags = {"FutController - CRUD Básico"})
public ResponseEntity<Void> delete(@PathVariable final Long id) {
futService.delete(id);
return ResponseEntity.noContent().build();
public CompletableFuture<ResponseEntity<Void>> delete(@PathVariable final Long id) {
return futService.delete(id).thenApply(v -> ResponseEntity.noContent().build());
}

// =================== acoes partidas =======================
Expand All @@ -65,20 +65,26 @@ public ResponseEntity<Void> delete(@PathVariable final Long id) {
@Operation(
summary = "Criar uma nova partida...",
tags = {"FutController - Ações Partidas"})
public ResponseEntity<SavePartidasResponseDTO> criarPartida(
public CompletableFuture<ResponseEntity<SavePartidasResponseDTO>> criarPartida(
@RequestBody SavePartidaRequestDTO requestDTO) {
FutModel futModel = futService.findByIdModel(requestDTO.futId());
return ResponseEntity.status(HttpStatus.CREATED)
.body(futService.criarPartida(requestDTO, futModel));
return futService
.findByIdModel(requestDTO.futId())
.thenCompose(
futModel ->
futService
.criarPartida(requestDTO, futModel)
.thenApply(obj -> ResponseEntity.status(HttpStatus.CREATED).body(obj)));
}

@PostMapping("partidaslist")
@Operation(
summary = "Cria varias partidas de uma só vez, todas com resultados preenchidos",
tags = {"FutController - Ações Partidas"})
public ResponseEntity<List<SavePartidasResponseDTO>> criarPartidasLista(
public CompletableFuture<ResponseEntity<List<SavePartidasResponseDTO>>> criarPartidasLista(
@RequestBody List<SavePartidaRequestDTO> requestDTO) {
return ResponseEntity.status(HttpStatus.CREATED).body(futService.criarPartidasList(requestDTO));
return futService
.criarPartidasList(requestDTO)
.thenApply(obj -> ResponseEntity.status(HttpStatus.CREATED).body(obj));
}

// ================ lista peladeiro =====================
Expand All @@ -87,19 +93,22 @@ public ResponseEntity<List<SavePartidasResponseDTO>> criarPartidasLista(
@Operation(
summary = "Adiciona um peladeiro a lista de peladeiros cadastrado no fut",
tags = {"FutController - Lista de Peladeiros"})
public ResponseEntity<Void> adicionarPeladeiroLista(
public CompletableFuture<ResponseEntity<Void>> adicionarPeladeiroLista(
@RequestBody AddPeladeiroInFutListRequestDTO addPeladeiroRequestDTO) {
futService.addPeladeiro(addPeladeiroRequestDTO);
return ResponseEntity.noContent().build();
return futService
.addPeladeiro(addPeladeiroRequestDTO)
.thenApply(v -> ResponseEntity.noContent().build());
}

@GetMapping("lista-peladeiros/{idFut}")
@Operation(
summary = "busca a lista de todos peldadeiros cadastrados no fut",
tags = {"FutController - Lista de Peladeiros"})
public ResponseEntity<List<PeladeiroResponseDTO>> listarPeladeirosCadastrados(
public CompletableFuture<ResponseEntity<List<PeladeiroResponseDTO>>> listarPeladeirosCadastrados(
@PathVariable final Long idFut) {
return ResponseEntity.ok().body(futService.listarPeladeiroCadastradosFut(idFut));
return futService
.listarPeladeiroCadastradosFut(idFut)
.thenApply(obj -> ResponseEntity.ok().body(obj));
}

// =============== lista Editores ===========================
Expand All @@ -108,20 +117,20 @@ public ResponseEntity<List<PeladeiroResponseDTO>> listarPeladeirosCadastrados(
@Operation(
summary = "Adiciona um Editor a lista de editores de um fut em especifico",
tags = {"FutController - Lista de Editores do Fut"})
public ResponseEntity<Void> adicionarEditorLista(
public CompletableFuture<ResponseEntity<Void>> adicionarEditorLista(
@RequestBody AddEditorInFutListResquestDTO editor) {
futService.addEditor(editor);
return ResponseEntity.noContent().build();
return futService.addEditor(editor).thenApply(v -> ResponseEntity.noContent().build());
}

@GetMapping("lista-editores/{idFut}")
@Operation(
summary = "busca a lista de editores de um fut em especifico",
tags = {"FutController - Lista de Editores do Fut"})
public ResponseEntity<List<PeladeiroNameIdResponseDTO>> listarEditoresFut(
public CompletableFuture<ResponseEntity<List<PeladeiroNameIdResponseDTO>>> listarEditoresFut(
@PathVariable final Long idFut) {

return ResponseEntity.ok().body(futService.listarEditoresCadastradosFut(idFut)); // TODO:testar
return futService
.listarEditoresCadastradosFut(idFut)
.thenApply(obj -> ResponseEntity.ok().body(obj));
}

// ================= upload arquivos fotos ==================
Expand All @@ -130,10 +139,11 @@ public ResponseEntity<List<PeladeiroNameIdResponseDTO>> listarEditoresFut(
@Operation(
summary = "Para enviar a foto de capa do Fut",
tags = {"FutController - Upload de Imagens"})
public ResponseEntity<String> uploadFotoFut(
public CompletableFuture<ResponseEntity<String>> uploadFotoFut(
@PathVariable Long id, @RequestPart("file") MultipartFile file) {
futService.atualizarFotoCapa(id, file);
return ResponseEntity.ok("Foto de capa Salva!");
return futService
.atualizarFotoCapa(id, file)
.thenApply(obj -> ResponseEntity.ok("Foto de capa Salva!"));
}

// ======================== Banimentos =======================
Expand All @@ -142,27 +152,28 @@ public ResponseEntity<String> uploadFotoFut(
@Operation(
summary = "Adicionando um peladeiro da lista para o banimento",
tags = {"FutController - Banimento no Fut"})
public ResponseEntity<Void> adicionarBanimento(@RequestBody SaveBanimentoRequestDTO dto) {
futService.addBanimentoList(dto);
return ResponseEntity.noContent().build();
public CompletableFuture<ResponseEntity<Void>> adicionarBanimento(
@RequestBody SaveBanimentoRequestDTO dto) {
return futService.addBanimentoList(dto).thenApply(v -> ResponseEntity.noContent().build());
}

@GetMapping("lista-banidos/{idFut}")
@Operation(
summary = "Busca a lista de Banidos do Fut em questao",
tags = {"FutController - Banimento no Fut"})
public ResponseEntity<List<BanimentoDetailsResponseDTO>> buscarListaBanidos(
public CompletableFuture<ResponseEntity<List<BanimentoDetailsResponseDTO>>> buscarListaBanidos(
@PathVariable Long idFut) {
return ResponseEntity.ok().body(futService.findAllBanidos(idFut));
return futService.findAllBanidos(idFut).thenApply(obj -> ResponseEntity.ok().body(obj));
}

@DeleteMapping("delete-banimento/{idFut}/{idPeladeiro}")
@Operation(
summary = "retira um peladeiro da lista de banidos",
tags = {"FutController - Banimento no Fut"})
public ResponseEntity<Void> retirandoBanimento(
public CompletableFuture<ResponseEntity<Void>> retirandoBanimento(
@PathVariable Long idFut, @PathVariable Long idPeladeiro) {
futService.removeBanido(idPeladeiro, idFut);
return ResponseEntity.noContent().build();
return futService
.removeBanido(idPeladeiro, idFut)
.thenApply(v -> ResponseEntity.noContent().build());
}
}
Loading