📚 Pré-requisitos Teóricos: Este projeto prático aplica os fundamentos do padrão arquitetural MVC, mapeamento objeto-relacional com Spring Data JPA e renderização com Thymeleaf ensinados na Especialização em Backend com Java e Spring Boot.

A Biblioteca de Jogos (v1) estabelece a fundação do desenvolvimento web corporativo com Spring Boot 3. O projeto implementa um catálogo completo de jogos digitais abrangendo as operações de cadastro, listagem dinâmica, alternância de status de conclusão (“zerado”) e exclusão de registros, utilizando banco de dados H2 em desenvolvimento e persistência relacional.


🏛️ Arquitetura da Solução MVC

O diagrama a seguir descreve o fluxo de requisições web entre a camada de visualização Thymeleaf, o controlador Spring MVC e o repositório JPA:

Arquitetura do CRUD de Jogos com Spring Boot e Thymeleaf

📁 Estrutura de Pastas Padronizada

A base de código segue o padrão canônico com nomenclatura anti-colisão:

catalogo_projetos/javaweb_jogos_01_crud/
├── assets/                   # Galeria de diagramas visuais e arquitetura
│   └── arquitetura_jogos_crud.svg
├── web-spring/               # Aplicação Spring Boot 3 MVC
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/br/com/bibliotecajogos/
│   │   │   │   ├── controller/   # JogoController (rotas web /jogos)
│   │   │   │   ├── entity/       # Jogo (Entidade JPA)
│   │   │   │   └── repository/   # JogoRepository (Spring Data JPA)
│   │   │   └── resources/
│   │   │       ├── templates/
│   │   │       │   └── index.html # View Thymeleaf com Bootstrap 5
│   │   │       └── application.properties
│   │   └── test/                 # Testes unitários do contexto
│   ├── Dockerfile
│   ├── pom.xml
│   ├── mvnw
│   └── mvnw.cmd
└── index.md                  # Especificação executiva e Padrão Ouro

🧑‍💼 Engenharia de Software & Requisitos

1. Histórias de Usuário (US)

ID Persona História de Usuário Prioridade
US-01 Gamer / Colecionador Desejo cadastrar novos títulos na minha biblioteca informando nome, plataforma e gênero. Alta
US-02 Gamer / Colecionador Desejo visualizar todos os jogos cadastrados com seus respectivos estados de progresso. Alta
US-03 Gamer / Colecionador Desejo alternar rapidamente o status do jogo para “concluído/zerado” com um clique. Média
US-04 Gamer / Colecionador Desejo remover títulos indesejados da biblioteca de forma simples e intuitiva. Média
US-05 Desenvolvedor Júnior Desejo compreender a integração direta entre Controller e Repository no ecossistema Spring. Alta

2. Requisitos Funcionais (RF)

ID Nome Descrição
RF-01 Listagem Geral Rota GET / renderizando a tabela de jogos cadastrados via template Thymeleaf.
RF-02 Cadastro de Jogo Rota POST /jogos persistindo novo objeto Jogo a partir dos dados do formulário.
RF-03 Alternar Status Rota POST /jogos/{id}/concluir invertendo o valor booleano do atributo concluido.
RF-04 Exclusão de Registro Rota POST /jogos/{id}/apagar removendo o jogo correspondente pelo identificador único.
RF-05 Interface Responsiva Renderização de cards e tabelas estilizadas com Bootstrap 5 sem dependência de JavaScript pesado.

3. Requisitos Não-Funcionais (RNF)

ID Nome Descrição
RNF-01 Desempenho de Carga Renderização da página inicial no servidor executada em menos de 100ms.
RNF-02 Simplicidade Arquitetural Aderência aos conceitos fundamentais de Spring MVC para fins pedagógicos.
RNF-03 Integridade dos Dados Chave primária auto-incremental gerenciada pelo banco com GenerationType.IDENTITY.
RNF-04 Portabilidade Multi-Ambiente Suporte a banco H2 em memória no perfil local e PostgreSQL em produção.
RNF-05 Empacotamento Docker Imagem OCI construída com Maven Wrapper garantindo reproducibilidade de build.

4. Diagrama de Casos de Uso

flowchart TD
    subgraph Ator
        USR["Gamer / Usuário"]
    end

    subgraph "Biblioteca de Jogos v1 (web-spring)"
        UC1["Visualizar Lista de Jogos (GET /)"]
        UC2["Cadastrar Novo Jogo (POST /jogos)"]
        UC3["Marcar como Concluído (POST /{id}/concluir)"]
        UC4["Remover Jogo (POST /{id}/apagar)"]
    end

    USR --> UC1
    USR --> UC2
    USR --> UC3
    USR --> UC4

5. Matriz de Rastreabilidade (RTM)

Requisito Funcional Histórias Atendidas Requisitos Não-Funcionais Status de Cobertura
RF-01 (Listagem Geral) US-02 RNF-01, RNF-02 Implementado ✅
RF-02 (Cadastro de Jogo) US-01 RNF-02, RNF-03 Implementado ✅
RF-03 (Alternar Status) US-03 RNF-01, RNF-03 Implementado ✅
RF-04 (Exclusão) US-04 RNF-02, RNF-03 Implementado ✅
RF-05 (Interface Bootstrap) US-02, US-05 RNF-01, RNF-04 Implementado ✅

🛠️ Implementação do Controlador e Modelo

1. Entidade JPA (Jogo.java)

@Entity
@Table(name = "jogos")
public class Jogo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String titulo;
    private String plataforma;
    private boolean concluido;

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getTitulo() { return titulo; }
    public void setTitulo(String titulo) { this.titulo = titulo; }
    public String getPlataforma() { return plataforma; }
    public void setPlataforma(String plataforma) { this.plataforma = plataforma; }
    public boolean isConcluido() { return concluido; }
    public void setConcluido(boolean concluido) { this.concluido = concluido; }
}

2. Endpoints do Controlador (JogoController.java)

📄 web-spring/src/main/java/br/com/bibliotecajogos/controller/JogoController.java (arquivo real do projeto)

package br.com.bibliotecajogos.controller;

import br.com.bibliotecajogos.entity.Jogo;
import br.com.bibliotecajogos.repository.JogoRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class JogoController {

    @Autowired
    private JogoRepository jogoRepository;

    @GetMapping("/")
    public String listar(Model model) {
        model.addAttribute("jogos", jogoRepository.findAll());
        model.addAttribute("novoJogo", new Jogo());
        return "jogos";
    }

    @PostMapping("/jogos")
    public String adicionar(@ModelAttribute Jogo novoJogo) {
        jogoRepository.save(novoJogo);
        return "redirect:/";
    }

    @PostMapping("/jogos/{id}/concluir")
    public String marcarConcluido(@PathVariable Long id) {
        jogoRepository.findById(id).ifPresent(jogo -> {
            jogo.setConcluido(!jogo.isConcluido());
            jogoRepository.save(jogo);
        });
        return "redirect:/";
    }

    @PostMapping("/jogos/{id}/apagar")
    public String apagar(@PathVariable Long id) {
        jogoRepository.deleteById(id);
        return "redirect:/";
    }
}

🚀 Roteiro de Execução

1. Iniciar a Aplicação com o Maven Wrapper

cd catalogo_projetos/javaweb_jogos_01_crud/web-spring
./mvnw spring-boot:run

No Windows (PowerShell):

cd catalogo_projetos\javaweb_jogos_01_crud\web-spring
.\mvnw.cmd spring-boot:run

2. Validar no Navegador


🎯 Matriz de Checkpoints de Entrega

Checkpoint Critério de Aceite Validação Status
CP-01 Inicialização bem-sucedida do contexto Spring Boot 3 Aplicação respondendo na porta 8080 PASS ✅
CP-02 Renderização da listagem de jogos com Thymeleaf Template HTML processado sem erros de parsing PASS ✅
CP-03 Persistência de novo registro através de formulário POST Registro gravado no banco relacional PASS ✅
CP-04 Atualização de status booleano via endpoint dedicado Estado invertido e refletido na interface PASS ✅
CP-05 Exclusão física de registros por identificador Entidade removida da tabela e view atualizada PASS ✅