Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Faça como eu fiz: cancelamento de consultas

Contextualizando:

A funcionalidade de Cancelamento de consulta deve seguir tais regras de negocio:

É obrigatório informar o motivo do cancelamento da consulta, dentre as opções: paciente desistiu, médico cancelou ou outros;

Uma consulta somente poderá ser cancelada com antecedência mínima de 24 horas.

Dito isso, a forma que eu resolvi foi que o ConsultaRepository encontrasse a Consulta a partir de uma query que já verifica se a consulta agendada tem antecedência de 24 horas:

public interface ConsultaRepository extends JpaRepository<Consulta, Long> {

    @Query("""
            select c from Consulta c
            where
            c.id = :id
            and
            c.data > CURRENT_DATE + 1 DAY
            """)
    Optional<Consulta> findByIdWhereIntervalDay(Long id);
}

Ou seja:

Supondo que:

MM-DDThh:mm:ss
    
Se o paciente marcou a consulta em:
    
    03-04T10:00:00

Então ele poderia cancelar até o dia:

    03-03T09:59:59

Ou seja, um dia antes do dia da consulta

De resto foi o feijão com o arroz:

Em DadosCancelamentoConsulta:

public record DadosCancelamentoConsulta(
        @NotNull Long id,
        @NotNull MotivoDeCancelamento motivo) {
}

Em MotivoDeCancelamento:

public enum MotivoDeCancelamento {
    PACIENTE_DESISTIU,
    MEDICO_CANCELOU,
    OUTROS
}

Em ConsultaController:

    @DeleteMapping("/cancelar")
    @Transactional
    public ResponseEntity<Void> calcelarConsulta(@RequestBody @Valid DadosCancelamentoConsulta dados) {
        agenda.cancelar(dados);
        return ResponseEntity.noContent().build();
    }

Em AgendaDeConsultas:

    public void cancelar(DadosCancelamentoConsulta dados) {
        if (!consultaRepository.existsById(dados.id())) {
            throw new ValidacaoException("O id informado não existe");
        }

        var consulta = consultaRepository.findByIdWhereIntervalDay(dados.id())
            .orElseThrow(() -> new ValidacaoException( 
            "A consulta informada não pode ser cancelada, pois uma consulta só pode ser cancelada com antecedência mínima de 24 horas."));

        consultaRepository.deleteById(consulta.getId());
    }

Vale resaltar que neste exemplo eu não fiz nada com o motivo de cancelamento, apenas verifiquei se existia (com a anotação @NotNull no record DadosCancelamentoConsulta ), tanto é que a classe Consulta não tem um atributo que guarda o motivo.

2 respostas
solução!

Oi, Kauã! Como vai?

Agradeço por compartilhar seu código com a comunidade Alura.

A sua solução ficou bem organizada. A ideia de criar uma query personalizada no ConsultaRepository para já validar a antecedência mínima de 24 horas mostra um bom entendimento de como mover regras para o acesso a dados quando faz sentido. Também ficou claro o uso correto de Optional para validar a existência da consulta e o fluxo de validação antes do cancelamento.

Uma dica interessante para o futuro é usar o método orElseThrow() do Optional, que ajuda a deixar o código mais direto ao lidar com validações.


var consulta = consultaRepository.findById(id)
    .orElseThrow(() -> new RuntimeException("consulta nao encontrada"));

System.out.println(consulta.getId());

Esse código tenta buscar uma consulta pelo id e, caso não exista, lança uma exceção automaticamente. Isso evita verificações extras e deixa o fluxo mais simples de ler.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Obrigado pela sugestão! O codigo de verificação realmente ficou mais limpo.