Visão Geral da Arquitetura
Este sistema emprega uma arquitetura separada entre front-end e back-end. O back-end é construído com o framework SpringBoot, proporcionando uma base robusta para a lógica de negócios e serviços de API. O front-end, desenvolvido em Vue.js, fornece uma interface de usuário interativa e responsiva. Adicionalmente, uma aplicação multiplataforma é desenvolvida utilizando o uniapp, permitindo que o sistema seja acessado em diferentes dispositivos móveis. A persistência de dados é gerenciada pelo MyBatis-Plus, facilitando as operações de banco de dados.
Tecnologias Empregadas
SpringBoot no Back-end
O SpringBoot simplifica o desenvolvimento de aplicações Spring, fornecendo configuração automática e um servidor integrado. Ele permite que os desenvolvedores iniciem rapidamente projetos sem a necessidade de configurações complexas de sevridor. Recursos como Spring Data e Spring Security estão prontamente disponíveis para uso, acelerando o desenvolvimento de funcionalidades comuns e a integração com outros componentes.
Vue.js no Front-end
O Vue.js utiliza uma abordagem baseada em componentes e reatividade. Seu sistema de virtual DOM otimiza a manipulação da interface do usuário, atualizando apenas as partes necessárias do DOM quando o estado da aplicação muda. Isso resulta em um desemepnho eficiente e uma experiência de desenvolvimento simplificada, permitindo que os programadores foquem no tratamento de dados.
MyBatis-Plus para Acesso a Dados
O MyBatis-Plus estende as funcionalidades do MyBatis, reduzindo a necessidade de escrever código SQL repetitivo. Ele oferece recursos como paginação, consultas dinâmicas e uma ferramenta de geração de código, que pode criar entidades, interfaces Mapper e arquivos de mapeamento automaticamente, aumentando significativamente a produtividade no desenvolvimento da camada de persistência.
Estratégia de Testes do Sistema
A verificação completa do sistema é crucial para garantir sua qualidade e confiabilidade. O processo de teste visa identificar defeitos, validar a conformidade com os requisitos e assegurar uma experiência de usuário fluida. São realizados testes funcionais (caixa preta) para explorar diferentes cenários de uso.
Objetivos da Verificação
O teste visa descobrir vulnerabilidades e inconsistências lógicas antes da implantação. Ao simular interações reais do usuário, busca-se corrigir falhas que poderiam comprometer a funcionalidade do sistema e a satisfação do usuário final. Uma validação bem-sucedida confirma que o sistema atende às especificações definidas.
Cenários de Teste Funcional
Testes são conduzidos em módulos críticos, como autenticação e gerenciamento de usuários. As tabelas a seguir ilustram alguns casos de teste executados.
| Cenário | Dados de Entrada | Resultado Esperado | Resultado Obtido | Análise |
|---|---|---|---|---|
| Login válido | Usuário: admin_correto, Senha: senha_correta | Autenticação bem-sucedida | Sucesso no login | Conforme esperado |
| Senha incorreta | Usuário: admin_correto, Senha: senha_errada | Falha na autenticação | Mensagem de erro exibida | Conforme esperado |
| Campo obrigatório vazio | Usuário: [vazio], Senha: senha_qualquer | Validação de campo obrigatório | Mensagem solicitando preenchimento | Conforme esperado |
| Ação | Operação | Resultado Esperado | Resultado Obtido | Análise |
|---|---|---|---|---|
| Criar usuário | Inserir dados válidos | Registro inserido com sucesso | Novo usuário visível na lista | Conforme esperado |
| Excluir usuário | Confirmar remoção | Registro removido do sistema | Usuário não mais acessível | Conforme esperado |
| Atualizar dados | Modificar informações | Dados atualizados corretamente | Novas informações exibidas | Conforme esperado |
Conclusão dos Testes
Os testes abrangentes realizados demonstram que o sistema opera de acordo com as expectativas. Os módulos testados apresentam a lógica correta e uma usabilidade adequada, validando assim a integridade da implementação.
Exemplo de Código Refatorado
O trecho abaixo demonstra uma parte da lógica de autenticação e verificação de token, com estruturas e nomes de variáveis modificados para fins ilustrativos.
@RestController
@RequestMapping("/api/auth")
public class AuthenticationController {
@Autowired
private UserAuthenticationService authService;
@PostMapping("/signin")
public ResponseEntity<ApiResponse> authenticateUser(@RequestBody LoginRequest request) {
Optional<UserPrincipal> userOpt = authService.validateCredentials(request.getUsername(), request.getPassword());
if (userOpt.isEmpty()) {
return ResponseEntity.badRequest().body(new ApiResponse("Credenciais inválidas", 401));
}
String jwtToken = authService.generateJwtToken(userOpt.get());
return ResponseEntity.ok(new ApiResponse("Autenticação bem-sucedida", 200, Collections.singletonMap("accessToken", jwtToken)));
}
}
@Service
public class TokenGenerationService {
@Autowired
private TokenRepository tokenRepo;
public String createTokenForUser(Long userId, String userRole) {
String randomToken = generateSecureRandomString(40);
Instant expirationTime = Instant.now().plus(1, ChronoUnit.HOURS);
tokenRepo.findByUserIdAndRole(userId, userRole)
.ifPresentOrElse(
existing -> {
existing.setTokenValue(randomToken);
existing.setExpiryTimestamp(expirationTime);
tokenRepo.save(existing);
},
() -> {
Token newToken = new Token();
newToken.setUserId(userId);
newToken.setRole(userRole);
newToken.setTokenValue(randomToken);
newToken.setExpiryTimestamp(expirationTime);
tokenRepo.save(newToken);
}
);
return randomToken;
}
private String generateSecureRandomString(int length) {
// Lógica para gerar string aleatória segura
return ...;
}
}
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
throws ServletException, IOException {
String authHeader = req.getHeader("Authorization");
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
// Lógica para validar o token JWT e carregar detalhes do usuário
// ...
}
chain.doFilter(req, res);
}
}
Esquema do Banco de Dados (Referência)
A tabela abaixo armazena as sessões de token dos usuários.
CREATE TABLE user_session_token (
session_id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'Identificador único da sessão',
user_id BIGINT NOT NULL COMMENT 'ID do usuário associado',
user_login VARCHAR(100) NOT NULL COMMENT 'Login do usuário',
user_profile VARCHAR(50) COMMENT 'Perfil ou papel do usuário',
access_token VARCHAR(255) NOT NULL COMMENT 'Token de acesso gerado',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Data de criação do registro',
expires_at TIMESTAMP NOT NULL COMMENT 'Data e hora de expiração do token',
INDEX idx_user_profile (user_id, user_profile)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Tabela para gerenciamento de tokens de sessão de usuários';