1
resposta

Faça como eu fiz: Cancelamento de Consultas

package med.voll.api.domain.consulta;

import jakarta.validation.constraints.NotNull;

public record DadosCancelamentoConsulta(
        @NotNull
        Long idConsulta,
        @NotNull
        MotivoCancelamento motivo
) {
}


package med.voll.api.domain.consulta;

public enum MotivoCancelamento {
    PACIENTE_DESISTIU,
    MEDICO_CANCELOU,
    OUTROS
}



package med.voll.api.domain.consulta;

import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDateTime;

@Entity
@Table(name = "consultas")
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Consulta {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private med.voll.api.domain.medico.Medico medico;

    @ManyToOne(fetch = FetchType.LAZY)
    private med.voll.api.domain.paciente.Paciente paciente;

    private LocalDateTime data;

    private Boolean cancelada;

    @Enumerated(EnumType.STRING)
    private MotivoCancelamento motivoCancelamento;

    public void cancelar(MotivoCancelamento motivo) {
        this.cancelada = true;
        this.motivoCancelamento = motivo;
    }
}


package med.voll.api.domain.consulta;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AgendaDeConsultas {

    @Autowired
    private ConsultaRepository consultaRepository;

    @Autowired
    private med.voll.api.domain.medico.MedicoRepository medicoRepository;

    @Autowired
    private med.voll.api.domain.paciente.PacienteRepository pacienteRepository;

    public void agendar(DadosAgendamentoConsulta dados) {
        if (!pacienteRepository.existsById(dados.idPaciente())) {
            throw new ValidacaoException("Id do paciente informado não existe!");
        }

        var paciente = pacienteRepository.findById(dados.idPaciente()).get();
        var medico = medicoRepository.findById(dados.idMedico()).get();

        var consulta = new Consulta(null, medico, paciente, dados.data(), false, null);
        consultaRepository.save(consulta);
    }

    public void cancelar(DadosCancelamentoConsulta dados) {
        var consulta = consultaRepository.getReferenceById(dados.idConsulta());
        consulta.cancelar(dados.motivo());
    }
}


package med.voll.api.controller;

import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import med.voll.api.domain.consulta.AgendaDeConsultas;
import med.voll.api.domain.consulta.DadosAgendamentoConsulta;
import med.voll.api.domain.consulta.DadosCancelamentoConsulta;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/consultas")
public class ConsultaController {

    @Autowired
    private AgendaDeConsultas agenda;

    @PostMapping
    @Transactional
    public ResponseEntity agendar(@RequestBody @Valid DadosAgendamentoConsulta dados) {
        agenda.agendar(dados);
        return ResponseEntity.ok().build();
    }

    @DeleteMapping
    @Transactional
    public ResponseEntity cancelar(@RequestBody @Valid DadosCancelamentoConsulta dados) {
        agenda.cancelar(dados);
        return ResponseEntity.noContent().build();
    }
}
1 resposta

Oi, Gabrielly! Como vai?

Seu código está muito bem estruturado! A separação das responsabilidades entre o domínio e o controller ficou clara, e a inclusão da enum para os motivos de cancelamento facilita bastante a legibilidade e manutenção.

Uma dica interessante para o futuro é adicionar uma verificação antes de cancelar a consulta para garantir que ela ainda não tenha sido cancelada. Veja este exemplo:


public void cancelar(MotivoCancelamento motivo) {
    if (this.cancelada != null && this.cancelada) {
        throw new IllegalStateException("Consulta já está cancelada.");
    }
    this.cancelada = true;
    this.motivoCancelamento = motivo;
}

Esse código evita que a consulta seja cancelada mais de uma vez, o que pode proteger sua lógica de negócio contra estados inesperados.

Você chegou a testar o comportamento para consultas já canceladas?

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