- Contextualização do Projeto: A Necessidade de um Sistema de Saúde Escolar
No cenário atual das instituições de ensino, a gestão tradicional de informações de saúde, baseada em formulários em papel e planilhas eletrônicas, apresenta ineficiências críticas. A coleta manual de dados, como questionários de saúde e informações de retorno ao campus, resulta em processos demorados para geração de relatórios, sincronização deficiente de dados e dificuldades na rastreabilidade histórica. Estimativas indicam que uma parcela significativa do tempo administrativo é consumida por atividades de consolidação e verificação, impactando a capacidade de resposta a alertas sanitários.
Para endereçar esses desafios, desenvolveu-se um sistema baseado em arquitetura B/S (Navegador/Servidor) que automatiza o fluxo de dados entre administradores, professsores e alunos. A plataforma integra módulos para coleta de dados de saúde, aplicação de pesquisas epidemiológicas e gestão de informações de retorno, promovendo eficiência operacional e conformidade com protocolos de saúde pública em ambientes educacionais.
- Stack Tecnológico do Sistema
A pilha tecnológica foi selecionada visando estabilidade, segurança e facilidade de manutenção, adequada para operações em larga escala em instituições de ensino.
| Componente | Tecnologia | Função Principal |
|---|---|---|
| Backend | Spring Boot 2.x | Framework principal para desenvolvimento de serviços RESTful, simplificação de configurações, gerenciamento de transações e injeção de dependências. |
| Linguagem | Java | Linguagem de programação orientada a objetos com suporte a múltiplas plataformas, garantindo manutenibilidade e segurança de memória. |
| Banco de Dados | MySQL 8.0 | Sistema de gerenciamento de banco de dados relacional para armazenamento persistente de informações de usuários, registros de saúde e metadados de questionários. |
| Arquitetura | B/S (Navegador/Servidor) | Modelo de aplicação web que elimina a necessidade de instalação de clientes, permitindo acesso via navegadores em dispositivos variados. |
| Ferramentas de Desenvolvimento | Eclipse IDE e Navicat | Ambiente integrado para codificação e depuração, e ferramenta para administração visual do banco de dados MySQL. |
| Servidor de Aplicação | Apache Tomcat 9.0 | Container web para implantação da aplicação, gerenciamento de requisições concorrentes e garantia de disponibilidade. |
| Front end | JSP, HTML5 e CSS3 | Tecnologias para construção de interfaces de usuário responsivas, focando em usabilidade para formulários de entrada de dados e visualização de relatórios. |
- Processo de Desenvolvimento em Etapas
3.1 Análise de Requisitos
O sistema visa resolver ineficiências na coleta, análise e rastreabilidade de dados. Os requisitos funcionais incluem um modelo de três perfis de usuário com permissões distintas: Administrador (controle total sobre usuários, dados e relatórios), Professor (gestão de seus próprios dados e resposats a questionários) e Aluno (submissão de informações de saúde e questionários). Requisitos não funcionais enfatizam desempenho (suporte a mais de 100 acessos simultâneos), segurança (criptografia de dados sensíveis) e escalabilidade (interfaces para futuras expansões).
3.2 Design do Sistema
Utilizou-se o padrão MVC (Model-View-Controller) para desacoplar a lógica de negócios da representação de dados e da interface do usuário. A camada de apresentação (View) consiste em interfaces web para cada perfil de usuário. A camada de controle (Controller) processa requisições HTTP e orquestra a lógica de negócios. A camada de modelo (Model) gerencia a persistência de dados através do ORM MyBatis, garantindo integridade transacional em operações como cadastro de usuários e inserção de registros de saúde.
O design do banco de dados inclui tabelas fundamentais para armazenar informações de usuários, dados de saúde, metadados de questionários e registros de respostas. Exemplos de entidades incluem tabelas para administradores, alunos, professores, coletas de dados de saúde, questionários e respostas, garantindo relacionamentos claros através de chaves estrangeiras.
3.3 Implementação do Backend com Spring Boot
A implementação do backend foca na exposição de endpoints RESTful para operações CRUD. A seguir, exemplos de controladores e serviços reescritos com alterações na estrutura e nomenclatura.
Controlador para Dados de Saúde
@RestController
@RequestMapping("/api/saude")
public class ControladorDadosSaude {
@Autowired
private ServicoSaudeAluno servicoAluno;
@Autowired
private ServicoSaudeProfessor servicoProfessor;
@PostMapping("/aluno/registrar")
public ResponseEntity<mensagemresposta> registrarDadosSaudeAluno(@RequestBody @Valid DadosSaudeDTO dadosDTO) {
try {
// Validação de campos específicos, como intervalo de temperatura
if (dadosDTO.getTemperatura() < 35.0 || dadosDTO.getTemperatura() > 37.5) {
return ResponseEntity.badRequest().body(new MensagemResposta("Temperatura fora do intervalo aceitável."));
}
// Conversão e persistência do objeto
RegistroSaudeAluno registro = new RegistroSaudeAluno();
BeanUtils.copyProperties(dadosDTO, registro);
registro.setDataRegistro(LocalDateTime.now());
servicoAluno.salvar(registro);
return ResponseEntity.ok(new MensagemResposta("Dados registrados com sucesso."));
} catch (Exception e) {
return ResponseEntity.internalServerError().body(new MensagemResposta("Erro ao processar solicitação."));
}
}
@GetMapping("/admin/listar-alunos")
public ResponseEntity<list>> listarDadosSaudeAlunos(
@RequestParam(required = false) String filtroMatricula,
@RequestParam(required = false) String filtroNome) {
Map<string object=""> filtros = new HashMap<>();
if (StringUtils.hasText(filtroMatricula)) filtros.put("matricula", filtroMatricula);
if (StringUtils.hasText(filtroNome)) filtros.put("nome", filtroNome);
List<registrosaudealuno> resultados = servicoAluno.buscarComFiltros(filtros);
return ResponseEntity.ok(resultados);
}
}</registrosaudealuno></string></list></mensagemresposta>
Serviço para Questionários e Informações de Retorno
@Service
@Transactional
public class ServicoQuestionariosRetorno {
@Autowired
private RepositorioQuestionario repositorioQ;
@Autowired
private RepositorioResposta repositorioR;
@Autowired
private RepositorioRetorno repositorioRet;
public RespostaServico submeterRespostaQuestionario(RespostaQuestionario resposta, String idUsuario, String perfil) {
// Verificação da existência do questionário
Questionario questionario = repositorioQ.findById(resposta.getIdQuestionario())
.orElseThrow(() -> new RecursoNaoEncontradoException("Questionário não encontrado."));
// Preenchimento automático de metadados
resposta.setIdUsuario(idUsuario);
resposta.setPerfilUsuario(perfil);
resposta.setStatus("CONCLUIDO");
resposta.setDataSubmissao(LocalDateTime.now());
repositorioR.save(resposta);
return new RespostaServico(true, "Resposta registrada.");
}
public RespostaServico enviarInformacaoRetorno(InformacaoRetorno infoRetorno, String idAluno) {
// Verificação do usuário associado
Aluno aluno = servicoAluno.obterPorId(idAluno);
// Lógica de atualização ou inserção com base na existência de registro anterior
Optional<informacaoretorno> existente = repositorioRet.findByIdAluno(idAluno);
if (existente.isPresent()) {
InformacaoRetorno registroExistente = existente.get();
registroExistente.atualizarCom(infoRetorno);
repositorioRet.save(registroExistente);
return new RespostaServico(true, "Informação atualizada.");
} else {
infoRetorno.setIdAluno(idAluno);
repositorioRet.save(infoRetorno);
return new RespostaServico(true, "Informação enviada.");
}
}
}</informacaoretorno>
3.4 Controle de Acesso Baseado em Perfis
A autorização é implementada através de um filtro de servlet que intercepta requisições e verifica o perfil do usuário armazenado na sessão. Rotas específicas são mapeadas para cada perfil, garantindo que, por exemplo, apenas administradores possam acessar endpoints de gerenciamento de usuários. O código do filtro a seguir demonstra essa lógica com caminhos e mensagens de erro reescritos.
@Component
public class FiltroAutorizacao implements Filter {
private static final List<string> CAMINHOS_ADMIN = Arrays.asList("/admin/usuarios/", "/admin/relatorios/");
private static final List<string> CAMINHOS_PROFESSOR = Arrays.asList("/professor/dados/", "/professor/questionarios/");
private static final List<string> CAMINHOS_ALUNO = Arrays.asList("/aluno/submeter/", "/aluno/perfil/");
private static final List<string> CAMINHOS_REQUER_LOGIN = Arrays.asList("/api/", "/gestao/");
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpRes = (HttpServletResponse) res;
String uri = httpReq.getRequestURI();
String perfil = (String) httpReq.getSession().getAttribute("perfilUsuario");
String idUsuario = (String) httpReq.getSession().getAttribute("idUsuario");
// Verificação de permissões por perfil
boolean isRotaAdmin = CAMINHOS_ADMIN.stream().anyMatch(uri::startsWith);
if (isRotaAdmin && !"ADMIN".equals(perfil)) {
httpRes.setStatus(HttpServletResponse.SC_FORBIDDEN);
httpRes.getWriter().write("Acesso negado: permissão insuficiente.");
return;
}
// Lógica similar para professor e aluno...
// Verificação de autenticação para rotas protegidas
boolean rotaProtegida = CAMINHOS_REQUER_LOGIN.stream().anyMatch(uri::startsWith);
if (rotaProtegida && (idUsuario == null || perfil == null)) {
httpRes.sendRedirect("/login");
return;
}
chain.doFilter(req, res);
}
}</string></string></string></string>
3.5 Interface do Usuário
As interfaces foram projetadas com foco em simplicidade e eficiência, utilizando JSP e Bootstrap para criar layouts responsivos. O painel do administrador oferece visões consolidadas de dados e ferramentas de exportação. O portal do professor facilita a submissão de respostas a questionários e o gerenciamento de informações pessoais. A interface do aluno prioriza formulários intuitivos para entrada de dados de saúde, com validações em tempo real para campos como temperatura corpórea.
3.6 Testes e Validação
Os testes abrangeram cenários funcionais, de desempenho e segurança. Testes funcionais validaram fluxos como submissão de dados com valores válidos e inválidos, verificando mensagens de erro apropriadas. Testes de desempenho simularam múltiplos acessos simultâneos durante picos de uso, confirmando tempos de resposta dentro de limites aceitáveis. Testes de segurança incluíram tentativas de acesso não autorizado a rotas restritas e verificação de criptografia de dados sensíveis, assegurando conformidade com políticas de proteção de informações.