diff --git a/pom.xml b/pom.xml
index c669f1c..bc1d869 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,8 +13,8 @@
com.members
msvc-members
0.0.1-SNAPSHOT
- msvc-members
- msvc-members
+ msvc-classes
+ msvc-classes
@@ -122,11 +122,6 @@
1.5.5.Final
provided
-
- org.springdoc
- springdoc-openapi-starter-webmvc-ui
- 2.8.11
-
com.cloudinary
cloudinary-http44
diff --git a/src/main/java/com/classes/controllers/ClassController.java b/src/main/java/com/classes/controllers/ClassController.java
index cbc1051..c7188d6 100644
--- a/src/main/java/com/classes/controllers/ClassController.java
+++ b/src/main/java/com/classes/controllers/ClassController.java
@@ -1,7 +1,9 @@
package com.classes.controllers;
-import com.classes.dtos.ClassDTO;
+import com.classes.dtos.Class.ClassRequest;
+import com.classes.dtos.Class.ClassResponse;
import com.classes.services.ClassService;
+import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
@@ -19,25 +21,31 @@ 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);
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id, authentication)")
+ public ResponseEntity createClass(@RequestBody ClassRequest request) {
+ ClassResponse created = classService.createClass(request);
+ return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
@GetMapping
- public ResponseEntity> findAllClasses() {
- List list = classService.findAll();
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id, authentication)")
+ 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);
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id, authentication)")
+ public ResponseEntity updateClass(@PathVariable UUID id, @RequestBody ClassRequest request) {
+ ClassResponse updated = classService.updateClass(id, request);
return ResponseEntity.ok(updated);
}
@DeleteMapping("/{id}")
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id, authentication)")
public ResponseEntity deleteClass(@PathVariable UUID id) {
classService.deleteClass(id);
return ResponseEntity.ok("Clase eliminada correctamente");
diff --git a/src/main/java/com/classes/controllers/LocationController.java b/src/main/java/com/classes/controllers/LocationController.java
index 7d4a738..8efd485 100644
--- a/src/main/java/com/classes/controllers/LocationController.java
+++ b/src/main/java/com/classes/controllers/LocationController.java
@@ -1,16 +1,16 @@
package com.classes.controllers;
import com.classes.annotations.AdminOrTrainerAccess;
-import com.classes.dtos.LocationDTO;
-import com.classes.entities.LocationEntity;
+import com.classes.dtos.Location.LocationRequest;
+import com.classes.dtos.Location.LocationResponse;
import com.classes.services.LocationService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
-import java.util.List;
import java.util.UUID;
@RestController
@@ -21,29 +21,45 @@ public class LocationController {
private final LocationService locationService;
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@PostMapping
- public ResponseEntity create(@RequestBody LocationDTO dto) {
- LocationDTO created = locationService.create(dto);
+ public ResponseEntity create(@RequestBody LocationRequest request) {
+ LocationResponse created = locationService.create(request);
return new ResponseEntity<>(created, HttpStatus.CREATED);
}
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@GetMapping
- public ResponseEntity> findAll(
+ public ResponseEntity> findAll(
@RequestParam(defaultValue = "0") int page,
- @RequestParam(defaultValue = "10") int size
+ @RequestParam(defaultValue = "10") int size,
+ @RequestParam(required = false) String search,
+ @RequestParam(required = false) Boolean active
) {
- Page locations = locationService.findAll(page, size);
+ Page locations = locationService.findAll(page, size, search, active);
return ResponseEntity.ok(locations);
}
-
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@GetMapping("/{id}")
- public ResponseEntity findById(@PathVariable UUID id) {
- return ResponseEntity.ok(locationService.findById(id));
+ public ResponseEntity findById(@PathVariable UUID id) {
+ LocationResponse location = locationService.findById(id);
+ return ResponseEntity.ok(location);
+ }
+
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
+ @PutMapping("/{id}")
+ public ResponseEntity update(
+ @PathVariable UUID id,
+ @RequestBody LocationRequest request
+ ) {
+ LocationResponse updated = locationService.update(id, request);
+ return ResponseEntity.ok(updated);
}
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@DeleteMapping("/{id}")
public ResponseEntity delete(@PathVariable UUID id) {
- locationService.delete(id);
+ locationService.delete(id); // Validación interna
return ResponseEntity.noContent().build();
}
}
diff --git a/src/main/java/com/classes/controllers/TrainerController.java b/src/main/java/com/classes/controllers/TrainerController.java
index 04dd2da..07db9e2 100644
--- a/src/main/java/com/classes/controllers/TrainerController.java
+++ b/src/main/java/com/classes/controllers/TrainerController.java
@@ -1,22 +1,19 @@
package com.classes.controllers;
-import com.classes.annotations.AdminAccess;
-import com.classes.annotations.AdminOrTrainerAccess;
-import com.classes.dtos.TrainerDTO;
+import com.classes.dtos.Trainer.TrainerDTO;
+import com.classes.services.AuthorizationService;
import com.classes.services.TrainerService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
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;
@@ -29,13 +26,17 @@
@RestController
@RequestMapping("/api/trainers")
@RequiredArgsConstructor
+@Slf4j
public class TrainerController {
private final TrainerService trainerService;
+ private final AuthorizationService authService;
- @AdminAccess
+/*probado*/
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity createTrainer(
+ Authentication authentication,
@RequestParam("trainer") String trainerJson,
@RequestParam(value = "profileImage", required = false) MultipartFile profileImage,
@RequestParam(value = "certifications", required = false) List certifications
@@ -47,22 +48,23 @@ public ResponseEntity createTrainer(
TrainerDTO createdTrainer = trainerService.createTrainer(trainerDTO, profileImage, certifications);
return ResponseEntity.status(HttpStatus.CREATED).body(createdTrainer);
}
-
- @PreAuthorize("@authService.canAccessResource(#id, authentication)")
+ /*probado*/
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@GetMapping("/{id}")
public ResponseEntity getTrainerById(@PathVariable UUID id) {
TrainerDTO trainer = trainerService.getTrainerById(id);
return ResponseEntity.ok(trainer);
}
- @AdminAccess
+ //probado
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@GetMapping
public ResponseEntity> getAllTrainers() {
List trainers = trainerService.getAllTrainers();
return ResponseEntity.ok(trainers);
}
- @PreAuthorize("@authService.canAccessResource(#ownerId, authentication)")
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id, authentication)")
@PutMapping(value = "/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity updateTrainer(
@PathVariable UUID id,
@@ -79,6 +81,7 @@ public ResponseEntity updateTrainer(
}
+ @PreAuthorize("@authorizationServiceImpl.canAccessResource(#id,authentication)")
@DeleteMapping("/{id}")
public ResponseEntity deleteTrainer(@PathVariable UUID id) {
try {
@@ -94,3 +97,4 @@ public ResponseEntity deleteTrainer(@PathVariable UUID id) {
}
}
+
diff --git a/src/main/java/com/classes/dtos/ClassDTO.java b/src/main/java/com/classes/dtos/Class/ClassRequest.java
similarity index 73%
rename from src/main/java/com/classes/dtos/ClassDTO.java
rename to src/main/java/com/classes/dtos/Class/ClassRequest.java
index bfa1099..e972438 100644
--- a/src/main/java/com/classes/dtos/ClassDTO.java
+++ b/src/main/java/com/classes/dtos/Class/ClassRequest.java
@@ -1,23 +1,26 @@
-package com.classes.dtos;
+package com.classes.dtos.Class;
import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.UUID;
@Data
-public class ClassDTO {
- private UUID id;
+@AllArgsConstructor
+@NoArgsConstructor
+public class ClassRequest {
private String className;
private UUID locationId;
+ private UUID trainerId;
@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;
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/classes/dtos/Class/ClassResponse.java b/src/main/java/com/classes/dtos/Class/ClassResponse.java
new file mode 100644
index 0000000..7a9ecfc
--- /dev/null
+++ b/src/main/java/com/classes/dtos/Class/ClassResponse.java
@@ -0,0 +1,28 @@
+package com.classes.dtos.Class;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.util.UUID;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ClassResponse {
+ private UUID id;
+ private String className;
+ private String locationName;
+ private String trainerName;
+ @JsonFormat(pattern = "dd-MM-yyyy")
+ private LocalDate classDate;
+ private int duration;
+ private int maxCapacity;
+ private LocalTime startTime;
+ private boolean active;
+ private String description;
+}
\ No newline at end of file
diff --git a/src/main/java/com/classes/dtos/LocationDTO.java b/src/main/java/com/classes/dtos/Location/LocationRequest.java
similarity index 67%
rename from src/main/java/com/classes/dtos/LocationDTO.java
rename to src/main/java/com/classes/dtos/Location/LocationRequest.java
index f3a1d08..f065e52 100644
--- a/src/main/java/com/classes/dtos/LocationDTO.java
+++ b/src/main/java/com/classes/dtos/Location/LocationRequest.java
@@ -1,10 +1,9 @@
-package com.classes.dtos;
-
+package com.classes.dtos.Location;
import lombok.Data;
@Data
-public class LocationDTO {
+public class LocationRequest {
private String name;
private String description;
private int ability;
diff --git a/src/main/java/com/classes/dtos/Location/LocationResponse.java b/src/main/java/com/classes/dtos/Location/LocationResponse.java
new file mode 100644
index 0000000..6ad0dba
--- /dev/null
+++ b/src/main/java/com/classes/dtos/Location/LocationResponse.java
@@ -0,0 +1,14 @@
+package com.classes.dtos.Location;
+
+import lombok.Data;
+
+import java.util.UUID;
+
+@Data
+public class LocationResponse {
+ private UUID id; // si tienes un ID generado
+ private String name;
+ private String description;
+ private int ability;
+ private boolean active;
+}
\ No newline at end of file
diff --git a/src/main/java/com/classes/dtos/FileResponseDTO.java b/src/main/java/com/classes/dtos/Trainer/FileResponseDTO.java
similarity index 90%
rename from src/main/java/com/classes/dtos/FileResponseDTO.java
rename to src/main/java/com/classes/dtos/Trainer/FileResponseDTO.java
index c4c2e4b..ed64c33 100644
--- a/src/main/java/com/classes/dtos/FileResponseDTO.java
+++ b/src/main/java/com/classes/dtos/Trainer/FileResponseDTO.java
@@ -1,4 +1,4 @@
-package com.classes.dtos;
+package com.classes.dtos.Trainer;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/src/main/java/com/classes/dtos/TrainerDTO.java b/src/main/java/com/classes/dtos/Trainer/TrainerDTO.java
similarity index 96%
rename from src/main/java/com/classes/dtos/TrainerDTO.java
rename to src/main/java/com/classes/dtos/Trainer/TrainerDTO.java
index 2a7743e..ec47f27 100644
--- a/src/main/java/com/classes/dtos/TrainerDTO.java
+++ b/src/main/java/com/classes/dtos/Trainer/TrainerDTO.java
@@ -1,4 +1,4 @@
-package com.classes.dtos;
+package com.classes.dtos.Trainer;
import com.classes.enums.ContractType;
import com.classes.enums.DayAvailability;
diff --git a/src/main/java/com/classes/entities/ClassEntity.java b/src/main/java/com/classes/entities/ClassEntity.java
index aca092b..46d5298 100644
--- a/src/main/java/com/classes/entities/ClassEntity.java
+++ b/src/main/java/com/classes/entities/ClassEntity.java
@@ -21,18 +21,23 @@ public class ClassEntity {
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
private String name;
-// private UUID LocationId;
+
private String className;
private int duration;
- private UUID trainerId;
+
private int maxCapacity;
private LocalTime startTime;
private boolean active;
private String description;
+
@ManyToOne
@JoinColumn(name = "location_id")
private LocationEntity location;
+ @ManyToOne
+ @JoinColumn(name = "trainer_id")
+ private TrainerEntity trainer;
+
@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 c3f6222..acbdb9b 100644
--- a/src/main/java/com/classes/entities/TrainerEntity.java
+++ b/src/main/java/com/classes/entities/TrainerEntity.java
@@ -65,6 +65,7 @@ public class TrainerEntity {
private BigDecimal salaryPerClass;
private String bankInfo;
private String notes;
+
@Embedded
private Audit audit;
diff --git a/src/main/java/com/classes/mappers/ClassMapper.java b/src/main/java/com/classes/mappers/ClassMapper.java
index a477bd5..3507ebf 100644
--- a/src/main/java/com/classes/mappers/ClassMapper.java
+++ b/src/main/java/com/classes/mappers/ClassMapper.java
@@ -1,24 +1,33 @@
package com.classes.mappers;
import com.classes.config.MapStructConfig;
-import com.classes.dtos.ClassDTO;
-import com.classes.dtos.LocationDTO;
+import com.classes.dtos.Class.ClassRequest;
+
+import com.classes.dtos.Class.ClassResponse;
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 org.mapstruct.*;
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);
+ // Crear entidad desde el request
+
+ @Mapping(target = "id", ignore = true)
+ @Mapping(target = "location", ignore = true) // se setean en el servicio
+ @Mapping(target = "trainer", ignore = true)
+ ClassEntity toEntity(ClassRequest request);
+ @Mapping(target = "locationName", source = "location.name")
+ @Mapping(target = "trainerName", source = "trainer.firstName")
+ ClassResponse toResponse(ClassEntity entity);
+
+ // Lista de respuestas
+ List toResponseList(List entities);
+
+ // Actualizar entidad desde el request (solo los campos no nulos)
+ @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
+ void updateFromRequest(ClassRequest request, @MappingTarget ClassEntity entity);
}
diff --git a/src/main/java/com/classes/mappers/LocationMapper.java b/src/main/java/com/classes/mappers/LocationMapper.java
index 4a6da5c..37cf259 100644
--- a/src/main/java/com/classes/mappers/LocationMapper.java
+++ b/src/main/java/com/classes/mappers/LocationMapper.java
@@ -1,7 +1,8 @@
package com.classes.mappers;
-import com.classes.dtos.LocationDTO;
+import com.classes.dtos.Location.LocationRequest;
+import com.classes.dtos.Location.LocationResponse;
import com.classes.config.MapStructConfig;
import com.classes.entities.LocationEntity;
import org.mapstruct.BeanMapping;
@@ -12,11 +13,14 @@
@Mapper(config = MapStructConfig.class)
public interface LocationMapper {
- LocationDTO toDto(LocationEntity locationEntity);
- LocationEntity toEntity(LocationDTO locationDTO);
+ LocationResponse toResponse(LocationEntity locationEntity);
+ // Request → Entity
+ LocationEntity toEntity(LocationRequest locationRequest);
+
+ // Actualización parcial: Request → Entity
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
- void updateFromDto(LocationDTO dto, @MappingTarget LocationEntity entity);
+ void updateFromRequest(LocationRequest request, @MappingTarget LocationEntity entity);
}
diff --git a/src/main/java/com/classes/mappers/TrainerMapper.java b/src/main/java/com/classes/mappers/TrainerMapper.java
index 1bf7d53..666f32f 100644
--- a/src/main/java/com/classes/mappers/TrainerMapper.java
+++ b/src/main/java/com/classes/mappers/TrainerMapper.java
@@ -1,7 +1,7 @@
package com.classes.mappers;
import com.classes.config.MapStructConfig;
-import com.classes.dtos.TrainerDTO;
+import com.classes.dtos.Trainer.TrainerDTO;
import com.classes.entities.TrainerEntity;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
diff --git a/src/main/java/com/classes/repositories/LocationRepository.java b/src/main/java/com/classes/repositories/LocationRepository.java
index aa10536..7bb3b09 100644
--- a/src/main/java/com/classes/repositories/LocationRepository.java
+++ b/src/main/java/com/classes/repositories/LocationRepository.java
@@ -3,11 +3,23 @@
import com.classes.entities.LocationEntity;
-import java.util.UUID;
-
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
+import java.util.UUID;
+
+
@Repository
public interface LocationRepository extends JpaRepository {
+ Page findByNameContainingIgnoreCase(String name, Pageable pageable);
+
+ // 2️⃣ Solo activos
+ Page findByActiveTrue(Pageable pageable);
+
+ // 3️⃣ Solo inactivos
+ Page findByActiveFalse(Pageable pageable);
+ Page findByNameContainingIgnoreCaseAndActive(String name, boolean active, Pageable pageable);
+
}
diff --git a/src/main/java/com/classes/repositories/TrainerRepository.java b/src/main/java/com/classes/repositories/TrainerRepository.java
index 5a0cdc2..9af8498 100644
--- a/src/main/java/com/classes/repositories/TrainerRepository.java
+++ b/src/main/java/com/classes/repositories/TrainerRepository.java
@@ -4,9 +4,13 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
+import java.util.Optional;
import java.util.UUID;
@Repository
public interface TrainerRepository extends JpaRepository {
+
+
+
}
diff --git a/src/main/java/com/classes/services/AuthorizationService.java b/src/main/java/com/classes/services/AuthorizationService.java
new file mode 100644
index 0000000..d62f206
--- /dev/null
+++ b/src/main/java/com/classes/services/AuthorizationService.java
@@ -0,0 +1,15 @@
+package com.classes.services;
+
+import org.springframework.security.core.Authentication;
+
+import java.util.UUID;
+
+public interface AuthorizationService {
+ boolean hasRole(Authentication authentication, String role);
+
+ UUID getUserId(Authentication authentication);
+
+ boolean canAccessResource(UUID ownerId, Authentication authentication);
+
+ boolean canAccessWithRoleOrOwner(UUID ownerId, Authentication authentication, String role);
+}
diff --git a/src/main/java/com/classes/services/AzureService.java b/src/main/java/com/classes/services/AzureService.java
index 3a3c6f3..0362893 100644
--- a/src/main/java/com/classes/services/AzureService.java
+++ b/src/main/java/com/classes/services/AzureService.java
@@ -1,6 +1,6 @@
package com.classes.services;
-import com.classes.dtos.FileResponseDTO;
+import com.classes.dtos.Trainer.FileResponseDTO;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
diff --git a/src/main/java/com/classes/services/ClassService.java b/src/main/java/com/classes/services/ClassService.java
index 89cd363..4d6f370 100644
--- a/src/main/java/com/classes/services/ClassService.java
+++ b/src/main/java/com/classes/services/ClassService.java
@@ -1,14 +1,19 @@
package com.classes.services;
-import com.classes.dtos.ClassDTO;
+import com.classes.dtos.Class.ClassRequest;
+import com.classes.dtos.Class.ClassResponse;
import java.util.List;
import java.util.UUID;
public interface ClassService {
- ClassDTO createClass(ClassDTO dto);
- List findAll();
- ClassDTO updateClass(UUID id, ClassDTO dto);
+
+ ClassResponse createClass(ClassRequest request);
+
+ List findAll();
+
+ ClassResponse updateClass(UUID id, ClassRequest request);
+
void deleteClass(UUID id);
}
diff --git a/src/main/java/com/classes/services/CloudinaryService.java b/src/main/java/com/classes/services/CloudinaryService.java
index 8f12c0e..5bc238a 100644
--- a/src/main/java/com/classes/services/CloudinaryService.java
+++ b/src/main/java/com/classes/services/CloudinaryService.java
@@ -1,6 +1,6 @@
package com.classes.services;
-import com.classes.dtos.FileResponseDTO;
+import com.classes.dtos.Trainer.FileResponseDTO;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
diff --git a/src/main/java/com/classes/services/Impl/AuthServiceImpl.java b/src/main/java/com/classes/services/Impl/AuthorizationServiceImpl.java
similarity index 84%
rename from src/main/java/com/classes/services/Impl/AuthServiceImpl.java
rename to src/main/java/com/classes/services/Impl/AuthorizationServiceImpl.java
index ebbecb7..00356fb 100644
--- a/src/main/java/com/classes/services/Impl/AuthServiceImpl.java
+++ b/src/main/java/com/classes/services/Impl/AuthorizationServiceImpl.java
@@ -1,5 +1,7 @@
package com.classes.services.Impl;
+import com.classes.services.AuthorizationService;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Service;
@@ -7,23 +9,27 @@
import java.util.UUID;
@Service
-public class AuthServiceImpl {
-
+@Slf4j
+public class AuthorizationServiceImpl implements AuthorizationService {
+ @Override
public boolean hasRole(Authentication authentication, String role) {
return authentication.getAuthorities().stream()
.anyMatch(a -> a.getAuthority().equals(role));
}
+ @Override
public UUID getUserId(Authentication authentication) {
String userIdStr = ((JwtAuthenticationToken) authentication).getToken().getClaim("user_id");
return UUID.fromString(userIdStr);
}
+ @Override
// 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));
}
+ @Override
// 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/AzureServiceImpl.java b/src/main/java/com/classes/services/Impl/AzureServiceImpl.java
index 9e3a8d6..7cf4514 100644
--- a/src/main/java/com/classes/services/Impl/AzureServiceImpl.java
+++ b/src/main/java/com/classes/services/Impl/AzureServiceImpl.java
@@ -5,7 +5,7 @@
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.common.StorageSharedKeyCredential;
-import com.classes.dtos.FileResponseDTO;
+import com.classes.dtos.Trainer.FileResponseDTO;
import com.classes.services.AzureService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
diff --git a/src/main/java/com/classes/services/Impl/ClassServiceImpl.java b/src/main/java/com/classes/services/Impl/ClassServiceImpl.java
index 621a14e..5274d7a 100644
--- a/src/main/java/com/classes/services/Impl/ClassServiceImpl.java
+++ b/src/main/java/com/classes/services/Impl/ClassServiceImpl.java
@@ -1,13 +1,15 @@
package com.classes.services.Impl;
-import com.classes.dtos.ClassDTO;
+import com.classes.dtos.Class.ClassRequest;
+import com.classes.dtos.Class.ClassResponse;
import com.classes.entities.ClassEntity;
+import com.classes.entities.LocationEntity;
+import com.classes.entities.TrainerEntity;
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;
@@ -28,43 +30,65 @@ public class ClassServiceImpl implements ClassService {
@Transactional
@Override
- public ClassDTO createClass(ClassDTO dto) {
- validateTrainerAndLocation(dto);
- ClassEntity entity = classMapper.toEntity(dto);
+ public ClassResponse createClass(ClassRequest request) {
+ validateTrainerAndLocation(request);
+ ClassEntity entity = classMapper.toEntity(request);
+ TrainerEntity trainer = trainerRepository.findById(request.getTrainerId())
+ .orElseThrow(() -> new IllegalArgumentException("El trainer con ID " + request.getTrainerId() + " no existe"));
+ LocationEntity location = locationRepository.findById(request.getLocationId())
+ .orElseThrow(() -> new IllegalArgumentException("La ubicación con ID " + request.getLocationId() + " no existe"));
+ entity.setTrainer(trainer);
+ entity.setLocation(location);
ClassEntity saved = repository.save(entity);
- return classMapper.toDTO(saved);
+ return classMapper.toResponse(saved);
}
- @Transactional(readOnly = true)
+ @Transactional
@Override
- public List findAll() {
- List entities = repository.findAll();
- return classMapper.toDTOList(entities);
+ public List findAll() {
+ return classMapper.toResponseList(repository.findAll());
}
@Transactional
@Override
- public ClassDTO updateClass(UUID id, ClassDTO dto) {
+ public ClassResponse updateClass(UUID id, ClassRequest request) {
+
ClassEntity existing = repository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("La clase con ID " + id + " no existe"));
- validateTrainerAndLocation(dto);
- classMapper.updateFromDto(dto, existing);
+
+
+ if (request.getTrainerId() != null) {
+ TrainerEntity trainer = trainerRepository.findById(request.getTrainerId())
+ .orElseThrow(() -> new IllegalArgumentException("El trainer con ID " + request.getTrainerId() + " no existe"));
+ existing.setTrainer(trainer);
+ }
+
+
+ if (request.getLocationId() != null) {
+ LocationEntity location = locationRepository.findById(request.getLocationId())
+ .orElseThrow(() -> new IllegalArgumentException("La ubicación con ID " + request.getLocationId() + " no existe"));
+ existing.setLocation(location);
+ }
+ classMapper.updateFromRequest(request, existing);
ClassEntity updated = repository.save(existing);
- return classMapper.toDTO(updated);
+ return classMapper.toResponse(updated);
}
@Transactional
@Override
public void deleteClass(UUID id) {
-
+ if (!repository.existsById(id)) {
+ throw new IllegalArgumentException("La clase con ID " + id + " no existe");
+ }
+ repository.deleteById(id);
}
- private void validateTrainerAndLocation(ClassDTO dto) {
- if (!trainerRepository.existsById(dto.getTrainerId())) {
- throw new IllegalArgumentException("El trainer con ID " + dto.getTrainerId() + " no existe");
+ private void validateTrainerAndLocation(ClassRequest request) {
+ if (!trainerRepository.existsById(request.getTrainerId())) {
+ throw new IllegalArgumentException("El trainer con ID " + request.getTrainerId() + " no existe");
}
- if (!locationRepository.existsById(dto.getLocationId())) {
- throw new IllegalArgumentException("La ubicación con ID " + dto.getLocationId() + " no existe");
+ if (!locationRepository.existsById(request.getLocationId())) {
+ throw new IllegalArgumentException("La ubicación con ID " + request.getLocationId() + " no existe");
}
}
}
diff --git a/src/main/java/com/classes/services/Impl/CloudinaryServiceImpl.java b/src/main/java/com/classes/services/Impl/CloudinaryServiceImpl.java
index 550857c..c1f2c05 100644
--- a/src/main/java/com/classes/services/Impl/CloudinaryServiceImpl.java
+++ b/src/main/java/com/classes/services/Impl/CloudinaryServiceImpl.java
@@ -1,6 +1,6 @@
package com.classes.services.Impl;
-import com.classes.dtos.FileResponseDTO;
+import com.classes.dtos.Trainer.FileResponseDTO;
import com.classes.services.CloudinaryService;
import com.cloudinary.Cloudinary;
import com.cloudinary.utils.ObjectUtils;
diff --git a/src/main/java/com/classes/services/Impl/LocationServiceImpl.java b/src/main/java/com/classes/services/Impl/LocationServiceImpl.java
index f7d8bde..d7f8034 100644
--- a/src/main/java/com/classes/services/Impl/LocationServiceImpl.java
+++ b/src/main/java/com/classes/services/Impl/LocationServiceImpl.java
@@ -1,21 +1,18 @@
package com.classes.services.Impl;
-import com.classes.dtos.LocationDTO;
+import com.classes.dtos.Location.LocationRequest;
+import com.classes.dtos.Location.LocationResponse;
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;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.List;
import java.util.UUID;
@Service
@@ -28,30 +25,24 @@ public class LocationServiceImpl implements LocationService {
@Override
@Transactional
- public LocationDTO create(LocationDTO dto) {
- LocationEntity locationEntity = mapper.toEntity(dto);
- return mapper.toDto(repository.save(locationEntity));
+ public LocationResponse create(LocationRequest request) {
+ LocationEntity entity = mapper.toEntity(request);
+ LocationEntity saved = repository.save(entity);
+ return mapper.toResponse(saved);
}
@Override
@Transactional
- public LocationDTO update(UUID id, LocationDTO dto) {
- LocationEntity locationEntity = findById(id);
- mapper.updateFromDto(dto, locationEntity);
- LocationEntity updated = repository.save(locationEntity);
- return mapper.toDto(updated);
- }
-
-
- @Override
- @Transactional(readOnly = true)
- public LocationEntity findById(UUID id) {
- return repository.findById(id)
+ public LocationResponse update(UUID id, LocationRequest request) {
+ LocationEntity entity = repository.findById(id)
.orElseThrow(() -> new RuntimeException("Location not found"));
+ mapper.updateFromRequest(request, entity);
+ LocationEntity updated = repository.save(entity);
+ return mapper.toResponse(updated);
}
- @Transactional
@Override
+ @Transactional
public void delete(UUID id) {
boolean hasClasses = classRepository.findFirstByLocationId(id).isPresent();
if (hasClasses) {
@@ -62,12 +53,30 @@ public void delete(UUID id) {
repository.deleteById(id);
}
-
- @Transactional(readOnly = true)
- public Page findAll(int page, int size) {
- Pageable pageable = PageRequest.of(page, size, Sort.by("name").ascending());
- Page pageEntity = repository.findAll(pageable);
- return pageEntity.map(mapper::toDto);
+ @Override
+ public LocationResponse findById(UUID id) {
+ LocationEntity entity = repository.findById(id)
+ .orElseThrow(() -> new RuntimeException("Location not found"));
+ return mapper.toResponse(entity);
}
+ @Override
+ public Page findAll(int page, int size, String search, Boolean active) {
+ PageRequest pageable = PageRequest.of(page, size);
+ Page pageResult;
+
+ if (search != null && !search.isEmpty() && active != null) {
+ pageResult = repository.findByNameContainingIgnoreCaseAndActive(search, active, pageable);
+ } else if (search != null && !search.isEmpty()) {
+ pageResult = repository.findByNameContainingIgnoreCase(search, pageable);
+ } else if (active != null) {
+ pageResult = active ? repository.findByActiveTrue(pageable)
+ : repository.findByActiveFalse(pageable);
+ } else {
+ pageResult = repository.findAll(pageable);
+ }
+
+ return pageResult.map(mapper::toResponse);
+ }
}
+
diff --git a/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java b/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java
index fddeff6..973edba 100644
--- a/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java
+++ b/src/main/java/com/classes/services/Impl/TrainerServiceImpl.java
@@ -1,7 +1,7 @@
package com.classes.services.Impl;
-import com.classes.dtos.FileResponseDTO;
-import com.classes.dtos.TrainerDTO;
+import com.classes.dtos.Trainer.FileResponseDTO;
+import com.classes.dtos.Trainer.TrainerDTO;
import com.classes.entities.TrainerEntity;
import com.classes.mappers.TrainerMapper;
import com.classes.repositories.ClassRepository;
diff --git a/src/main/java/com/classes/services/LocationService.java b/src/main/java/com/classes/services/LocationService.java
index 09921b9..5dad83b 100644
--- a/src/main/java/com/classes/services/LocationService.java
+++ b/src/main/java/com/classes/services/LocationService.java
@@ -1,17 +1,21 @@
package com.classes.services;
-import com.classes.dtos.LocationDTO;
-import com.classes.entities.LocationEntity;
+import com.classes.dtos.Location.LocationRequest;
+import com.classes.dtos.Location.LocationResponse;
import org.springframework.data.domain.Page;
-import java.util.List;
import java.util.UUID;
public interface LocationService {
- LocationDTO create(LocationDTO dto);
- LocationDTO update(UUID id, LocationDTO dto);
+ LocationResponse create(LocationRequest request);
+
+ LocationResponse update(UUID id, LocationRequest request);
+
void delete(UUID id);
- LocationEntity findById(UUID id);
- Page findAll(int page, int size);
-}
+
+ LocationResponse findById(UUID id);
+
+ // Paginación + filtros
+ Page findAll(int page, int size, String search, Boolean active);
+}
\ No newline at end of file
diff --git a/src/main/java/com/classes/services/TrainerService.java b/src/main/java/com/classes/services/TrainerService.java
index 1b93963..f2b6a44 100644
--- a/src/main/java/com/classes/services/TrainerService.java
+++ b/src/main/java/com/classes/services/TrainerService.java
@@ -1,6 +1,6 @@
package com.classes.services;
-import com.classes.dtos.TrainerDTO;
+import com.classes.dtos.Trainer.TrainerDTO;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@@ -22,5 +22,9 @@ TrainerDTO updateTrainer(UUID id,
List certifications) throws IOException;
void deleteTrainer(UUID id) throws IOException;
+
+
+
+
}
diff --git a/src/main/resources/bootstrap.yml b/src/main/resources/bootstrap.yml
index 26449e8..3381ebb 100644
--- a/src/main/resources/bootstrap.yml
+++ b/src/main/resources/bootstrap.yml
@@ -6,4 +6,7 @@ spring:
cloud:
config:
uri: ${SPRING_CLOUD_CONFIG_URI:http://config-server:7777}
-
\ No newline at end of file
+ servlet:
+ multipart:
+ max-file-size: 10MB
+ max-request-size: 20MB
\ No newline at end of file