diff --git a/TODO b/TODO index 12c72d3..4541a49 100644 --- a/TODO +++ b/TODO @@ -1,14 +1,13 @@ POR HACER -------------------------------- +- sistema comun de errores en back & front +- cambiar contraseña (?) +- documentación +- implementar urlParams para filtros +- mail wrapper + +RESUELTO --------------------------------- - añadir colaborador desde perfil - apuntarse lista espera - aceptar solicitudes LE/Colab (sobre todo por crear preusers) -- mail wrapper -- documentación -- cambiar contraseña (?) -- implementar urlParams para filtros -- sistema comun de errores en back & front - - -RESUELTO --------------------------------- - mejorar queries para no filtrar en memoria -> IMPOSIBLE CON ENDPOINTS INTERNOS DE CORE: RESUELTO CON CACHING - normalizar el uso de services y repositories desde otros services y repositories \ No newline at end of file diff --git a/core/src/main/java/net/miarma/backend/core/controller/CredentialController.java b/core/src/main/java/net/miarma/backend/core/controller/CredentialController.java index 209b747..1e9a692 100644 --- a/core/src/main/java/net/miarma/backend/core/controller/CredentialController.java +++ b/core/src/main/java/net/miarma/backend/core/controller/CredentialController.java @@ -70,17 +70,18 @@ public class CredentialController { return ResponseEntity.noContent().build(); } - @GetMapping("/{credential_id}/status") - public ResponseEntity getStatus(@PathVariable("credential_id") UUID credentialId) { - return ResponseEntity.ok(credentialService.getStatus(credentialId)); + @GetMapping("/{service_id}/{user_id}/status") + public ResponseEntity getStatus(@PathVariable("user_id") UUID userId, @PathVariable("service_id") Byte serviceId) { + return ResponseEntity.ok(credentialService.getStatus(userId, serviceId)); } - @PutMapping("/{credential_id}/status") + @PutMapping("/{service_id}/{user_id}/status") public ResponseEntity updateStatus( - @PathVariable("credential_id") UUID credentialId, + @PathVariable("user_id") UUID userId, + @PathVariable("service_id") Byte serviceId, @RequestBody ChangeStatusRequest req ) { - credentialService.updateStatus(credentialId, req.status()); + credentialService.updateStatus(userId, serviceId, req.status()); return ResponseEntity.noContent().build(); } } diff --git a/core/src/main/java/net/miarma/backend/core/service/CredentialService.java b/core/src/main/java/net/miarma/backend/core/service/CredentialService.java index d0a262c..a75e121 100644 --- a/core/src/main/java/net/miarma/backend/core/service/CredentialService.java +++ b/core/src/main/java/net/miarma/backend/core/service/CredentialService.java @@ -23,10 +23,12 @@ import net.miarma.backlib.util.UuidUtil; public class CredentialService { private final CredentialRepository credentialRepository; + private final UserService userService; private final PasswordEncoder passwordEncoder; - public CredentialService(CredentialRepository credentialRepository, PasswordEncoder passwordEncoder) { + public CredentialService(CredentialRepository credentialRepository, UserService userService, PasswordEncoder passwordEncoder) { this.credentialRepository = credentialRepository; + this.userService = userService; this.passwordEncoder = passwordEncoder; } @@ -155,15 +157,13 @@ public class CredentialService { credentialRepository.deleteById(idBytes); } - public Byte getStatus(UUID credentialId) { - Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId)) - .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));; + public Byte getStatus(UUID userId, Byte serviceId) { + Credential credential = getByUserIdAndService(userId, serviceId); return credential.getStatus(); } - public void updateStatus(UUID credentialId, Byte status) { - Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId)) - .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));; + public void updateStatus(UUID userId, Byte serviceId, Byte status) { + Credential credential = getByUserIdAndService(userId, serviceId); credential.setStatus(status); credentialRepository.save(credential); } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/client/HuertosWebClient.java b/huertos/src/main/java/net/miarma/backend/huertos/client/HuertosWebClient.java index 50d7023..dae7ed5 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/client/HuertosWebClient.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/client/HuertosWebClient.java @@ -83,4 +83,21 @@ public class HuertosWebClient { restTemplate.delete(coreUrl + "/users/{user_id}", userId); } catch (Exception e) { } } + + public Byte getCredentialStatus(UUID userId, Byte serviceId) { + return restTemplate.getForObject( + coreUrl + "/credentials/{service_id}/{user_id}/status", + Byte.class, + serviceId, userId + ); + } + + public void updateCredentialStatus(UUID userId, Byte serviceId, Byte newStatus) { + ChangeStatusRequest req = new ChangeStatusRequest(newStatus); + restTemplate.put( + coreUrl + "/credentials/{service_id}/{user_id}/status", + req, + serviceId, userId + ); + } } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/config/SecurityConfig.java b/huertos/src/main/java/net/miarma/backend/huertos/config/SecurityConfig.java index 1dbc13e..67349ea 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/config/SecurityConfig.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/config/SecurityConfig.java @@ -65,9 +65,7 @@ public class SecurityConfig { .requestMatchers("/auth/login").permitAll() .requestMatchers("/users/waitlist/limited").permitAll() .requestMatchers("/requests").permitAll() - .requestMatchers("/pre-users").permitAll() .requestMatchers("/users/latest-number").permitAll() - .requestMatchers("/pre-users/validate").permitAll() // PRIVADAS .anyRequest().authenticated() ); diff --git a/huertos/src/main/java/net/miarma/backend/huertos/controller/RequestController.java b/huertos/src/main/java/net/miarma/backend/huertos/controller/RequestController.java index 49190c4..a438f44 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/controller/RequestController.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/controller/RequestController.java @@ -2,6 +2,7 @@ package net.miarma.backend.huertos.controller; import net.miarma.backend.huertos.dto.*; import net.miarma.backend.huertos.mapper.RequestMapper; +import net.miarma.backend.huertos.mapper.RequestMetadataMapper; import net.miarma.backend.huertos.mapper.RequestWithMetadataMapper; import net.miarma.backend.huertos.model.Request; import net.miarma.backend.huertos.service.RequestAcceptanceService; @@ -131,6 +132,7 @@ public class RequestController { @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") public ResponseEntity> acceptRequest(@PathVariable("request_id") UUID requestId) { Request r = requestAcceptanceService.acceptRequest(requestId); + requestAcceptanceService.handleSideEffects(r); return ResponseEntity.ok(Map.of("message", "Accepted request: " + r.getRequestId())); } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestDto.java b/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestDto.java index 2c2302d..2e4f71d 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestDto.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestDto.java @@ -9,6 +9,7 @@ public class RequestDto { public static class Request { private Byte type; private UUID userId; + private String name; private RequestMetadataDto metadata; public Byte getType() { @@ -27,6 +28,14 @@ public class RequestDto { this.userId = userId; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public RequestMetadataDto getMetadata() { return metadata; } @@ -41,6 +50,7 @@ public class RequestDto { private Byte type; private Byte status; private UUID userId; + private String name; private RequestMetadataDto metadata; private Instant createdAt; @@ -76,6 +86,14 @@ public class RequestDto { this.userId = userId; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + public RequestMetadataDto getMetadata() { return metadata; } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestWithMetadataDto.java b/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestWithMetadataDto.java index 5af10bf..6a452e5 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestWithMetadataDto.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/dto/RequestWithMetadataDto.java @@ -6,6 +6,7 @@ import java.util.UUID; public record RequestWithMetadataDto( UUID requestId, UUID userId, + String name, Byte type, Byte status, Instant createdAt, diff --git a/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestMapper.java b/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestMapper.java index a796cdb..b44634b 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestMapper.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestMapper.java @@ -34,7 +34,7 @@ public class RequestMapper { if (dto.getMetadata() != null) { entity.setMetadata( - RequestMetadataMapper.fromDto(dto.getMetadata()) + RequestMetadataMapper.fromDto(dto.getMetadata()) ); } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestWithMetadataMapper.java b/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestWithMetadataMapper.java index ed52727..ab35d78 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestWithMetadataMapper.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/mapper/RequestWithMetadataMapper.java @@ -9,6 +9,7 @@ public class RequestWithMetadataMapper { return new RequestWithMetadataDto( r.getRequestId(), r.getUserId(), + r.getName(), r.getType(), r.getStatus(), r.getCreatedAt(), diff --git a/huertos/src/main/java/net/miarma/backend/huertos/model/Request.java b/huertos/src/main/java/net/miarma/backend/huertos/model/Request.java index 60b043f..9bc5dcb 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/model/Request.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/model/Request.java @@ -2,7 +2,6 @@ package net.miarma.backend.huertos.model; import java.time.Instant; import java.util.UUID; - import jakarta.persistence.*; import net.miarma.backlib.util.UuidUtil; @@ -18,103 +17,60 @@ public class Request { private UUID requestId; @Column(name = "user_id", columnDefinition = "BINARY(16)") - private byte[] userIdBin; // usuario que hace la solicitud (puede ser null si anon) + private byte[] userIdBin; @Transient private UUID userId; - @Column(name = "type", nullable = false) + private String name; + + @Column(nullable = false) private Byte type; - @Column(name = "status", nullable = false) + @Column(nullable = false) private Byte status; @Column(name = "created_at", nullable = false) private Instant createdAt; - @OneToOne(cascade = CascadeType.ALL) - @JoinColumn(name = "metadata_id") + @OneToOne(mappedBy = "request", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = true) private RequestMetadata metadata; @PrePersist private void prePersist() { - if (requestId != null) { - requestIdBin = net.miarma.backlib.util.UuidUtil.uuidToBin(requestId); - } - createdAt = Instant.now(); + if (requestId != null) requestIdBin = UuidUtil.uuidToBin(requestId); + if (userId != null) userIdBin = UuidUtil.uuidToBin(userId); } @PostLoad private void postLoad() { - if (requestIdBin != null) { - requestId = net.miarma.backlib.util.UuidUtil.binToUUID(requestIdBin); - } - if (userIdBin != null) { - userId = net.miarma.backlib.util.UuidUtil.binToUUID(userIdBin); - } + if (requestIdBin != null) requestId = UuidUtil.binToUUID(requestIdBin); + if (userIdBin != null) userId = UuidUtil.binToUUID(userIdBin); } - public byte[] getRequestIdBin() { - return requestIdBin; + public UUID getRequestId() { return requestId; } + public void setRequestId(UUID requestId) { this.requestId = requestId; } + + public UUID getUserId() { return userId; } + public void setUserId(UUID userId) { this.userId = userId; } + + public String getName() { + return name; } - public void setRequestIdBin(byte[] requestIdBin) { - this.requestIdBin = requestIdBin; + public void setName(String name) { + this.name = name; } - public UUID getRequestId() { - return requestId; - } + public Byte getType() { return type; } + public void setType(Byte type) { this.type = type; } - public void setRequestId(UUID requestId) { - this.requestId = requestId; - } + public Byte getStatus() { return status; } + public void setStatus(Byte status) { this.status = status; } - public byte[] getUserIdBin() { - return userIdBin; - } + public Instant getCreatedAt() { return createdAt; } + public void setCreatedAt(Instant createdAt) { this.createdAt = createdAt; } - public void setUserIdBin(byte[] userIdBin) { - this.userIdBin = userIdBin; - } - - public UUID getUserId() { - return userId; - } - - public void setUserId(UUID userId) { - this.userId = userId; - } - - public Byte getType() { - return type; - } - - public void setType(Byte type) { - this.type = type; - } - - public Byte getStatus() { - return status; - } - - public void setStatus(Byte status) { - this.status = status; - } - - public Instant getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Instant createdAt) { - this.createdAt = createdAt; - } - - public RequestMetadata getMetadata() { - return metadata; - } - - public void setMetadata(RequestMetadata metadata) { - this.metadata = metadata; - } + public RequestMetadata getMetadata() { return metadata; } + public void setMetadata(RequestMetadata metadata) { this.metadata = metadata; } } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/model/RequestMetadata.java b/huertos/src/main/java/net/miarma/backend/huertos/model/RequestMetadata.java index 6ca182f..e3c2d1b 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/model/RequestMetadata.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/model/RequestMetadata.java @@ -1,8 +1,10 @@ package net.miarma.backend.huertos.model; import jakarta.persistence.*; +import net.miarma.backlib.util.UuidUtil; import java.time.Instant; +import java.util.UUID; @Entity @Table(name = "huertos_request_metadata") @@ -12,6 +14,16 @@ public class RequestMetadata { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(name = "request_id", columnDefinition = "BINARY(16)", nullable = false, unique = true) + private byte[] requestIdBin; + + @Transient + private UUID requestId; + + @OneToOne + @JoinColumn(name = "request_id", referencedColumnName = "request_id", insertable = false, updatable = false) + private Request request; + @Column(name = "display_name", nullable = false, length = 150) private String displayName; @@ -39,17 +51,22 @@ public class RequestMetadata { @Column(name = "plot_number") private Integer plotNumber; - private Byte type; - @Column(nullable = false, length = 100) private String username; + private Byte type; + @Column(name = "created_at", nullable = false, updatable = false) private Instant createdAt; @PrePersist private void prePersist() { - createdAt = Instant.now(); + if (requestId != null) requestIdBin = UuidUtil.uuidToBin(requestId); + } + + @PostLoad + private void postLoad() { + if (requestIdBin != null) requestId = UuidUtil.binToUUID(requestIdBin); } public Long getId() { @@ -60,6 +77,30 @@ public class RequestMetadata { this.id = id; } + public byte[] getRequestIdBin() { + return requestIdBin; + } + + public void setRequestIdBin(byte[] requestIdBin) { + this.requestIdBin = requestIdBin; + } + + public UUID getRequestId() { + return requestId; + } + + public void setRequestId(UUID requestId) { + this.requestId = requestId; + } + + public Request getRequest() { + return request; + } + + public void setRequest(Request request) { + this.request = request; + } + public String getDisplayName() { return displayName; } @@ -140,14 +181,6 @@ public class RequestMetadata { this.type = type; } - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - public Instant getCreatedAt() { return createdAt; } @@ -155,5 +188,12 @@ public class RequestMetadata { public void setCreatedAt(Instant createdAt) { this.createdAt = createdAt; } -} + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/huertos/src/main/java/net/miarma/backend/huertos/repository/RequestRepository.java b/huertos/src/main/java/net/miarma/backend/huertos/repository/RequestRepository.java index 85d6178..bde9669 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/repository/RequestRepository.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/repository/RequestRepository.java @@ -2,6 +2,17 @@ package net.miarma.backend.huertos.repository; import net.miarma.backend.huertos.model.Request; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.Optional; public interface RequestRepository extends JpaRepository { + @Query(""" + SELECT r FROM Request r + LEFT JOIN FETCH r.metadata + WHERE r.requestIdBin = :id + """) + Optional findByIdWithMetadata(@Param("id") byte[] id); + } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/service/MemberService.java b/huertos/src/main/java/net/miarma/backend/huertos/service/MemberService.java index de9612b..c1f4f4a 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/service/MemberService.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/service/MemberService.java @@ -182,11 +182,11 @@ public Boolean hasCollaboratorRequest(Integer memberNumber) { UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId(); - return requestService.hasPendingCollaboratorRequest(userId); + return requestService.hasCollaboratorRequest(userId); } public Boolean hasGreenhouseRequest(Integer memberNumber) { UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId(); - return requestService.hasPendingGreenhouseRequest(userId); + return requestService.hasGreenhouseRequest(userId); } } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/service/RequestAcceptanceService.java b/huertos/src/main/java/net/miarma/backend/huertos/service/RequestAcceptanceService.java index 7add5f7..50bc655 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/service/RequestAcceptanceService.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/service/RequestAcceptanceService.java @@ -2,7 +2,6 @@ package net.miarma.backend.huertos.service; import jakarta.transaction.Transactional; import net.miarma.backend.huertos.client.HuertosWebClient; -import net.miarma.backend.huertos.mapper.RequestMapper; import net.miarma.backend.huertos.mapper.RequestMetadataMapper; import net.miarma.backend.huertos.model.Request; import net.miarma.backend.huertos.model.RequestMetadata; @@ -11,88 +10,131 @@ import net.miarma.backlib.dto.UserWithCredentialDto; import net.miarma.backlib.exception.BadRequestException; import org.springframework.stereotype.Service; -import java.time.Instant; import java.util.UUID; @Service -@Transactional public class RequestAcceptanceService { + private final RequestService requestService; private final UserMetadataService metadataService; private final HuertosWebClient huertosWebClient; + private final MemberService memberService; - public RequestAcceptanceService(RequestService requestService, UserMetadataService metadataService, HuertosWebClient huertosWebClient) { + public RequestAcceptanceService( + RequestService requestService, + UserMetadataService metadataService, + HuertosWebClient huertosWebClient, + MemberService memberService + ) { this.requestService = requestService; this.metadataService = metadataService; this.huertosWebClient = huertosWebClient; + this.memberService = memberService; } - @Transactional public Request acceptRequest(UUID requestId) { Request request = requestService.accept(requestId); - RequestMetadata metadata = request.getMetadata(); - if (metadata == null) throw new BadRequestException("No hay metadata asociada"); - - switch (request.getType()) { - case 0: // REGISTER - UserWithCredentialDto createdUser = huertosWebClient.createUser( - RequestMetadataMapper.toDto(metadata) - ); - - UserMetadata userMetadata = new UserMetadata(); - userMetadata.setUserId(createdUser.user().getUserId()); - userMetadata.setMemberNumber(metadata.getMemberNumber()); - userMetadata.setPlotNumber(metadata.getPlotNumber()); - userMetadata.setDni(metadata.getDni()); - userMetadata.setPhone(metadata.getPhone()); - userMetadata.setType((byte)0); - userMetadata.setRole((byte)0); - metadataService.create(userMetadata); - break; - - case 1: // UNREGISTER - UserMetadata toRemove = metadataService.getByMemberNumber(metadata.getMemberNumber()); - huertosWebClient.deleteUser(toRemove.getUserId()); // borramos User + Credential + Metadata - break; - - case 2: // ADD_COLLABORATOR - UserWithCredentialDto newCollab = huertosWebClient.createUser( - RequestMetadataMapper.toDto(metadata) - ); - - UserMetadata collabMeta = new UserMetadata(); - collabMeta.setUserId(newCollab.user().getUserId()); - collabMeta.setMemberNumber(metadata.getMemberNumber()); - collabMeta.setPlotNumber(metadata.getPlotNumber()); - collabMeta.setDni(metadata.getDni()); - collabMeta.setPhone(metadata.getPhone()); - collabMeta.setType((byte)3); // colaborador - collabMeta.setRole((byte)0); - metadataService.create(collabMeta); - break; - - case 3: // REMOVE_COLLABORATOR - UserMetadata collabToRemove = metadataService.getByMemberNumber(metadata.getMemberNumber()); - huertosWebClient.deleteUser(collabToRemove.getUserId()); - break; - - case 4: // ADD_GREENHOUSE - UserMetadata greenhouseMeta = metadataService.getByMemberNumber(metadata.getMemberNumber()); - greenhouseMeta.setType((byte)2); // invernadero - metadataService.update(greenhouseMeta.getUserId(), greenhouseMeta); - break; - - case 5: // REMOVE_GREENHOUSE - UserMetadata ghToRemove = metadataService.getByMemberNumber(metadata.getMemberNumber()); - ghToRemove.setType((byte)1); // socio normal - metadataService.update(ghToRemove.getUserId(), ghToRemove); - break; - - default: - throw new BadRequestException("Tipo de solicitud no soportado para aceptar"); + if (request.getMetadata() == null) { + throw new BadRequestException("No hay metadata asociada"); } return request; } + + public void handleSideEffects(Request request) { + RequestMetadata metadata = request.getMetadata(); + + switch (request.getType()) { + + case 0: // REGISTER + handleRegister(metadata); + break; + + case 1: // UNREGISTER + handleUnregister(metadata); + break; + + case 2: // ADD_COLLABORATOR + handleAddCollaborator(metadata); + break; + + case 3: // REMOVE_COLLABORATOR + handleRemoveCollaborator(metadata); + break; + + case 4: // ADD_GREENHOUSE + handleAddGreenhouse(metadata); + break; + + case 5: // REMOVE_GREENHOUSE + handleRemoveGreenhouse(metadata); + break; + + default: + throw new BadRequestException("Tipo de solicitud no soportado"); + } + } + + private void handleRegister(RequestMetadata metadata) { + UserWithCredentialDto createdUser = + huertosWebClient.createUser(RequestMetadataMapper.toDto(metadata)); + + UserMetadata userMetadata = buildBaseUserMetadata(metadata, createdUser.user().getUserId()); + userMetadata.setType((byte) 0); // socio + userMetadata.setRole((byte) 0); + + metadataService.create(userMetadata); + } + + private void handleUnregister(RequestMetadata metadata) { + UserMetadata toRemove = metadataService.getByMemberNumber(metadata.getMemberNumber()); + huertosWebClient.updateCredentialStatus(toRemove.getUserId(), (byte)1, (byte)0); + } + + private void handleAddCollaborator(RequestMetadata metadata) { + UserWithCredentialDto newCollab = + huertosWebClient.createUser(RequestMetadataMapper.toDto(metadata)); + + UserMetadata collabMeta = buildBaseUserMetadata( + metadata, + newCollab.user().getUserId() + ); + + collabMeta.setType((byte) 3); // colaborador + collabMeta.setRole((byte) 0); + + metadataService.create(collabMeta); + } + + private void handleRemoveCollaborator(RequestMetadata metadata) { + UserMetadata collab = metadataService.getByMemberNumber(metadata.getMemberNumber()); + huertosWebClient.updateCredentialStatus(collab.getUserId(), (byte)1, (byte)0); + } + + private void handleAddGreenhouse(RequestMetadata metadata) { + UserMetadata user = + metadataService.getByMemberNumber(metadata.getMemberNumber()); + + user.setType((byte) 2); // invernadero + metadataService.update(user.getUserId(), user); + } + + private void handleRemoveGreenhouse(RequestMetadata metadata) { + UserMetadata user = + metadataService.getByMemberNumber(metadata.getMemberNumber()); + + user.setType((byte) 1); // socio normal + metadataService.update(user.getUserId(), user); + } + + private UserMetadata buildBaseUserMetadata(RequestMetadata metadata, UUID userId) { + UserMetadata um = new UserMetadata(); + um.setUserId(userId); + um.setMemberNumber(metadata.getMemberNumber()); + um.setPlotNumber(metadata.getPlotNumber()); + um.setDni(metadata.getDni()); + um.setPhone(metadata.getPhone()); + return um; + } } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/service/RequestService.java b/huertos/src/main/java/net/miarma/backend/huertos/service/RequestService.java index 7819c7b..4a96ba4 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/service/RequestService.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/service/RequestService.java @@ -8,6 +8,8 @@ import net.miarma.backend.huertos.dto.RequestDto; import net.miarma.backend.huertos.dto.RequestMetadataDto; import net.miarma.backend.huertos.mapper.RequestMapper; import net.miarma.backend.huertos.mapper.RequestMetadataMapper; +import net.miarma.backend.huertos.validation.RequestValidator; +import net.miarma.backlib.exception.ConflictException; import org.springframework.stereotype.Service; import jakarta.transaction.Transactional; @@ -47,25 +49,36 @@ public class RequestService { .toList(); } - public Request create(Request request) { - if (request.getType() == null) throw new BadRequestException("Tipo de solicitud obligatorio"); - request.setRequestId(UUID.randomUUID()); - request.setCreatedAt(Instant.now()); - return requestRepository.save(request); - } - @Transactional - public Request createWithMetadata(RequestDto.Request requestDto, - RequestMetadataDto metadataDto) { - Request request = RequestMapper.toEntity(requestDto); - RequestMetadata metadata = RequestMetadataMapper.fromDto(metadataDto); - request.setMetadata(metadata); + public Request create(Request request) { + + if (request == null) { + throw new BadRequestException("La solicitud es obligatoria"); + } + + if (request.getType() == null) { + throw new BadRequestException("El tipo de solicitud es obligatorio"); + } + + if (request.getType() == 2 && hasCollaboratorRequest(request.getUserId())) { // tiene soli de collab + throw new ConflictException("Ya tienes una solicitud, espera que se acepte o se elimine al ser rechazada"); + } + + if (request.getType() == 1 && hasGreenhouseRequest(request.getUserId())) { // tiene soli de invernadero + throw new ConflictException("Ya tienes una solicitud, espera que se acepte o se elimine al ser rechazada"); + } + request.setRequestId(UUID.randomUUID()); request.setCreatedAt(Instant.now()); + request.getMetadata().setRequestId(request.getRequestId()); + + if (request.getMetadata() != null) { + RequestValidator.validate(request.getMetadata(), request.getType()); + } + return requestRepository.save(request); } - public Request update(UUID requestId, Request changes) { Request request = getById(requestId); @@ -77,13 +90,21 @@ public class RequestService { } public Request accept(UUID requestId) { - Request request = getById(requestId); + byte[] bin = UuidUtil.uuidToBin(requestId); + Request request = requestRepository.findByIdWithMetadata(bin) + .orElseThrow(() -> new NotFoundException("Request no encontrada")); + if (request.getStatus() != 0) { + throw new BadRequestException("La solicitud ya ha sido procesada"); + } request.setStatus((byte)1); return requestRepository.save(request); } public Request reject(UUID requestId) { Request request = getById(requestId); + if (request.getStatus() != 0) { + throw new BadRequestException("La solicitud ya ha sido procesada"); + } request.setStatus((byte)2); return requestRepository.save(request); } @@ -96,12 +117,12 @@ public class RequestService { requestRepository.deleteById(UuidUtil.uuidToBin(id)); } - public boolean hasPendingGreenhouseRequest(UUID userId) { + public boolean hasGreenhouseRequest(UUID userId) { return getByUserId(userId).stream() .anyMatch(r -> r.getType() == 1); } - public boolean hasPendingCollaboratorRequest(UUID userId) { + public boolean hasCollaboratorRequest(UUID userId) { return getByUserId(userId).stream() .anyMatch(r -> r.getType() == 2); } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/service/UserMetadataService.java b/huertos/src/main/java/net/miarma/backend/huertos/service/UserMetadataService.java index 8d52c1b..4b18c93 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/service/UserMetadataService.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/service/UserMetadataService.java @@ -77,7 +77,7 @@ public class UserMetadataService { "metadataByMemberNumber", "metadataExists" }, - key = "#userId" + key = "#p0" ) public UserMetadata update(UUID userId, UserMetadata changes) { byte[] idBytes = UuidUtil.uuidToBin(userId); diff --git a/huertos/src/main/java/net/miarma/backend/huertos/util/UsernameGenerator.java b/huertos/src/main/java/net/miarma/backend/huertos/util/UsernameGenerator.java index a55154a..1f7018b 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/util/UsernameGenerator.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/util/UsernameGenerator.java @@ -1,7 +1,9 @@ package net.miarma.backend.huertos.util; +import java.util.Locale; + public class UsernameGenerator { public static String generate(String name, Integer number) { - return name.split(" ")[0] + number; + return name.split(" ")[0].toLowerCase() + number; } } diff --git a/huertos/src/main/java/net/miarma/backend/huertos/validation/RequestValidator.java b/huertos/src/main/java/net/miarma/backend/huertos/validation/RequestValidator.java index 9492bbb..50d2a46 100644 --- a/huertos/src/main/java/net/miarma/backend/huertos/validation/RequestValidator.java +++ b/huertos/src/main/java/net/miarma/backend/huertos/validation/RequestValidator.java @@ -1,4 +1,54 @@ package net.miarma.backend.huertos.validation; +import net.miarma.backend.huertos.model.RequestMetadata; +import net.miarma.backlib.exception.BadRequestException; + public class RequestValidator { + public static void validate(RequestMetadata metadata, Byte requestType) { + if (metadata.getRequestId() == null) { + throw new BadRequestException("Estos metadatos deben pertenecer a una solicitud (falta ID)"); + } + + if (isBlank(metadata.getDisplayName())) { + throw new BadRequestException("El nombre es obligatorio"); + } + + if (isBlank(metadata.getDni())) { + throw new BadRequestException("El DNI es obligatorio"); + } + + if (isBlank(metadata.getEmail())) { + throw new BadRequestException("El email es obligatorio"); + } + + if (isBlank(metadata.getUsername())) { + throw new BadRequestException("El username es obligatorio"); + } + + if (metadata.getType() == null) { + throw new BadRequestException("El tipo de usuario es obligatorio"); + } + + if (requestType == 2) { + if (metadata.getPlotNumber() == null) { + throw new BadRequestException("El colaborador debe tener parcela"); + } + } + + if (requestType == 0 || requestType == 1) { + if (metadata.getMemberNumber() == null) { + throw new BadRequestException("El número de socio es obligatorio"); + } + } + + if (requestType == 0) { + if (metadata.getAddress() == null || metadata.getZipCode() == null || metadata.getCity() == null) { + throw new BadRequestException("La dirección, código postal y ciudad son obligatorios"); + } + } + } + + private static boolean isBlank(String s) { + return s == null || s.trim().isEmpty(); + } }