diff --git a/pom.xml b/pom.xml index 3b28882..c669f1c 100644 --- a/pom.xml +++ b/pom.xml @@ -176,7 +176,6 @@ - diff --git a/src/main/java/com/classes/config/SecurityConfig.java b/src/main/java/com/classes/config/SecurityConfig.java index 38694cc..26e0134 100644 --- a/src/main/java/com/classes/config/SecurityConfig.java +++ b/src/main/java/com/classes/config/SecurityConfig.java @@ -30,7 +30,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti "/swagger-ui/**", "/v3/api-docs/**", "/saludo", - "/" + "/", + "/test/**" ).permitAll() .anyRequest().authenticated() ) diff --git a/src/main/java/com/classes/controllers/ClassController.java b/src/main/java/com/classes/controllers/ClassController.java new file mode 100644 index 0000000..cbc1051 --- /dev/null +++ b/src/main/java/com/classes/controllers/ClassController.java @@ -0,0 +1,45 @@ +package com.classes.controllers; + +import com.classes.dtos.ClassDTO; +import com.classes.services.ClassService; +import org.springframework.web.bind.annotation.PostMapping; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.UUID; + +@RestController +@RequestMapping("/api/classes") +@RequiredArgsConstructor +public class ClassController { + + private final ClassService classService; + + + @PostMapping + public ResponseEntity createClass(@RequestBody ClassDTO dto) { + ClassDTO created = classService.createClass(dto); + return new ResponseEntity<>(created, HttpStatus.CREATED); + } + + @GetMapping + public ResponseEntity> findAllClasses() { + List list = classService.findAll(); + return ResponseEntity.ok(list); + } + + @PutMapping("/{id}") + public ResponseEntity updateClass(@PathVariable UUID id, @RequestBody ClassDTO dto) { + ClassDTO updated = classService.updateClass(id, dto); + return ResponseEntity.ok(updated); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteClass(@PathVariable UUID id) { + classService.deleteClass(id); + return ResponseEntity.ok("Clase eliminada correctamente"); + } +} diff --git a/src/main/java/com/classes/controllers/HelloController.java b/src/main/java/com/classes/controllers/HelloController.java index 05b7594..365769b 100644 --- a/src/main/java/com/classes/controllers/HelloController.java +++ b/src/main/java/com/classes/controllers/HelloController.java @@ -1,12 +1,15 @@ package com.classes.controllers; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/saludo") +@RequestMapping("/test") public class HelloController { - public String saludo() { - return "Microservicio de clases activo"; + @GetMapping("saludo") + public ResponseEntity saludo() { + return ResponseEntity.ok("Microservicio de clases activo"); } } diff --git a/src/main/java/com/classes/controllers/TrainerController.java b/src/main/java/com/classes/controllers/TrainerController.java index 40ed7c7..04dd2da 100644 --- a/src/main/java/com/classes/controllers/TrainerController.java +++ b/src/main/java/com/classes/controllers/TrainerController.java @@ -1,5 +1,7 @@ package com.classes.controllers; +import com.classes.annotations.AdminAccess; +import com.classes.annotations.AdminOrTrainerAccess; import com.classes.dtos.TrainerDTO; import com.classes.services.TrainerService; import com.fasterxml.jackson.databind.ObjectMapper; @@ -10,6 +12,11 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -26,6 +33,7 @@ public class TrainerController { private final TrainerService trainerService; + @AdminAccess @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity createTrainer( @RequestParam("trainer") String trainerJson, @@ -40,18 +48,21 @@ public ResponseEntity createTrainer( return ResponseEntity.status(HttpStatus.CREATED).body(createdTrainer); } + @PreAuthorize("@authService.canAccessResource(#id, authentication)") @GetMapping("/{id}") public ResponseEntity getTrainerById(@PathVariable UUID id) { TrainerDTO trainer = trainerService.getTrainerById(id); return ResponseEntity.ok(trainer); } + @AdminAccess @GetMapping public ResponseEntity> getAllTrainers() { List trainers = trainerService.getAllTrainers(); return ResponseEntity.ok(trainers); } + @PreAuthorize("@authService.canAccessResource(#ownerId, authentication)") @PutMapping(value = "/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity updateTrainer( @PathVariable UUID id, @@ -67,14 +78,17 @@ public ResponseEntity updateTrainer( return ResponseEntity.ok(updatedTrainer); } + @DeleteMapping("/{id}") public ResponseEntity deleteTrainer(@PathVariable UUID id) { try { trainerService.deleteTrainer(id); return ResponseEntity.noContent().build(); - } catch (EntityNotFoundException e) { + } catch ( + EntityNotFoundException e) { return ResponseEntity.notFound().build(); - } catch (IOException e) { + } catch ( + IOException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } diff --git a/src/main/java/com/classes/dtos/ClassDTO.java b/src/main/java/com/classes/dtos/ClassDTO.java new file mode 100644 index 0000000..bfa1099 --- /dev/null +++ b/src/main/java/com/classes/dtos/ClassDTO.java @@ -0,0 +1,23 @@ +package com.classes.dtos; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.UUID; + +@Data +public class ClassDTO { + private UUID id; + private String className; + private UUID locationId; + @JsonFormat(pattern = "dd-MM-yyyy") + private LocalDate classDate; + private int duration; + private UUID trainerId; + private int maxCapacity; + private LocalTime startTime; + private boolean active; + private String description; +} diff --git a/src/main/java/com/classes/dtos/TrainerDTO.java b/src/main/java/com/classes/dtos/TrainerDTO.java index f202d8f..2a7743e 100644 --- a/src/main/java/com/classes/dtos/TrainerDTO.java +++ b/src/main/java/com/classes/dtos/TrainerDTO.java @@ -1,9 +1,9 @@ package com.classes.dtos; -import com.classes.Enums.ContractType; -import com.classes.Enums.DayAvailability; -import com.classes.Enums.Gender; -import com.classes.Enums.TrainerStatus; +import com.classes.enums.ContractType; +import com.classes.enums.DayAvailability; +import com.classes.enums.Gender; +import com.classes.enums.TrainerStatus; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; @@ -18,7 +18,7 @@ public class TrainerDTO { private String lastName; private String dni; - @JsonFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "dd-MM-yyyy") private LocalDate birthDate; private Gender gender; @@ -32,7 +32,7 @@ public class TrainerDTO { private List certifications; private Set availability; - @JsonFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "dd-MM-yyyy") private LocalDate hireDate; private TrainerStatus status; diff --git a/src/main/java/com/classes/entities/ClassEntity.java b/src/main/java/com/classes/entities/ClassEntity.java index 4ca9111..aca092b 100644 --- a/src/main/java/com/classes/entities/ClassEntity.java +++ b/src/main/java/com/classes/entities/ClassEntity.java @@ -5,6 +5,8 @@ import jakarta.persistence.*; import lombok.*; +import java.time.LocalDate; +import java.time.LocalTime; import java.util.UUID; @Entity @@ -18,13 +20,19 @@ public class ClassEntity { @Id @GeneratedValue(strategy = GenerationType.UUID) private UUID id; - private String title; - @Column(length = 2000) - private String description; - @Column(name = "trainer_id") + private String name; +// private UUID LocationId; + private String className; + private int duration; private UUID trainerId; - @Column(name = "max_capacity") - private Integer maxCapacity; + private int maxCapacity; + private LocalTime startTime; + private boolean active; + private String description; + @ManyToOne + @JoinColumn(name = "location_id") + private LocationEntity location; + @Embedded private Audit audit; } diff --git a/src/main/java/com/classes/entities/TrainerEntity.java b/src/main/java/com/classes/entities/TrainerEntity.java index 61f9400..c3f6222 100644 --- a/src/main/java/com/classes/entities/TrainerEntity.java +++ b/src/main/java/com/classes/entities/TrainerEntity.java @@ -1,9 +1,9 @@ package com.classes.entities; -import com.classes.Enums.ContractType; -import com.classes.Enums.DayAvailability; -import com.classes.Enums.Gender; -import com.classes.Enums.TrainerStatus; +import com.classes.enums.ContractType; +import com.classes.enums.DayAvailability; +import com.classes.enums.Gender; +import com.classes.enums.TrainerStatus; import com.classes.config.Audit; import com.classes.config.AuditListener; import jakarta.persistence.*; diff --git a/src/main/java/com/classes/Enums/ContractType.java b/src/main/java/com/classes/enums/ContractType.java similarity index 78% rename from src/main/java/com/classes/Enums/ContractType.java rename to src/main/java/com/classes/enums/ContractType.java index c5d5b42..1b507b6 100644 --- a/src/main/java/com/classes/Enums/ContractType.java +++ b/src/main/java/com/classes/enums/ContractType.java @@ -1,4 +1,4 @@ -package com.classes.Enums; +package com.classes.enums; public enum ContractType { TIEMPO_COMPLETO, diff --git a/src/main/java/com/classes/Enums/DayAvailability.java b/src/main/java/com/classes/enums/DayAvailability.java similarity index 81% rename from src/main/java/com/classes/Enums/DayAvailability.java rename to src/main/java/com/classes/enums/DayAvailability.java index e394d67..ac2d5df 100644 --- a/src/main/java/com/classes/Enums/DayAvailability.java +++ b/src/main/java/com/classes/enums/DayAvailability.java @@ -1,4 +1,4 @@ -package com.classes.Enums; +package com.classes.enums; public enum DayAvailability { diff --git a/src/main/java/com/classes/Enums/Gender.java b/src/main/java/com/classes/enums/Gender.java similarity index 78% rename from src/main/java/com/classes/Enums/Gender.java rename to src/main/java/com/classes/enums/Gender.java index 543fa99..ba01901 100644 --- a/src/main/java/com/classes/Enums/Gender.java +++ b/src/main/java/com/classes/enums/Gender.java @@ -1,4 +1,4 @@ -package com.classes.Enums; +package com.classes.enums; public enum Gender { MASCULINO, // Masculino diff --git a/src/main/java/com/classes/Enums/TrainerStatus.java b/src/main/java/com/classes/enums/TrainerStatus.java similarity index 89% rename from src/main/java/com/classes/Enums/TrainerStatus.java rename to src/main/java/com/classes/enums/TrainerStatus.java index 68fb885..ff5af03 100644 --- a/src/main/java/com/classes/Enums/TrainerStatus.java +++ b/src/main/java/com/classes/enums/TrainerStatus.java @@ -1,4 +1,4 @@ -package com.classes.Enums; +package com.classes.enums; public enum TrainerStatus { ACTIVO, // Entrenador activo diff --git a/src/main/java/com/classes/exceptions/GlobalExceptionController.java b/src/main/java/com/classes/exceptions/GlobalExceptionController.java index 001c963..889de7f 100644 --- a/src/main/java/com/classes/exceptions/GlobalExceptionController.java +++ b/src/main/java/com/classes/exceptions/GlobalExceptionController.java @@ -1,5 +1,6 @@ package com.classes.exceptions; +import jakarta.persistence.EntityNotFoundException; import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -7,6 +8,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; //import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.AccessDeniedException; import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -108,19 +110,28 @@ public ResponseEntity handleNoHandlerFoundException(NoHandlerFoun return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); } -// @ExceptionHandler(AccessDeniedException.class) -// public ResponseEntity handleAccessDeniedException(AccessDeniedException ex) { -// ErrorResponse errorResponse = new ErrorResponse( -// "ACCESS_DENIED", -// "Acceso denegado", -// Collections.singletonList("No tienes los permisos necesarios para realizar esta acción") -// ); -// -// log.warn("Access denied for user"); -// return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse); -// } + @ExceptionHandler(AccessDeniedException.class) + public ResponseEntity handleAccessDeniedException(AccessDeniedException ex) { + ErrorResponse errorResponse = new ErrorResponse( + "ACCESS_DENIED", + "Acceso denegado", + Collections.singletonList("No tienes los permisos necesarios para realizar esta acción") + ); + log.warn("Access denied for user"); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(errorResponse); + } + @ExceptionHandler(EntityNotFoundException.class) + public ResponseEntity handleEntityNotFoundException(EntityNotFoundException ex) { + ErrorResponse errorResponse = new ErrorResponse( + "ENTITY_NOT_FOUND", + "No se encontró la entidad solicitada", + List.of(ex.getMessage()) + ); + log.warn("Entity not found: {}", ex.getMessage()); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); + } } \ No newline at end of file diff --git a/src/main/java/com/classes/mappers/ClassMapper.java b/src/main/java/com/classes/mappers/ClassMapper.java new file mode 100644 index 0000000..a477bd5 --- /dev/null +++ b/src/main/java/com/classes/mappers/ClassMapper.java @@ -0,0 +1,24 @@ +package com.classes.mappers; + +import com.classes.config.MapStructConfig; +import com.classes.dtos.ClassDTO; +import com.classes.dtos.LocationDTO; +import com.classes.entities.ClassEntity; +import com.classes.entities.LocationEntity; +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; + +import java.util.List; + +@Mapper(config = MapStructConfig.class) +public interface ClassMapper { + ClassEntity toEntity(ClassDTO dto); + ClassDTO toDTO(ClassEntity entity); + List toDTOList(List entities); + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + void updateFromDto(ClassDTO dto, @MappingTarget ClassEntity entity); + + +} diff --git a/src/main/java/com/classes/repositories/ClassRepository.java b/src/main/java/com/classes/repositories/ClassRepository.java new file mode 100644 index 0000000..6e32432 --- /dev/null +++ b/src/main/java/com/classes/repositories/ClassRepository.java @@ -0,0 +1,15 @@ +package com.classes.repositories; + +import com.classes.entities.ClassEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; +import java.util.UUID; + +@Repository +public interface ClassRepository extends JpaRepository { + Optional findFirstByTrainerId(UUID trainerId); + Optional findFirstByLocationId(UUID locationId); + +} diff --git a/src/main/java/com/classes/services/ClassService.java b/src/main/java/com/classes/services/ClassService.java new file mode 100644 index 0000000..89cd363 --- /dev/null +++ b/src/main/java/com/classes/services/ClassService.java @@ -0,0 +1,14 @@ +package com.classes.services; + +import com.classes.dtos.ClassDTO; + +import java.util.List; +import java.util.UUID; + +public interface ClassService { + + ClassDTO createClass(ClassDTO dto); + List findAll(); + ClassDTO updateClass(UUID id, ClassDTO dto); + void deleteClass(UUID id); +} diff --git a/src/main/java/com/classes/services/Impl/AuthServiceImpl.java b/src/main/java/com/classes/services/Impl/AuthServiceImpl.java new file mode 100644 index 0000000..ebbecb7 --- /dev/null +++ b/src/main/java/com/classes/services/Impl/AuthServiceImpl.java @@ -0,0 +1,31 @@ +package com.classes.services.Impl; + +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +public class AuthServiceImpl { + + public boolean hasRole(Authentication authentication, String role) { + return authentication.getAuthorities().stream() + .anyMatch(a -> a.getAuthority().equals(role)); + } + + public UUID getUserId(Authentication authentication) { + String userIdStr = ((JwtAuthenticationToken) authentication).getToken().getClaim("user_id"); + return UUID.fromString(userIdStr); + } + + // Verifica si el usuario es admin o dueño del recurso + public boolean canAccessResource(UUID ownerId, Authentication authentication) { + return hasRole(authentication, "ROLE_ADMIN") || ownerId.equals(getUserId(authentication)); + } + + // Verifica si el usuario tiene un rol específico o es dueño del recurso + public boolean canAccessWithRoleOrOwner(UUID ownerId, Authentication authentication, String role) { + return hasRole(authentication, role) || ownerId.equals(getUserId(authentication)); + } +} diff --git a/src/main/java/com/classes/services/Impl/ClassServiceImpl.java b/src/main/java/com/classes/services/Impl/ClassServiceImpl.java new file mode 100644 index 0000000..621a14e --- /dev/null +++ b/src/main/java/com/classes/services/Impl/ClassServiceImpl.java @@ -0,0 +1,70 @@ +package com.classes.services.Impl; + +import com.classes.dtos.ClassDTO; +import com.classes.entities.ClassEntity; +import com.classes.mappers.ClassMapper; +import com.classes.repositories.ClassRepository; +import com.classes.repositories.LocationRepository; +import com.classes.repositories.TrainerRepository; +import com.classes.services.ClassService; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.UUID; + + +@Service +@RequiredArgsConstructor +public class ClassServiceImpl implements ClassService { + + private final ClassRepository repository; + private final ClassMapper classMapper; + private final TrainerRepository trainerRepository; + private final LocationRepository locationRepository; + + + @Transactional + @Override + public ClassDTO createClass(ClassDTO dto) { + validateTrainerAndLocation(dto); + ClassEntity entity = classMapper.toEntity(dto); + ClassEntity saved = repository.save(entity); + return classMapper.toDTO(saved); + } + + @Transactional(readOnly = true) + @Override + public List findAll() { + List entities = repository.findAll(); + return classMapper.toDTOList(entities); + } + + @Transactional + @Override + public ClassDTO updateClass(UUID id, ClassDTO dto) { + ClassEntity existing = repository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("La clase con ID " + id + " no existe")); + validateTrainerAndLocation(dto); + classMapper.updateFromDto(dto, existing); + ClassEntity updated = repository.save(existing); + return classMapper.toDTO(updated); + } + + @Transactional + @Override + public void deleteClass(UUID id) { + + } + + private void validateTrainerAndLocation(ClassDTO dto) { + if (!trainerRepository.existsById(dto.getTrainerId())) { + throw new IllegalArgumentException("El trainer con ID " + dto.getTrainerId() + " no existe"); + } + if (!locationRepository.existsById(dto.getLocationId())) { + throw new IllegalArgumentException("La ubicación con ID " + dto.getLocationId() + " no existe"); + } + } +} diff --git a/src/main/java/com/classes/services/Impl/LocationServiceImpl.java b/src/main/java/com/classes/services/Impl/LocationServiceImpl.java index 2a25aff..f7d8bde 100644 --- a/src/main/java/com/classes/services/Impl/LocationServiceImpl.java +++ b/src/main/java/com/classes/services/Impl/LocationServiceImpl.java @@ -3,6 +3,7 @@ import com.classes.dtos.LocationDTO; import com.classes.entities.LocationEntity; import com.classes.mappers.LocationMapper; +import com.classes.repositories.ClassRepository; import com.classes.repositories.LocationRepository; import com.classes.services.LocationService; import lombok.AllArgsConstructor; @@ -23,6 +24,7 @@ public class LocationServiceImpl implements LocationService { private final LocationRepository repository; private final LocationMapper mapper; + private final ClassRepository classRepository; @Override @Transactional @@ -51,9 +53,16 @@ public LocationEntity findById(UUID id) { @Transactional @Override public void delete(UUID id) { + boolean hasClasses = classRepository.findFirstByLocationId(id).isPresent(); + if (hasClasses) { + throw new IllegalArgumentException( + "No se puede eliminar porque hay clases asociadas con este ID" + ); + } repository.deleteById(id); } + @Transactional(readOnly = true) public Page findAll(int page, int size) { Pageable pageable = PageRequest.of(page, size, Sort.by("name").ascending()); diff --git a/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java b/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java index a8175ef..fddeff6 100644 --- a/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java +++ b/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java @@ -4,11 +4,13 @@ import com.classes.dtos.TrainerDTO; import com.classes.entities.TrainerEntity; import com.classes.mappers.TrainerMapper; +import com.classes.repositories.ClassRepository; import com.classes.repositories.TrainerRepository; import com.classes.services.AzureService; import com.classes.services.CloudinaryService; import com.classes.services.TrainerService; import jakarta.persistence.EntityNotFoundException; +import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -26,7 +28,9 @@ public class TrainerServiceImpl implements TrainerService { private final TrainerMapper trainerMapper; private final CloudinaryService cloudinaryService; private final AzureService azureStorageService; + private final ClassRepository classRepository; + @Transactional @Override public TrainerDTO createTrainer(TrainerDTO trainerDTO, MultipartFile profileImage, @@ -49,6 +53,7 @@ public TrainerDTO createTrainer(TrainerDTO trainerDTO, return trainerMapper.toDTO(savedTrainer); } + @Transactional(readOnly = true) @Override public TrainerDTO getTrainerById(UUID id) { TrainerEntity trainer = trainerRepository.findById(id) @@ -56,11 +61,13 @@ public TrainerDTO getTrainerById(UUID id) { return trainerMapper.toDTO(trainer); } + @Transactional(readOnly = true) @Override public List getAllTrainers() { return trainerMapper.toDTOList(trainerRepository.findAll()); } + @Transactional @Override public TrainerDTO updateTrainer(UUID id, TrainerDTO trainerDTO, @@ -86,10 +93,18 @@ public TrainerDTO updateTrainer(UUID id, TrainerEntity updated = trainerRepository.save(trainer); return trainerMapper.toDTO(updated); } + @Transactional @Override public void deleteTrainer(UUID id) throws IOException { TrainerEntity trainer = trainerRepository.findById(id) .orElseThrow(() -> new EntityNotFoundException("Trainer not found with id: " + id)); + + boolean hasClasses = classRepository.findFirstByTrainerId(id).isPresent(); + if (hasClasses) { + throw new IllegalArgumentException( + "No se puede eliminar el trainer porque tiene clases asignadas" + ); + } if (trainer.getProfileImageUrl() != null) { cloudinaryService.delete(trainer.getProfileImageUrl()); } diff --git a/src/main/java/com/classes/services/TrainerServiceImpl.java b/src/main/java/com/classes/services/TrainerServiceImpl.java deleted file mode 100644 index eb2a4a5..0000000 --- a/src/main/java/com/classes/services/TrainerServiceImpl.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.classes.services; - -public class TrainerServiceImpl { -}