Antes de qualquer linha de código, todo projeto precisa responder duas perguntas: o que o sistema precisa fazer, e quem interage com ele. Este módulo cobre o levantamento de requisitos, os casos de uso derivados dele, e só então a estrutura de pastas do projeto que os implementa.
O sistema “Gestão de Estoques” administra produtos, categorias e fornecedores, com controle de acesso por papel (usuário comum vs. administrador). Os requisitos abaixo descrevem o sistema como ele existe hoje — não uma lista de desejos, mas o que o código realmente implementa.
| ID | Requisito |
|---|---|
| RF01 | O sistema deve permitir autenticação via login e senha, retornando um token JWT |
| RF02 | O sistema deve permitir cadastrar, listar, atualizar e excluir produtos |
| RF03 | O sistema deve permitir cadastrar, listar, atualizar e excluir categorias |
| RF04 | O sistema deve permitir cadastrar, listar, atualizar e excluir fornecedores |
| RF05 | Todo produto deve estar associado a exatamente uma categoria e um fornecedor |
| RF06 | O sistema deve permitir que um administrador cadastre, liste, atualize e exclua usuários |
| RF07 | O sistema deve permitir associar um ou mais papéis (roles) a cada usuário |
| RF08 | O sistema deve permitir consultar a lista de papéis disponíveis (somente leitura) |
| RF09 | O sistema deve documentar automaticamente sua API (Swagger/OpenAPI) |
| ID | Requisito |
|---|---|
| RNF01 | O sistema deve exigir autenticação para todas as operações, exceto login e recursos estáticos/documentação |
| RNF02 | Operações de escrita (criar/editar/excluir) em Produto, Fornecedor e Usuário devem exigir o papel ADMIN |
| RNF03 | Senhas devem ser armazenadas de forma criptografada (BCrypt), nunca em texto plano |
| RNF04 | A sessão deve ser stateless (token JWT), sem estado de sessão guardado no servidor |
| RNF05 | Entradas inválidas devem ser rejeitadas com mensagens de erro claras (Bean Validation) antes de qualquer alteração no banco |
| RNF06 | O sistema deve funcionar em navegador web via uma SPA (Single Page Application) |
📌 Backlog futuro (fora do escopo atual): movimentação de estoque com histórico de entrada/saída, alertas de estoque mínimo, e relatórios gerenciais não fazem parte do sistema hoje — ficam como evolução natural para uma trilha de nível Sênior, no mesmo espírito do Controle de Gastos 04.
Dois atores interagem com o sistema: o Usuário (autenticado, sem papel administrativo) e o Administrador (papel ADMIN), que herda tudo que o Usuário pode fazer e ganha as operações de escrita/gestão.
flowchart LR
Usuario(["👤 Usuário"])
Admin(["🛡️ Administrador"])
subgraph SISTEMA["Sistema de Gestão de Estoques"]
UC1(["Fazer Login"])
UC2(["Consultar Produtos"])
UC3(["Consultar Categorias"])
UC4(["Consultar Fornecedores"])
UC5(["Cadastrar Produto"])
UC6(["Atualizar Produto"])
UC7(["Excluir Produto"])
UC8(["Gerenciar Categorias"])
UC9(["Gerenciar Fornecedores"])
UC10(["Gerenciar Usuários"])
UC11(["Consultar Papéis"])
end
Usuario --> UC1
Usuario --> UC2
Usuario --> UC3
Usuario --> UC4
Admin --> UC1
Admin --> UC5
Admin --> UC6
Admin --> UC7
Admin --> UC8
Admin --> UC9
Admin --> UC10
Admin --> UC11
UC5 -.->|inclui| UC2
UC6 -.->|inclui| UC2
UC7 -.->|inclui| UC2
💡 Por que
UC5/UC6/UC7“incluem”UC2? Cadastrar, atualizar e excluir um produto sempre retornam/dependem da lista consultada — no fluxo real da SPA, toda operação de escrita recarrega a listagem (router()é chamado de novo após osubmit/delete). É a relação<<include>>clássica de UML: um caso de uso reaproveita o comportamento de outro.
A organização do nosso projeto segue as convenções do Maven e as melhores práticas para uma aplicação Spring Boot com uma API REST desacoplada e um frontend SPA.
gestaodeestoques/
├── .mvn/ // Arquivos do Maven Wrapper
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── br/com/aula/gestaodeestoques/
│ │ │ ├── GestaodeestoquesApplication.java // Ponto de entrada da aplicação Spring Boot
│ │ │ ├── config/
│ │ │ │ ├── DataSeeder.java // Popula o banco de dados com dados iniciais (idempotente)
│ │ │ │ ├── OpenApiConfig.java // Configuração global do Swagger/OpenAPI
│ │ │ │ └── SecurityConfig.java // Configuração principal do Spring Security (stateless com JWT)
│ │ │ │ └── security/
│ │ │ │ ├── JwtAuthenticationFilter.java // O "segurança" que valida o token em cada requisição
│ │ │ │ └── JwtTokenProvider.java // Classe utilitária para criar e validar tokens JWT
│ │ │ ├── controller/
│ │ │ │ ├── AuthenticationController.java // Endpoint para login (/api/auth/login)
│ │ │ │ ├── CategoriaController.java // Endpoints para /api/categorias
│ │ │ │ ├── FornecedorController.java // Endpoints para /api/fornecedores
│ │ │ │ ├── PapelController.java // Endpoint para /api/papeis (só leitura, ADMIN)
│ │ │ │ ├── ProdutoController.java // Endpoints para /api/produtos
│ │ │ │ └── UsuarioController.java // Endpoints para /api/usuarios (ADMIN)
│ │ │ ├── dto/
│ │ │ │ ├── CategoriaDTO.java
│ │ │ │ ├── ErrorResponseDTO.java // DTO para padronizar respostas de erro
│ │ │ │ ├── FornecedorDTO.java
│ │ │ │ ├── ProdutoDTO.java // DTO para exibir produtos
│ │ │ │ ├── ProdutoFormDTO.java // DTO para receber dados de formulários de produto
│ │ │ │ ├── UsuarioDTO.java // DTO para exibir usuários (sem a senha)
│ │ │ │ ├── UsuarioFormDTO.java // DTO para criar/atualizar usuários
│ │ │ │ ├── ValidationErrorResponseDTO.java // DTO de erro para falhas de Bean Validation
│ │ │ │ └── auth/
│ │ │ │ ├── JwtAuthenticationResponse.java // DTO para a resposta de login com o token
│ │ │ │ └── LoginRequest.java // DTO para a requisição de login
│ │ │ ├── exception/
│ │ │ │ ├── GlobalExceptionHandler.java // Handler global para tratar exceções da API
│ │ │ │ └── ResourceNotFoundException.java // Exceção customizada para erros 404
│ │ │ ├── mapper/
│ │ │ │ ├── CategoriaMapper.java
│ │ │ │ ├── FornecedorMapper.java
│ │ │ │ ├── ProdutoMapper.java
│ │ │ │ └── UsuarioMapper.java
│ │ │ ├── model/
│ │ │ │ ├── Categoria.java
│ │ │ │ ├── Fornecedor.java
│ │ │ │ ├── Papel.java
│ │ │ │ ├── Produto.java
│ │ │ │ └── Usuario.java
│ │ │ ├── repository/
│ │ │ │ ├── CategoriaRepository.java
│ │ │ │ ├── FornecedorRepository.java
│ │ │ │ ├── PapelRepository.java
│ │ │ │ ├── ProdutoRepository.java
│ │ │ │ └── UsuarioRepository.java
│ │ │ └── service/
│ │ │ ├── DatabaseUserDetailsService.java // Carrega usuário + papéis para o Spring Security
│ │ │ ├── CategoriaService.java, FornecedorService.java, PapelService.java, ProdutoService.java, UsuarioService.java // Interfaces dos serviços
│ │ │ └── impl/
│ │ │ └── CategoriaServiceImpl.java, FornecedorServiceImpl.java, PapelServiceImpl.java, ProdutoServiceImpl.java, UsuarioServiceImpl.java // Implementações
│ │ └── resources/
│ │ ├── application.properties // Configurações principais (H2, JWT secret)
│ │ ├── application-prod.properties // Configurações para o ambiente de produção (PostgreSQL)
│ │ ├── schema.sql // Script de criação das tabelas para o H2 (dev)
│ │ ├── schema-prod.sql // Script equivalente em sintaxe Postgres, idempotente (prod)
│ │ └── static/ // <-- Raiz de todos os arquivos do Frontend (SPA)
│ │ ├── css/
│ │ │ └── style.css
│ │ ├── js/
│ │ │ ├── api.js // Módulo para centralizar as chamadas à API
│ │ │ ├── auth.js // Módulo para gerenciar autenticação (token, login, logout)
│ │ │ └── router.js // Módulo para roteamento no lado do cliente
│ │ ├── index.html // A "casca" principal da SPA
│ │ └── login.html // Página de login estática
│ └── test/
│ └── java/
│ └── br/com/aula/gestaodeestoques/
│ ├── GestaodeestoquesApplicationTests.java
│ ├── controller/
│ │ └── ProdutoControllerTest.java // Teste de integração para o controller de produtos
│ └── service/
│ └── impl/
│ └── ProdutoServiceImplTest.java // Teste unitário para o serviço de produtos
├── .gitignore // Arquivos e pastas a serem ignorados pelo Git
├── Dockerfile // Receita para construir a imagem Docker da aplicação
├── docker-compose.yml // Orquestrador para subir a API e o banco PostgreSQL
├── mvnw // Executável do Maven Wrapper para Unix/Linux
├── mvnw.cmd // Script do Maven Wrapper para Windows
└── pom.xml // O coração do projeto Maven: dependências e build
Esta estrutura não é aleatória; ela segue o princípio da Separação de Responsabilidades para manter o projeto organizado e escalável.
src/main/java/br/com/aula/gestaodeestoques/ - O Coração do Backendconfig/: Contém todas as classes de configuração do Spring. A separação em um subpacote security/ ajuda a isolar a complexidade da autenticação JWT.controller/: A camada mais externa do backend. Responsável por expor os endpoints da API, receber requisições HTTP e retornar respostas JSON. Não contém lógica de negócio.dto/: Objetos de Transferência de Dados. São os “contratos” da nossa API, definindo a estrutura dos dados que entram e saem.exception/: Classes para tratamento de erros, incluindo o GlobalExceptionHandler que padroniza as respostas de erro da API.mapper/: Classes responsáveis pela conversão entre as entidades do banco (model) e os objetos de transferência (dto).model/: As entidades que representam as tabelas do nosso banco de dados. São a representação interna dos nossos dados.repository/: Interfaces do Spring Data que definem como acessar o banco de dados. Abstraem toda a complexidade do JDBC/SQL.service/: O “cérebro” da aplicação. Contém toda a lógica de negócio (regras, orquestração de operações). As impl/ são as implementações concretas das interfaces de serviço.src/main/resources/ - Configurações e o Frontendapplication.properties: Arquivos de configuração do Spring. O uso de perfis (ex: application-prod.properties) permite ter configurações diferentes para ambientes diferentes.schema.sql: Usado pelo H2 para criar o banco em memória, ideal para o ambiente de desenvolvimento.static/: Este é o nosso frontend. Como estamos construindo uma SPA, todos os arquivos HTML, CSS e JavaScript são servidos como arquivos estáticos pelo Spring Boot. O backend não sabe e não se importa com o conteúdo desses arquivos; ele apenas os entrega ao navegador./) - Ferramentas de Build e Deploypom.xml: Define todas as dependências do projeto e como ele deve ser compilado e empacotado.Dockerfile e docker-compose.yml: Ferramentas de DevOps. Definem como nossa aplicação será “empacotada” em um container e como ela irá rodar junto com outros serviços (como um banco de dados) em qualquer ambiente.Esta estrutura clara e bem definida é a marca de um projeto profissional, tornando-o mais fácil de entender, manter e escalar no futuro.