Fix: services and controllers argument type discordance. Add: totally revamped request system, easier to manager than older pre-user based one. Remove: old views no longer necessary to have.

This commit is contained in:
Jose
2026-01-29 10:58:55 +01:00
parent 2627267391
commit a46ab8635c
69 changed files with 1124 additions and 2403 deletions

14
TODO Normal file
View File

@@ -0,0 +1,14 @@
POR HACER --------------------------------
- añadir colaborador desde perfil
- apuntarse lista espera
- mail wrapper
- documentación
- cambiar contraseña (?)
- aceptar solicitudes LE/Colab (sobre todo por crear preusers)
- 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

View File

@@ -0,0 +1,6 @@
package net.miarma.backlib.dto;
public record CreateUserDto(String displayName,
String avatar) {
}

View File

@@ -0,0 +1,45 @@
package net.miarma.backlib.security;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PasswordGenerator {
private static final String UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER = "abcdefghijklmnopqrstuvwxyz";
private static final String DIGITS = "0123456789";
private static final String SYMBOLS = "!@#$%^&*"; // compatibles con bcrypt
private static final String ALL = UPPER + LOWER + DIGITS + SYMBOLS;
private static final SecureRandom random = new SecureRandom();
public static String generate(int length) {
if (length < 8) length = 8;
List<Character> password = new ArrayList<>();
password.add(getRandChar(UPPER));
password.add(getRandChar(LOWER));
password.add(getRandChar(DIGITS));
password.add(getRandChar(SYMBOLS));
while (password.size() < length) {
password.add(getRandChar(ALL));
}
Collections.shuffle(password, random);
StringBuilder sb = new StringBuilder();
for (char c : password) {
sb.append(c);
}
return sb.toString();
}
private static char getRandChar(String chars) {
return chars.charAt(random.nextInt(chars.length()));
}
}

View File

@@ -58,7 +58,9 @@ public class CredentialController {
@RequestBody CredentialDto dto @RequestBody CredentialDto dto
) { ) {
dto.setCredentialId(credentialId); dto.setCredentialId(credentialId);
return ResponseEntity.ok(credentialService.update(credentialId, dto)); return ResponseEntity.ok(
credentialService.update(
credentialId, CredentialMapper.toEntity(dto)));
} }
@DeleteMapping("/{credential_id}") @DeleteMapping("/{credential_id}")

View File

@@ -54,27 +54,17 @@ public class FileController {
@PostMapping @PostMapping
@PreAuthorize("hasRole('ADMIN') or #uploadedBy == authentication.principal.userId") @PreAuthorize("hasRole('ADMIN') or #uploadedBy == authentication.principal.userId")
public ResponseEntity<FileDto.Response> create( public ResponseEntity<FileDto.Response> create(
@RequestParam String fileName, @RequestBody FileDto.Request dto,
@RequestParam String mimeType,
@RequestParam UUID uploadedBy,
@RequestParam Byte context,
@RequestPart("file") MultipartFile file @RequestPart("file") MultipartFile file
) throws IOException { ) throws IOException {
FileDto.Request dto = new FileDto.Request(); File created = fileService.create(FileMapper.toEntity(dto), file.getBytes());
dto.setFileName(fileName);
dto.setMimeType(mimeType);
dto.setUploadedBy(uploadedBy);
dto.setContext(context);
File created = fileService.create(dto, file.getBytes());
return ResponseEntity.status(HttpStatus.CREATED).body(FileMapper.toResponse(created)); return ResponseEntity.status(HttpStatus.CREATED).body(FileMapper.toResponse(created));
} }
@PutMapping("/{fileId}") @PutMapping("/{fileId}")
@PreAuthorize("hasRole('ADMIN') or @fileService.isOwner(#fileId, authentication.principal.userId)") @PreAuthorize("hasRole('ADMIN') or @fileService.isOwner(#fileId, authentication.principal.userId)")
public ResponseEntity<File> update(@PathVariable("fileId") UUID fileId, @RequestBody File file) { public ResponseEntity<File> update(@PathVariable("fileId") UUID fileId, @RequestBody FileDto.Request request) {
file.setFileId(fileId); File updated = fileService.update(fileId, FileMapper.toEntity(request));
File updated = fileService.update(file);
return ResponseEntity.ok(updated); return ResponseEntity.ok(updated);
} }

View File

@@ -44,9 +44,11 @@ public class UserController {
@PostMapping @PostMapping
@PreAuthorize("hasRole('ADMIN')") @PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<UserDto> create(@RequestBody UserDto dto) { public ResponseEntity<UserDto> create(@RequestBody CreateUserDto dto) {
return ResponseEntity.ok( return ResponseEntity.ok(
UserMapper.toDto(userService.create(dto)) UserMapper.toDto(
userService.create(
UserMapper.fromCreateDto(dto)))
); );
} }
@@ -89,13 +91,17 @@ public class UserController {
) )
); );
} }
@PutMapping("/{user_id}") @PutMapping("/{user_id}")
@PreAuthorize("hasRole('ADMIN') or #userId == principal.userId") @PreAuthorize("hasRole('ADMIN') or #userId == principal.userId")
public ResponseEntity<UserDto> update(@PathVariable("user_id") UUID userId, @RequestBody UserDto dto) { public ResponseEntity<UserDto> update(
return ResponseEntity.ok(UserMapper.toDto(userService.update(userId, dto))); @PathVariable("user_id") UUID userId,
} @RequestBody UserDto dto
) {
User updated = userService.update(userId, UserMapper.fromDto(dto));
return ResponseEntity.ok(UserMapper.toDto(updated));
}
@GetMapping("/{user_id}/avatar") @GetMapping("/{user_id}/avatar")
public ResponseEntity<String> getAvatar(@PathVariable("user_id") UUID userId) { public ResponseEntity<String> getAvatar(@PathVariable("user_id") UUID userId) {
return ResponseEntity.ok(userService.getById(userId).getAvatar()); return ResponseEntity.ok(userService.getById(userId).getAvatar());

View File

@@ -1,11 +1,35 @@
package net.miarma.backend.core.mapper; package net.miarma.backend.core.mapper;
import net.miarma.backend.core.model.User; import net.miarma.backend.core.model.User;
import net.miarma.backlib.dto.CreateUserDto;
import net.miarma.backlib.dto.CredentialDto; import net.miarma.backlib.dto.CredentialDto;
import net.miarma.backlib.dto.UserDto; import net.miarma.backlib.dto.UserDto;
import net.miarma.backlib.dto.UserWithCredentialDto; import net.miarma.backlib.dto.UserWithCredentialDto;
import java.util.UUID;
public class UserMapper { public class UserMapper {
public static User fromDto(UserDto dto) {
if (dto == null) return null;
User user = new User();
user.setDisplayName(dto.getDisplayName());
user.setAvatar(dto.getAvatar());
user.setGlobalRole(dto.getGlobalRole());
user.setGlobalStatus(dto.getGlobalStatus());
return user;
}
public static User fromCreateDto(CreateUserDto dto) {
User user = new User();
user.setUserId(UUID.randomUUID());
user.setDisplayName(dto.displayName());
user.setAvatar(dto.avatar() != null ? dto.avatar() : null);
user.setGlobalRole((byte)0);
user.setGlobalStatus((byte)1);
return user;
}
public static UserDto toDto(User u) { public static UserDto toDto(User u) {
if (u == null) return null; if (u == null) return null;

View File

@@ -2,6 +2,7 @@ package net.miarma.backend.core.service;
import java.util.UUID; import java.util.UUID;
import net.miarma.backlib.dto.*;
import net.miarma.backlib.exception.ConflictException; import net.miarma.backlib.exception.ConflictException;
import net.miarma.backlib.exception.ForbiddenException; import net.miarma.backlib.exception.ForbiddenException;
import net.miarma.backlib.exception.UnauthorizedException; import net.miarma.backlib.exception.UnauthorizedException;
@@ -12,11 +13,6 @@ import net.miarma.backend.core.mapper.CredentialMapper;
import net.miarma.backend.core.mapper.UserMapper; import net.miarma.backend.core.mapper.UserMapper;
import net.miarma.backend.core.model.Credential; import net.miarma.backend.core.model.Credential;
import net.miarma.backend.core.model.User; import net.miarma.backend.core.model.User;
import net.miarma.backlib.dto.CredentialDto;
import net.miarma.backlib.dto.LoginRequest;
import net.miarma.backlib.dto.LoginResponse;
import net.miarma.backlib.dto.RegisterRequest;
import net.miarma.backlib.dto.UserDto;
import tools.jackson.databind.JsonNode; import tools.jackson.databind.JsonNode;
@Service @Service
@@ -39,11 +35,11 @@ public class AuthService {
Credential cred = credentialService.getForLogin(request.serviceId(), request.username()); Credential cred = credentialService.getForLogin(request.serviceId(), request.username());
if (!passwordEncoder.matches(request.password(), cred.getPassword())) { if (!passwordEncoder.matches(request.password(), cred.getPassword())) {
throw new UnauthorizedException("Invalid credentials"); throw new UnauthorizedException("Credenciales no válidas");
} }
if (cred.getStatus() == 0) { if (cred.getStatus() == 0) {
throw new ForbiddenException("This account is inactive"); throw new ForbiddenException("Esa cuenta está desactivada");
} }
String token = jwtService.generateToken(cred.getUserId(), request.serviceId()); String token = jwtService.generateToken(cred.getUserId(), request.serviceId());
@@ -55,17 +51,15 @@ public class AuthService {
public LoginResponse register(RegisterRequest request) { public LoginResponse register(RegisterRequest request) {
if (credentialService.existsByUsernameAndService(request.username(), request.serviceId())) { if (credentialService.existsByUsernameAndService(request.username(), request.serviceId())) {
throw new ConflictException("Username already taken"); throw new ConflictException("Ese usuario ya existe");
} }
User user; User user;
try { try {
user = credentialService.getByEmail(request.email()); user = credentialService.getByEmail(request.email());
} catch (Exception e) { } catch (Exception e) {
UserDto dto = new UserDto(); CreateUserDto dto = new CreateUserDto(request.displayName(), null);
dto.setUserId(UUID.randomUUID()); user = userService.create(UserMapper.fromCreateDto(dto));
dto.setDisplayName(request.displayName());
user = userService.create(dto);
} }
Credential cred = new Credential(); Credential cred = new Credential();

View File

@@ -33,30 +33,30 @@ public class CredentialService {
public Credential getById(UUID credentialId) { public Credential getById(UUID credentialId) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId); byte[] idBytes = UuidUtil.uuidToBin(credentialId);
return credentialRepository.findById(idBytes) return credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found")); .orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
} }
public Credential create(Credential credential) { public Credential create(Credential credential) {
if (credential.getUsername() == null || credential.getUsername().isBlank()) { if (credential.getUsername() == null || credential.getUsername().isBlank()) {
throw new ValidationException("userName", "Username cannot be blank"); throw new ValidationException("userName", "El usuario no puede estar vacío");
} }
if (credential.getEmail() == null || !credential.getEmail().matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) { if (credential.getEmail() == null || !credential.getEmail().matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) {
throw new ValidationException("email", "Invalid email format"); throw new ValidationException("email", "Formato de email no válido");
} }
if (credential.getPassword() == null || credential.getPassword().length() < 6) { if (credential.getPassword() == null || credential.getPassword().length() < 6) {
throw new ValidationException("password", "Password must be at least 6 characters"); throw new ValidationException("password", "La contraseña tiene que tener al menos 6 caracteres");
} }
if (credential.getServiceId() == null || credential.getServiceId() < 0) { if (credential.getServiceId() == null || credential.getServiceId() < 0) {
throw new ValidationException("serviceId", "ServiceId must be positive"); throw new ValidationException("serviceId", "El identificador de servicio debe ser positivo");
} }
boolean existsUsername = credentialRepository.existsByUsernameAndServiceId( boolean existsUsername = credentialRepository.existsByUsernameAndServiceId(
credential.getUsername(), credential.getServiceId()); credential.getUsername(), credential.getServiceId());
if (existsUsername) throw new ConflictException("Username already exists for this service"); if (existsUsername) throw new ConflictException("El usuario ya existe para este servicio");
boolean existsEmail = credentialRepository.existsByEmailAndServiceId( boolean existsEmail = credentialRepository.existsByEmailAndServiceId(
credential.getEmail(), credential.getServiceId()); credential.getEmail(), credential.getServiceId());
if (existsEmail) throw new ConflictException("Email already exists for this service"); if (existsEmail) throw new ConflictException("El email ya existe para este servicio");
credential.setCredentialId(UUID.randomUUID()); credential.setCredentialId(UUID.randomUUID());
credential.setPassword(passwordEncoder.encode(credential.getPassword())); credential.setPassword(passwordEncoder.encode(credential.getPassword()));
@@ -78,25 +78,25 @@ public class CredentialService {
public List<Credential> getByUserId(UUID userId) { public List<Credential> getByUserId(UUID userId) {
List<Credential> creds = credentialRepository.findByUserId(UuidUtil.uuidToBin(userId)); List<Credential> creds = credentialRepository.findByUserId(UuidUtil.uuidToBin(userId));
if (creds.isEmpty()) { if (creds.isEmpty()) {
throw new NotFoundException("User has no credentials"); throw new NotFoundException("El usuario no tiene cuenta");
} }
return creds; return creds;
} }
public User getByEmail(String email) { public User getByEmail(String email) {
return credentialRepository.findByEmail(email) return credentialRepository.findByEmail(email)
.orElseThrow(() -> new NotFoundException("No credential found for email")) .orElseThrow(() -> new NotFoundException("No hay cuenta asociada a ese email"))
.getUser(); .getUser();
} }
public Credential getByUserIdAndService(UUID userId, Byte serviceId) { public Credential getByUserIdAndService(UUID userId, Byte serviceId) {
return credentialRepository.findByUserIdAndServiceId(UuidUtil.uuidToBin(userId), serviceId) return credentialRepository.findByUserIdAndServiceId(UuidUtil.uuidToBin(userId), serviceId)
.orElseThrow(() -> new NotFoundException("Credential not found in this site")); .orElseThrow(() -> new NotFoundException("El usuario no tiene cuenta en este sitio"));
} }
public Credential getForLogin(Byte serviceId, String username) { public Credential getForLogin(Byte serviceId, String username) {
return credentialRepository.findByServiceIdAndUsername(serviceId, username) return credentialRepository.findByServiceIdAndUsername(serviceId, username)
.orElseThrow(() -> new BadRequestException("Invalid credentials")); .orElseThrow(() -> new BadRequestException("Credenciales no válidas"));
} }
public boolean existsByUsernameAndService(String username, int serviceId) { public boolean existsByUsernameAndService(String username, int serviceId) {
@@ -106,30 +106,30 @@ public class CredentialService {
public boolean isOwner(UUID credentialId, UUID userId) { public boolean isOwner(UUID credentialId, UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId); byte[] idBytes = UuidUtil.uuidToBin(credentialId);
Credential c = credentialRepository.findById(idBytes) Credential c = credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found")); .orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
return c.getUserId().equals(userId); return c.getUserId().equals(userId);
} }
public Credential update(UUID credentialId, CredentialDto dto) { public Credential update(UUID credentialId, Credential changes) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId); byte[] idBytes = UuidUtil.uuidToBin(credentialId);
Credential cred = credentialRepository.findById(idBytes) Credential cred = credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found")); .orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
if (dto.getUsername() != null && dto.getUsername().isBlank()) { if (changes.getUsername() != null && changes.getUsername().isBlank()) {
throw new ValidationException("userName", "Username cannot be blank"); throw new ValidationException("userName", "El usuario no puede estar vacío");
} }
if (dto.getEmail() != null && !dto.getEmail().matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) { if (changes.getEmail() != null && !changes.getEmail().matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) {
throw new ValidationException("email", "Invalid email format"); throw new ValidationException("email", "Formato de email no válido");
} }
if (dto.getServiceId() != null && dto.getServiceId() < 0) { if (changes.getServiceId() != null && changes.getServiceId() < 0) {
throw new ValidationException("serviceId", "ServiceId must be positive"); throw new ValidationException("serviceId", "El identificador de servicio debe ser positivo");
} }
if (dto.getUsername() != null) cred.setUsername(dto.getUsername()); if (changes.getUsername() != null) cred.setUsername(changes.getUsername());
if (dto.getEmail() != null) cred.setEmail(dto.getEmail()); if (changes.getEmail() != null) cred.setEmail(changes.getEmail());
if (dto.getServiceId() != null) cred.setServiceId(dto.getServiceId()); if (changes.getServiceId() != null) cred.setServiceId(changes.getServiceId());
if (dto.getStatus() != null) cred.setStatus(dto.getStatus()); if (changes.getStatus() != null) cred.setStatus(changes.getStatus());
return credentialRepository.save(cred); return credentialRepository.save(cred);
} }
@@ -138,10 +138,10 @@ public class CredentialService {
byte[] idBytes = UuidUtil.uuidToBin(credentialId); byte[] idBytes = UuidUtil.uuidToBin(credentialId);
Credential cred = credentialRepository.findById(idBytes) Credential cred = credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found")); .orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
if (!passwordEncoder.matches(request.oldPassword(), cred.getPassword())) { if (!passwordEncoder.matches(request.oldPassword(), cred.getPassword())) {
throw new ValidationException("oldPassword", "Old password is incorrect"); throw new ValidationException("oldPassword", "La contraseña actual es incorrecta");
} }
cred.setPassword(passwordEncoder.encode(request.newPassword())); cred.setPassword(passwordEncoder.encode(request.newPassword()));
@@ -151,19 +151,19 @@ public class CredentialService {
public void delete(UUID credentialId) { public void delete(UUID credentialId) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId); byte[] idBytes = UuidUtil.uuidToBin(credentialId);
if(!credentialRepository.existsById(idBytes)) if(!credentialRepository.existsById(idBytes))
throw new NotFoundException("Credential not found"); throw new NotFoundException("Cuenta no encontrada");
credentialRepository.deleteById(idBytes); credentialRepository.deleteById(idBytes);
} }
public Byte getStatus(UUID credentialId) { public Byte getStatus(UUID credentialId) {
Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId)) Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId))
.orElseThrow(() -> new NotFoundException("User not found"));; .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
return credential.getStatus(); return credential.getStatus();
} }
public void updateStatus(UUID credentialId, Byte status) { public void updateStatus(UUID credentialId, Byte status) {
Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId)) Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId))
.orElseThrow(() -> new NotFoundException("User not found"));; .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
credential.setStatus(status); credential.setStatus(status);
credentialRepository.save(credential); credentialRepository.save(credential);
} }

View File

@@ -36,7 +36,7 @@ public class FileService {
public File getById(UUID fileId) { public File getById(UUID fileId) {
byte[] idBytes = UuidUtil.uuidToBin(fileId); byte[] idBytes = UuidUtil.uuidToBin(fileId);
return fileRepository.findById(idBytes) return fileRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("File not found")); .orElseThrow(() -> new NotFoundException("Archivo no encontrado"));
} }
public List<File> getAll() { public List<File> getAll() {
@@ -47,26 +47,26 @@ public class FileService {
return fileRepository.findByUploadedBy(userId); return fileRepository.findByUploadedBy(userId);
} }
public File create(FileDto.Request dto, byte[] fileBinary) throws IOException { public File create(File file, byte[] fileBinary) throws IOException {
Path dirPath = Paths.get(filesDir, String.valueOf(dto.getContext())); Path dirPath = Paths.get(filesDir, String.valueOf(file.getContext()));
if (!Files.exists(dirPath)) { if (!Files.exists(dirPath)) {
Files.createDirectories(dirPath); Files.createDirectories(dirPath);
} }
Path filePath = dirPath.resolve(dto.getFileName()); Path filePath = dirPath.resolve(file.getFileName());
try (FileOutputStream fos = new FileOutputStream(filePath.toFile())) { try (FileOutputStream fos = new FileOutputStream(filePath.toFile())) {
fos.write(fileBinary); fos.write(fileBinary);
} }
dto.setFilePath(filePath.toString()); file.setFilePath(filePath.toString());
return fileRepository.save(FileMapper.toEntity(dto)); return fileRepository.save(file);
} }
public File update(File file) { public File update(UUID fileId, File file) {
byte[] idBytes = UuidUtil.uuidToBin(file.getFileId()); byte[] idBytes = UuidUtil.uuidToBin(fileId);
if (!fileRepository.existsById(idBytes)) { if (!fileRepository.existsById(idBytes)) {
throw new NotFoundException("File not found"); throw new NotFoundException("Archivo no encontrado");
} }
return fileRepository.save(file); return fileRepository.save(file);
} }
@@ -74,7 +74,7 @@ public class FileService {
public void delete(UUID fileId) { public void delete(UUID fileId) {
byte[] idBytes = UuidUtil.uuidToBin(fileId); byte[] idBytes = UuidUtil.uuidToBin(fileId);
if (!fileRepository.existsById(idBytes)) { if (!fileRepository.existsById(idBytes)) {
throw new NotFoundException("File not found"); throw new NotFoundException("Archivo no encontrado");
} }
fileRepository.deleteById(idBytes); fileRepository.deleteById(idBytes);
} }

View File

@@ -31,58 +31,49 @@ public class UserService {
public User getById(UUID userId) { public User getById(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId); byte[] idBytes = UuidUtil.uuidToBin(userId);
return userRepository.findById(idBytes) return userRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("User not found")); .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
} }
public User create(UserDto dto) { public User create(User user) {
if(dto.getDisplayName() == null || dto.getDisplayName().isBlank()) { if(user.getDisplayName() == null || user.getDisplayName().isBlank()) {
throw new ValidationException("displayName", "Display name is required"); throw new ValidationException("displayName", "El nombre a mostrar es necesario");
}
return userRepository.save(user);
}
public User update(UUID userId, User changes) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
if (changes.getDisplayName() != null) {
String dn = changes.getDisplayName().trim();
if (dn.isEmpty()) throw new ValidationException("displayName", "No puede estar vacío");
if (dn.length() > 50) throw new ValidationException("displayName", "Máx 50 caracteres");
user.setDisplayName(dn);
} }
User user = new User(); if (changes.getAvatar() != null)
user.setUserId(UUID.randomUUID()); user.setAvatar(changes.getAvatar());
user.setDisplayName(dto.getDisplayName());
user.setAvatar(dto.getAvatar()); if (changes.getGlobalRole() != null)
user.setGlobalRole(dto.getGlobalRole() != null ? dto.getGlobalRole() : 0); user.setGlobalRole(changes.getGlobalRole());
user.setGlobalStatus(dto.getGlobalStatus() != null ? dto.getGlobalStatus() : 1);
if (changes.getGlobalStatus() != null)
user.setGlobalStatus(changes.getGlobalStatus());
return userRepository.save(user); return userRepository.save(user);
} }
public User update(UUID userId, UserDto dto) { public void delete(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
User user = userRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("User not found"));
if (dto.getDisplayName() != null) {
String displayName = dto.getDisplayName().trim();
if (displayName.isEmpty()) {
throw new IllegalArgumentException("Display name cannot be empty");
}
if (displayName.length() > 50) {
throw new IllegalArgumentException("Display name too long (max 50 chars)");
}
user.setDisplayName(displayName);
}
if(dto.getDisplayName() != null) user.setDisplayName(dto.getDisplayName());
if(dto.getAvatar() != null) user.setAvatar(dto.getAvatar());
if(dto.getGlobalRole() != null) user.setGlobalRole(dto.getGlobalRole());
if(dto.getGlobalStatus() != null) user.setGlobalStatus(dto.getGlobalStatus());
return userRepository.save(user);
}
public void delete(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId); byte[] idBytes = UuidUtil.uuidToBin(userId);
if(!userRepository.existsById(idBytes)) if(!userRepository.existsById(idBytes))
throw new NotFoundException("User not found"); throw new NotFoundException("Usuario no encontrado");
userRepository.deleteById(idBytes); userRepository.deleteById(idBytes);
} }
public UserDto updateAvatar(UUID userId, ChangeAvatarRequest req) { public UserDto updateAvatar(UUID userId, ChangeAvatarRequest req) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId)) User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found")); .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
user.setAvatar(req.avatar()); user.setAvatar(req.avatar());
userRepository.save(user); userRepository.save(user);
return UserMapper.toDto(user); return UserMapper.toDto(user);
@@ -90,26 +81,26 @@ public class UserService {
public Byte getStatus(UUID userId) { public Byte getStatus(UUID userId) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId)) User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));; .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
return user.getGlobalStatus(); return user.getGlobalStatus();
} }
public void updateStatus(UUID userId, Byte status) { public void updateStatus(UUID userId, Byte status) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId)) User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));; .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
user.setGlobalStatus(status); user.setGlobalStatus(status);
userRepository.save(user); userRepository.save(user);
} }
public Byte getRole(UUID userId) { public Byte getRole(UUID userId) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId)) User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));; .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
return user.getGlobalRole(); return user.getGlobalRole();
} }
public void updateRole(UUID userId, Byte role) { public void updateRole(UUID userId, Byte role) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId)) User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));; .orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
user.setGlobalRole(role); user.setGlobalRole(role);
userRepository.save(user); userRepository.save(user);
} }

View File

@@ -46,6 +46,15 @@
<version>4.0.1</version> <version>4.0.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!-- CACHE -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<!-- JWT --> <!-- JWT -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>

View File

@@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
@EnableCaching
@SpringBootApplication(scanBasePackages = { @SpringBootApplication(scanBasePackages = {
"net.miarma.backend.huertos", "net.miarma.backend.huertos",
"net.miarma.backlib" "net.miarma.backlib"

View File

@@ -1,8 +1,10 @@
package net.miarma.backend.huertos.client; package net.miarma.backend.huertos.client;
import net.miarma.backlib.dto.LoginRequest; import net.miarma.backend.huertos.dto.RequestMetadataDto;
import net.miarma.backlib.dto.LoginResponse; import net.miarma.backend.huertos.model.RequestMetadata;
import net.miarma.backlib.dto.UserWithCredentialDto; import net.miarma.backend.huertos.util.UsernameGenerator;
import net.miarma.backlib.dto.*;
import net.miarma.backlib.security.PasswordGenerator;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -41,4 +43,44 @@ public class HuertosWebClient {
return arr == null ? List.of() : Arrays.asList(arr); return arr == null ? List.of() : Arrays.asList(arr);
} }
public UserWithCredentialDto createUser(
RequestMetadataDto metadataDto
) {
CreateUserDto userDto = new CreateUserDto(metadataDto.name(), null);
UserDto createdUser = restTemplate.postForObject(
coreUrl + "/users",
userDto,
UserDto.class
);
if (createdUser == null)
throw new RuntimeException("No se pudo crear al usuario");
CreateCredentialDto credDto = new CreateCredentialDto(
createdUser.getUserId(),
(byte)1,
UsernameGenerator.generate(metadataDto.name(), metadataDto.memberNumber()),
metadataDto.email(),
PasswordGenerator.generate(8),
(byte)1
);
CredentialDto createdCred = restTemplate.postForObject(
coreUrl + "/credentials",
credDto,
CredentialDto.class
);
if (createdCred == null)
throw new RuntimeException("No se pudo crear la cuenta del usuario");
return new UserWithCredentialDto(createdUser, createdCred);
}
public void deleteUser(UUID userId) {
try {
restTemplate.delete(coreUrl + "/users/{user_id}", userId);
} catch (Exception e) { }
}
} }

View File

@@ -0,0 +1,26 @@
package net.miarma.backend.huertos.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager(
"members", "memberById", "waitlist",
"metadataByUserId", "metadataByMemberNumber", "metadataExists");
manager.setCaffeine(
Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(10_000)
);
return manager;
}
}

View File

@@ -64,6 +64,8 @@ public class SecurityConfig {
// PUBLICAS // PUBLICAS
.requestMatchers("/auth/login").permitAll() .requestMatchers("/auth/login").permitAll()
.requestMatchers("/users/waitlist/limited").permitAll() .requestMatchers("/users/waitlist/limited").permitAll()
.requestMatchers("/requests").permitAll()
.requestMatchers("/pre-users").permitAll()
.requestMatchers("/users/latest-number").permitAll() .requestMatchers("/users/latest-number").permitAll()
.requestMatchers("/pre-users/validate").permitAll() .requestMatchers("/pre-users/validate").permitAll()
// PRIVADAS // PRIVADAS

View File

@@ -46,7 +46,7 @@ public class AnnouncementController {
@RequestBody AnnouncementDto.Request dto @RequestBody AnnouncementDto.Request dto
) { ) {
return ResponseEntity.ok( return ResponseEntity.ok(
AnnouncementMapper.toResponse(announcementService.update(announcementId, dto)) AnnouncementMapper.toResponse(announcementService.update(announcementId, AnnouncementMapper.toEntity(dto)))
); );
} }
@@ -54,10 +54,10 @@ public class AnnouncementController {
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<AnnouncementDto.Response> create(@RequestBody AnnouncementDto.Request dto) { public ResponseEntity<AnnouncementDto.Response> create(@RequestBody AnnouncementDto.Request dto) {
return ResponseEntity.ok( return ResponseEntity.ok(
AnnouncementMapper.toResponse( AnnouncementMapper.toResponse(
announcementService.create( announcementService.create(
AnnouncementMapper.toEntity(dto) AnnouncementMapper.toEntity(dto)
))); )));
} }
@DeleteMapping("/{announce_id}") @DeleteMapping("/{announce_id}")

View File

@@ -51,8 +51,18 @@ public class ExpenseController {
@PutMapping("/{expense_id}") @PutMapping("/{expense_id}")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<ExpenseDto.Response> update(@PathVariable("expense_id") UUID expenseId, @RequestBody ExpenseDto.Request dto) { public ResponseEntity<ExpenseDto.Response> update(
return ResponseEntity.ok(ExpenseMapper.toResponse(expenseService.update(expenseId, dto))); @PathVariable("expense_id") UUID expenseId,
@RequestBody ExpenseDto.Request dto
) {
Expense updated = expenseService.update(
expenseId,
ExpenseMapper.toEntity(dto)
);
return ResponseEntity.ok(
ExpenseMapper.toResponse(updated)
);
} }
@DeleteMapping("/{expense_id}") @DeleteMapping("/{expense_id}")

View File

@@ -1,12 +1,10 @@
package net.miarma.backend.huertos.controller; package net.miarma.backend.huertos.controller;
import net.miarma.backend.huertos.client.CoreAuthClient; import net.miarma.backend.huertos.client.CoreAuthClient;
import net.miarma.backend.huertos.client.HuertosWebClient;
import net.miarma.backend.huertos.dto.HuertosLoginResponse; import net.miarma.backend.huertos.dto.HuertosLoginResponse;
import net.miarma.backend.huertos.dto.HuertosUserMetadataDto; import net.miarma.backend.huertos.mapper.UserMetadataMapper;
import net.miarma.backend.huertos.mapper.HuertosUserMetadataMapper; import net.miarma.backend.huertos.model.UserMetadata;
import net.miarma.backend.huertos.model.HuertosUserMetadata; import net.miarma.backend.huertos.service.UserMetadataService;
import net.miarma.backend.huertos.service.HuertosUserMetadataService;
import net.miarma.backlib.dto.LoginRequest; import net.miarma.backlib.dto.LoginRequest;
import net.miarma.backlib.dto.LoginResponse; import net.miarma.backlib.dto.LoginResponse;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -18,10 +16,10 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/auth") @RequestMapping("/auth")
public class HuertosAuthController { public class HuertosAuthController {
private final HuertosUserMetadataService metadataService; private final UserMetadataService metadataService;
private final CoreAuthClient authClient; private final CoreAuthClient authClient;
public HuertosAuthController(HuertosUserMetadataService metadataService, public HuertosAuthController(UserMetadataService metadataService,
CoreAuthClient authClient) { CoreAuthClient authClient) {
this.metadataService = metadataService; this.metadataService = metadataService;
this.authClient = authClient; this.authClient = authClient;
@@ -30,13 +28,13 @@ public class HuertosAuthController {
@PostMapping("/login") @PostMapping("/login")
public ResponseEntity<HuertosLoginResponse> login(@RequestBody LoginRequest req) { public ResponseEntity<HuertosLoginResponse> login(@RequestBody LoginRequest req) {
LoginResponse coreResponse = authClient.login(req); LoginResponse coreResponse = authClient.login(req);
HuertosUserMetadata metadata = metadataService.getById(coreResponse.user().getUserId()); UserMetadata metadata = metadataService.getById(coreResponse.user().getUserId());
return ResponseEntity.ok( return ResponseEntity.ok(
new HuertosLoginResponse( new HuertosLoginResponse(
coreResponse.token(), coreResponse.token(),
coreResponse.user(), coreResponse.user(),
coreResponse.account(), coreResponse.account(),
HuertosUserMetadataMapper.toDto(metadata) UserMetadataMapper.toDto(metadata)
) )
); );
} }

View File

@@ -5,7 +5,6 @@ import net.miarma.backend.huertos.dto.view.VIncomesWithInfoDto;
import net.miarma.backend.huertos.mapper.IncomeMapper; import net.miarma.backend.huertos.mapper.IncomeMapper;
import net.miarma.backend.huertos.mapper.view.VIncomesWithInfoMapper; import net.miarma.backend.huertos.mapper.view.VIncomesWithInfoMapper;
import net.miarma.backend.huertos.model.Income; import net.miarma.backend.huertos.model.Income;
import net.miarma.backend.huertos.service.HuertosUserMetadataService;
import net.miarma.backend.huertos.service.IncomeService; import net.miarma.backend.huertos.service.IncomeService;
import net.miarma.backend.huertos.service.view.VIncomesWithInfoService; import net.miarma.backend.huertos.service.view.VIncomesWithInfoService;
import net.miarma.backlib.security.JwtService; import net.miarma.backlib.security.JwtService;
@@ -95,8 +94,14 @@ public class IncomeController {
@PutMapping("/{income_id}") @PutMapping("/{income_id}")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<IncomeDto.Response> update(@PathVariable("income_id") UUID incomeId, @RequestBody IncomeDto.Request dto) { public ResponseEntity<IncomeDto.Response> update(
return ResponseEntity.ok(IncomeMapper.toResponse(incomeService.update(incomeId, dto))); @PathVariable("income_id") UUID incomeId,
@RequestBody IncomeDto.Request dto
) {
return ResponseEntity.ok(
IncomeMapper.toResponse(
incomeService.update(
incomeId, IncomeMapper.toEntity(dto))));
} }
@DeleteMapping("/{income_id}") @DeleteMapping("/{income_id}")

View File

@@ -23,15 +23,9 @@ import java.util.UUID;
public class MemberController { public class MemberController {
private final MemberService memberService; private final MemberService memberService;
private final RequestService requestService;
private final IncomeService incomeService;
private final JwtService jwtService;
public MemberController(MemberService memberService, RequestService requestService, IncomeService incomeService, JwtService jwtService) { public MemberController(MemberService memberService) {
this.memberService = memberService; this.memberService = memberService;
this.requestService = requestService;
this.incomeService = incomeService;
this.jwtService = jwtService;
} }
@GetMapping @GetMapping
@@ -41,41 +35,13 @@ public class MemberController {
} }
@GetMapping("/me") @GetMapping("/me")
public ResponseEntity<MemberProfileDto> getMe() { public ResponseEntity<MemberProfileDto> getMe(Authentication authentication) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication.getPrincipal() instanceof HuertosPrincipal principal)) { if (!(authentication.getPrincipal() instanceof HuertosPrincipal principal)) {
throw new IllegalStateException("Invalid principal type"); throw new IllegalStateException("Tipo de autenticación inválida");
} }
UUID userId = principal.getUserId();
Byte serviceId = principal.getServiceId();
if (serviceId == null) {
throw new IllegalStateException("ServiceId missing in token");
}
MemberDto member = memberService.getById(userId);
Integer memberNumber = member.metadata().getMemberNumber();
List<RequestDto.Response> requests = requestService.getByUserId(userId).stream()
.map(RequestMapper::toResponse)
.toList();
List<IncomeDto.Response> payments = incomeService.getByMemberNumber(memberNumber).stream()
.map(IncomeMapper::toResponse)
.toList();
return ResponseEntity.ok( return ResponseEntity.ok(
new MemberProfileDto( memberService.getMyProfile(principal.getUserId())
member.user(),
member.account(),
member.metadata(),
requests,
payments,
memberService.hasCollaborator(memberNumber),
memberService.hasGreenhouse(memberNumber),
memberService.hasCollaboratorRequest(memberNumber),
memberService.hasGreenhouseRequest(memberNumber)
)
); );
} }

View File

@@ -1,70 +0,0 @@
package net.miarma.backend.huertos.controller;
import net.miarma.backend.huertos.dto.PreUserDto;
import net.miarma.backend.huertos.mapper.PreUserMapper;
import net.miarma.backend.huertos.model.PreUser;
import net.miarma.backend.huertos.service.PreUserService;
import net.miarma.backlib.dto.ApiValidationErrorDto;
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.Map;
import java.util.UUID;
@RestController
@RequestMapping("/pre-users")
public class PreUserController {
private final PreUserService preUserService;
public PreUserController(PreUserService preUserService) {
this.preUserService = preUserService;
}
@GetMapping
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<List<PreUserDto.Response>> getAll() {
return ResponseEntity.ok(
preUserService.getAll()
.stream()
.map(PreUserMapper::toResponse)
.toList()
);
}
@GetMapping("/{pre_user_id}")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<PreUserDto.Response> getById(@PathVariable("pre_user_id") UUID preUserId) {
PreUser preUser = preUserService.getById(preUserId);
return ResponseEntity.ok(PreUserMapper.toResponse(preUser));
}
@PostMapping("/validate")
public ResponseEntity<ApiValidationErrorDto> validate(@RequestBody PreUserDto.Request request) {
Map<String, String> errors = preUserService.validate(request);
if(!errors.isEmpty())
return ResponseEntity.status(HttpStatus.UNPROCESSABLE_CONTENT).body(new ApiValidationErrorDto(errors));
return ResponseEntity.ok(new ApiValidationErrorDto(Map.of()));
}
@PutMapping("/{pre_user_id}")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<PreUserDto.Response> update(
@PathVariable("pre_user_id") UUID preUserId,
@RequestBody PreUserDto.Request dto
) {
return ResponseEntity.ok(
PreUserMapper.toResponse(preUserService.update(preUserId, dto))
);
}
@DeleteMapping("/{pre_user_id}")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<Map<String, String>> delete(@PathVariable("pre_user_id") UUID preUserId) {
preUserService.delete(preUserId);
return ResponseEntity.ok(Map.of("message", "Deleted pre_user: " + preUserId));
}
}

View File

@@ -1,15 +1,11 @@
package net.miarma.backend.huertos.controller; package net.miarma.backend.huertos.controller;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.dto.*; import net.miarma.backend.huertos.dto.*;
import net.miarma.backend.huertos.dto.view.VRequestsWithPreUsersDto;
import net.miarma.backend.huertos.mapper.RequestMapper; import net.miarma.backend.huertos.mapper.RequestMapper;
import net.miarma.backend.huertos.mapper.view.VRequestsWithPreUsersMapper; import net.miarma.backend.huertos.mapper.RequestWithMetadataMapper;
import net.miarma.backend.huertos.model.Request; import net.miarma.backend.huertos.model.Request;
import net.miarma.backend.huertos.model.view.VRequestsWithPreUsers; import net.miarma.backend.huertos.service.RequestAcceptanceService;
import net.miarma.backend.huertos.service.PreUserService;
import net.miarma.backend.huertos.service.RequestService; import net.miarma.backend.huertos.service.RequestService;
import net.miarma.backend.huertos.service.view.VRequestsWithPreUsersService;
import net.miarma.backlib.security.JwtService; import net.miarma.backlib.security.JwtService;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@@ -26,17 +22,14 @@ import java.util.stream.Collectors;
public class RequestController { public class RequestController {
private final RequestService requestService; private final RequestService requestService;
private final PreUserService preUserService; private final RequestAcceptanceService requestAcceptanceService;
private final VRequestsWithPreUsersService vRequestsWithPreUsersService;
private final JwtService jwtService; private final JwtService jwtService;
public RequestController(RequestService requestService, public RequestController(RequestService requestService,
PreUserService preUserService, RequestAcceptanceService requestAcceptanceService,
VRequestsWithPreUsersService vRequestsWithPreUsersService,
JwtService jwtService) { JwtService jwtService) {
this.requestService = requestService; this.requestService = requestService;
this.preUserService = preUserService; this.requestAcceptanceService = requestAcceptanceService;
this.vRequestsWithPreUsersService = vRequestsWithPreUsersService;
this.jwtService = jwtService; this.jwtService = jwtService;
} }
@@ -60,14 +53,6 @@ public class RequestController {
))); )));
} }
@PostMapping("/with-pre-user")
@Transactional
public ResponseEntity<RequestDto.Response> createWithPreUser(
@RequestBody RequestWithPreUserDto.Request body) {
RequestDto.Response response = requestService.createWithPreUser(body.getRequest(), body.getPreUser());
return ResponseEntity.ok(response);
}
@GetMapping("/count") @GetMapping("/count")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<RequestCountDto> getRequestCount() { public ResponseEntity<RequestCountDto> getRequestCount() {
@@ -107,20 +92,21 @@ public class RequestController {
@GetMapping("/full") @GetMapping("/full")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<List<VRequestsWithPreUsersDto>> getAllWithPreUsers() { public ResponseEntity<List<RequestWithMetadataDto>> getAllWithMetadata() {
return ResponseEntity.ok( return ResponseEntity.ok(
vRequestsWithPreUsersService.getAll() requestService.getAll()
.stream() .stream()
.map(VRequestsWithPreUsersMapper::toResponse) .map(RequestWithMetadataMapper::toDto)
.toList() .toList()
); );
} }
@GetMapping("/full/{request_id}") @GetMapping("/full/{request_id}")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<VRequestsWithPreUsersDto> getByIdWithPreUsers(@PathVariable("request_id") UUID requestId) { public ResponseEntity<RequestWithMetadataDto> getByIdWithMetadata(
VRequestsWithPreUsers request = vRequestsWithPreUsersService.getById(requestId); @PathVariable("request_id") UUID requestId) {
return ResponseEntity.ok(VRequestsWithPreUsersMapper.toResponse(request)); Request request = requestService.getById(requestId);
return ResponseEntity.ok(RequestWithMetadataMapper.toDto(request));
} }
@GetMapping("/{request_id}") @GetMapping("/{request_id}")
@@ -137,22 +123,22 @@ public class RequestController {
@RequestBody RequestDto.Request dto @RequestBody RequestDto.Request dto
) { ) {
return ResponseEntity.ok( return ResponseEntity.ok(
RequestMapper.toResponse(requestService.update(requestId, dto)) RequestMapper.toResponse(requestService.update(requestId, RequestMapper.toEntity(dto)))
); );
} }
@PutMapping("/{request_id}/accept") @PutMapping("/{request_id}/accept")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<Map<String, String>> acceptRequest(@PathVariable("request_id") UUID requestId) { public ResponseEntity<Map<String, String>> acceptRequest(@PathVariable("request_id") UUID requestId) {
requestService.acceptRequest(requestId); Request r = requestAcceptanceService.acceptRequest(requestId);
return ResponseEntity.ok(Map.of("message", "Accepted request: " + requestId)); return ResponseEntity.ok(Map.of("message", "Accepted request: " + r.getRequestId()));
} }
@PutMapping("/{request_id}/reject") @PutMapping("/{request_id}/reject")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')") @PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<Map<String, String>> rejectRequest(@PathVariable("request_id") UUID requestId) { public ResponseEntity<Map<String, String>> rejectRequest(@PathVariable("request_id") UUID requestId) {
requestService.rejectRequest(requestId); Request r = requestService.reject(requestId);
return ResponseEntity.ok(Map.of("message", "Denied request: " + requestId)); return ResponseEntity.ok(Map.of("message", "Denied request: " + r.getRequestId()));
} }
@DeleteMapping("/{request_id}") @DeleteMapping("/{request_id}")

View File

@@ -7,6 +7,6 @@ public record HuertosLoginResponse(
String token, String token,
UserDto user, UserDto user,
CredentialDto account, CredentialDto account,
HuertosUserMetadataDto metadata UserMetadataDto metadata
) { ) {
} }

View File

@@ -5,4 +5,4 @@ import net.miarma.backlib.dto.UserDto;
public record MemberDto(UserDto user, public record MemberDto(UserDto user,
CredentialDto account, CredentialDto account,
HuertosUserMetadataDto metadata) {} UserMetadataDto metadata) {}

View File

@@ -8,7 +8,7 @@ import java.util.List;
public record MemberProfileDto( public record MemberProfileDto(
UserDto user, UserDto user,
CredentialDto account, CredentialDto account,
HuertosUserMetadataDto metadata, UserMetadataDto metadata,
List<RequestDto.Response> requests, List<RequestDto.Response> requests,
List<IncomeDto.Response> payments, List<IncomeDto.Response> payments,
boolean hasCollaborator, boolean hasCollaborator,

View File

@@ -1,274 +0,0 @@
package net.miarma.backend.huertos.dto;
import java.time.Instant;
import java.util.UUID;
public class PreUserDto {
public static class Request {
private UUID requestId;
private String userName;
private String displayName;
private String dni;
private String phone;
private String email;
private String password;
private String address;
private String zipCode;
private String city;
private Integer memberNumber;
private Integer plotNumber;
private Byte type;
public UUID getRequestId() {
return requestId;
}
public void setRequestId(UUID requestId) {
this.requestId = requestId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Integer getMemberNumber() {
return memberNumber;
}
public void setMemberNumber(Integer memberNumber) {
this.memberNumber = memberNumber;
}
public Integer getPlotNumber() {
return plotNumber;
}
public void setPlotNumber(Integer plotNumber) {
this.plotNumber = plotNumber;
}
public Byte getType() {
return type;
}
public void setType(Byte type) {
this.type = type;
}
public Byte getRole() {
return role;
}
public void setRole(Byte role) {
this.role = role;
}
private Byte role;
}
public static class Response {
private UUID preUserId;
private UUID requestId;
private String userName;
private String displayName;
private String dni;
private String phone;
private String email;
private String address;
private String zipCode;
private String city;
private Integer memberNumber;
private Integer plotNumber;
private Byte type;
private Byte role;
private Instant createdAt;
public UUID getPreUserId() {
return preUserId;
}
public void setPreUserId(UUID preUserId) {
this.preUserId = preUserId;
}
public UUID getRequestId() {
return requestId;
}
public void setRequestId(UUID requestId) {
this.requestId = requestId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Integer getMemberNumber() {
return memberNumber;
}
public void setMemberNumber(Integer memberNumber) {
this.memberNumber = memberNumber;
}
public Integer getPlotNumber() {
return plotNumber;
}
public void setPlotNumber(Integer plotNumber) {
this.plotNumber = plotNumber;
}
public Byte getType() {
return type;
}
public void setType(Byte type) {
this.type = type;
}
public Byte getRole() {
return role;
}
public void setRole(Byte role) {
this.role = role;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
}
}

View File

@@ -8,8 +8,8 @@ import java.util.UUID;
public class RequestDto { public class RequestDto {
public static class Request { public static class Request {
private Byte type; private Byte type;
private Byte status; private UUID userId;
private UUID requestedBy; private RequestMetadataDto metadata;
public Byte getType() { public Byte getType() {
return type; return type;
@@ -19,37 +19,30 @@ public class RequestDto {
this.type = type; this.type = type;
} }
public Byte getStatus() { public UUID getUserId() {
return status; return userId;
} }
public void setStatus(Byte status) { public void setUserId(UUID userId) {
this.status = status; this.userId = userId;
} }
public UUID getRequestedBy() { public RequestMetadataDto getMetadata() {
return requestedBy; return metadata;
} }
public void setRequestedBy(UUID requestedBy) { public void setMetadata(RequestMetadataDto metadata) {
this.requestedBy = requestedBy; this.metadata = metadata;
} }
public @Nullable UUID getTargetUserId() {
return targetUserId;
}
public void setTargetUserId(@Nullable UUID targetUserId) {
this.targetUserId = targetUserId;
}
@Nullable private UUID targetUserId;
} }
public static class Response { public static class Response {
private UUID requestId; private UUID requestId;
private Byte type; private Byte type;
private Byte status; private Byte status;
private UUID userId;
private RequestMetadataDto metadata;
private Instant createdAt;
public UUID getRequestId() { public UUID getRequestId() {
return requestId; return requestId;
@@ -75,20 +68,20 @@ public class RequestDto {
this.status = status; this.status = status;
} }
public UUID getRequestedBy() { public UUID getUserId() {
return requestedBy; return userId;
} }
public void setRequestedBy(UUID requestedBy) { public void setUserId(UUID userId) {
this.requestedBy = requestedBy; this.userId = userId;
} }
public UUID getTargetUserId() { public RequestMetadataDto getMetadata() {
return targetUserId; return metadata;
} }
public void setTargetUserId(UUID targetUserId) { public void setMetadata(RequestMetadataDto metadata) {
this.targetUserId = targetUserId; this.metadata = metadata;
} }
public Instant getCreatedAt() { public Instant getCreatedAt() {
@@ -98,9 +91,5 @@ public class RequestDto {
public void setCreatedAt(Instant createdAt) { public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt; this.createdAt = createdAt;
} }
private UUID requestedBy;
private UUID targetUserId;
private Instant createdAt;
} }
} }

View File

@@ -0,0 +1,15 @@
package net.miarma.backend.huertos.dto;
import java.time.Instant;
public record RequestMetadataDto(
Long id,
String name,
String dni,
String phone,
String email,
Integer memberNumber,
Integer plotNumber,
Instant createdAt
) {}

View File

@@ -0,0 +1,14 @@
package net.miarma.backend.huertos.dto;
import java.time.Instant;
import java.util.UUID;
public record RequestWithMetadataDto(
UUID requestId,
UUID userId,
Byte type,
Byte status,
Instant createdAt,
RequestMetadataDto metadata
) {}

View File

@@ -1,55 +0,0 @@
package net.miarma.backend.huertos.dto;
public class RequestWithPreUserDto {
public static class Request {
private RequestDto.Request request;
private PreUserDto.Request preUser;
public Request(RequestDto.Request request, PreUserDto.Request preUser) {
this.request = request;
this.preUser = preUser;
}
public RequestDto.Request getRequest() {
return request;
}
public void setRequest(RequestDto.Request request) {
this.request = request;
}
public PreUserDto.Request getPreUser() {
return preUser;
}
public void setPreUser(PreUserDto.Request preUser) {
this.preUser = preUser;
}
}
public static class Response {
private RequestDto.Response request;
private PreUserDto.Response preUser;
public RequestDto.Response getRequest() {
return request;
}
public void setRequest(RequestDto.Response request) {
this.request = request;
}
public PreUserDto.Response getPreUser() {
return preUser;
}
public void setPreUser(PreUserDto.Response preUser) {
this.preUser = preUser;
}
public Response(RequestDto.Response request, PreUserDto.Response preUser) {
this.request = request;
this.preUser = preUser;
}
}
}

View File

@@ -3,7 +3,7 @@ package net.miarma.backend.huertos.dto;
import java.time.Instant; import java.time.Instant;
import java.util.UUID; import java.util.UUID;
public class HuertosUserMetadataDto { public class UserMetadataDto {
private UUID userId; private UUID userId;
private Integer memberNumber; private Integer memberNumber;
private Integer plotNumber; private Integer plotNumber;

View File

@@ -1,151 +0,0 @@
package net.miarma.backend.huertos.dto.view;
import java.time.Instant;
import java.util.UUID;
public class VHuertosMembersDto {
private UUID userId;
private String displayName;
private String avatar;
private Integer memberNumber;
private Integer plotNumber;
private String dni;
private String phone;
private Byte type;
private Byte role;
private Byte credentialStatus;
private String notes;
private Instant createdAt;
private Instant assignedAt;
private Instant deactivatedAt;
private Byte serviceId;
private String serviceName;
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public Integer getMemberNumber() {
return memberNumber;
}
public void setMemberNumber(Integer memberNumber) {
this.memberNumber = memberNumber;
}
public Integer getPlotNumber() {
return plotNumber;
}
public void setPlotNumber(Integer plotNumber) {
this.plotNumber = plotNumber;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Byte getType() {
return type;
}
public void setType(Byte type) {
this.type = type;
}
public Byte getRole() {
return role;
}
public void setRole(Byte role) {
this.role = role;
}
public Byte getCredentialStatus() {
return credentialStatus;
}
public void setCredentialStatus(Byte credentialStatus) {
this.credentialStatus = credentialStatus;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
public Instant getAssignedAt() {
return assignedAt;
}
public void setAssignedAt(Instant assignedAt) {
this.assignedAt = assignedAt;
}
public Instant getDeactivatedAt() {
return deactivatedAt;
}
public void setDeactivatedAt(Instant deactivatedAt) {
this.deactivatedAt = deactivatedAt;
}
public Byte getServiceId() {
return serviceId;
}
public void setServiceId(Byte serviceId) {
this.serviceId = serviceId;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
}

View File

@@ -1,198 +0,0 @@
package net.miarma.backend.huertos.dto.view;
import java.time.Instant;
import java.util.UUID;
public class VRequestsWithPreUsersDto {
private UUID requestId;
private Byte requestType;
private Byte requestStatus;
private UUID requestedBy;
private String requestedByName;
private UUID targetUserId;
private Instant requestCreatedAt;
// PreUser fields
private UUID preUserId;
private String preUserName;
private String preDisplayName;
private String preDni;
private String prePhone;
private String preEmail;
private String preAddress;
private String preZipCode;
private String preCity;
private Integer preMemberNumber;
private Integer prePlotNumber;
private Byte preType;
private Byte preRole;
private Instant preCreatedAt;
public UUID getRequestId() {
return requestId;
}
public void setRequestId(UUID requestId) {
this.requestId = requestId;
}
public Byte getRequestType() {
return requestType;
}
public void setRequestType(Byte requestType) {
this.requestType = requestType;
}
public Byte getRequestStatus() {
return requestStatus;
}
public void setRequestStatus(Byte requestStatus) {
this.requestStatus = requestStatus;
}
public UUID getRequestedBy() {
return requestedBy;
}
public void setRequestedBy(UUID requestedBy) {
this.requestedBy = requestedBy;
}
public String getRequestedByName() {
return requestedByName;
}
public void setRequestedByName(String requestedByName) {
this.requestedByName = requestedByName;
}
public UUID getTargetUserId() {
return targetUserId;
}
public void setTargetUserId(UUID targetUserId) {
this.targetUserId = targetUserId;
}
public Instant getRequestCreatedAt() {
return requestCreatedAt;
}
public void setRequestCreatedAt(Instant requestCreatedAt) {
this.requestCreatedAt = requestCreatedAt;
}
public UUID getPreUserId() {
return preUserId;
}
public void setPreUserId(UUID preUserId) {
this.preUserId = preUserId;
}
public String getPreUserName() {
return preUserName;
}
public void setPreUserName(String preUserName) {
this.preUserName = preUserName;
}
public String getPreDisplayName() {
return preDisplayName;
}
public void setPreDisplayName(String preDisplayName) {
this.preDisplayName = preDisplayName;
}
public String getPreDni() {
return preDni;
}
public void setPreDni(String preDni) {
this.preDni = preDni;
}
public String getPrePhone() {
return prePhone;
}
public void setPrePhone(String prePhone) {
this.prePhone = prePhone;
}
public String getPreEmail() {
return preEmail;
}
public void setPreEmail(String preEmail) {
this.preEmail = preEmail;
}
public String getPreAddress() {
return preAddress;
}
public void setPreAddress(String preAddress) {
this.preAddress = preAddress;
}
public String getPreZipCode() {
return preZipCode;
}
public void setPreZipCode(String preZipCode) {
this.preZipCode = preZipCode;
}
public String getPreCity() {
return preCity;
}
public void setPreCity(String preCity) {
this.preCity = preCity;
}
public Integer getPreMemberNumber() {
return preMemberNumber;
}
public void setPreMemberNumber(Integer preMemberNumber) {
this.preMemberNumber = preMemberNumber;
}
public Integer getPrePlotNumber() {
return prePlotNumber;
}
public void setPrePlotNumber(Integer prePlotNumber) {
this.prePlotNumber = prePlotNumber;
}
public Byte getPreType() {
return preType;
}
public void setPreType(Byte preType) {
this.preType = preType;
}
public Byte getPreRole() {
return preRole;
}
public void setPreRole(Byte preRole) {
this.preRole = preRole;
}
public Instant getPreCreatedAt() {
return preCreatedAt;
}
public void setPreCreatedAt(Instant preCreatedAt) {
this.preCreatedAt = preCreatedAt;
}
}

View File

@@ -1,50 +0,0 @@
package net.miarma.backend.huertos.mapper;
import net.miarma.backend.huertos.dto.PreUserDto;
import net.miarma.backend.huertos.model.PreUser;
public class PreUserMapper {
public static PreUserDto.Response toResponse(PreUser entity) {
if (entity == null) return null;
PreUserDto.Response dto = new PreUserDto.Response();
dto.setPreUserId(entity.getPreUserId());
dto.setRequestId(entity.getRequestId());
dto.setUserName(entity.getUserName());
dto.setDisplayName(entity.getDisplayName());
dto.setDni(entity.getDni());
dto.setPhone(entity.getPhone());
dto.setEmail(entity.getEmail());
dto.setAddress(entity.getAddress());
dto.setZipCode(entity.getZipCode());
dto.setCity(entity.getCity());
dto.setMemberNumber(entity.getMemberNumber());
dto.setPlotNumber(entity.getPlotNumber());
dto.setType(entity.getType());
dto.setRole(entity.getRole());
dto.setCreatedAt(entity.getCreatedAt());
return dto;
}
public static PreUser toEntity(PreUserDto.Request dto) {
if (dto == null) return null;
PreUser entity = new PreUser();
entity.setRequestId(dto.getRequestId());
entity.setUserName(dto.getUserName());
entity.setDisplayName(dto.getDisplayName());
entity.setDni(dto.getDni());
entity.setPhone(dto.getPhone());
entity.setEmail(dto.getEmail());
entity.setPassword(dto.getPassword());
entity.setAddress(dto.getAddress());
entity.setZipCode(dto.getZipCode());
entity.setCity(dto.getCity());
entity.setMemberNumber(dto.getMemberNumber());
entity.setPlotNumber(dto.getPlotNumber());
entity.setType(dto.getType());
entity.setRole(dto.getRole());
return entity;
}
}

View File

@@ -1,8 +1,6 @@
package net.miarma.backend.huertos.mapper; package net.miarma.backend.huertos.mapper;
import net.miarma.backend.huertos.dto.RequestDto; import net.miarma.backend.huertos.dto.RequestDto;
import net.miarma.backend.huertos.dto.RequestWithPreUserDto;
import net.miarma.backend.huertos.model.PreUser;
import net.miarma.backend.huertos.model.Request; import net.miarma.backend.huertos.model.Request;
public class RequestMapper { public class RequestMapper {
@@ -14,29 +12,32 @@ public class RequestMapper {
dto.setRequestId(entity.getRequestId()); dto.setRequestId(entity.getRequestId());
dto.setType(entity.getType()); dto.setType(entity.getType());
dto.setStatus(entity.getStatus()); dto.setStatus(entity.getStatus());
dto.setRequestedBy(entity.getRequestedBy()); dto.setUserId(entity.getUserId());
dto.setTargetUserId(entity.getTargetUserId());
dto.setCreatedAt(entity.getCreatedAt()); dto.setCreatedAt(entity.getCreatedAt());
if (entity.getMetadata() != null) {
dto.setMetadata(
RequestMetadataMapper.toDto(entity.getMetadata())
);
}
return dto; return dto;
} }
public static RequestWithPreUserDto.Response toResponseWithPreUser(Request request, PreUser preUser) {
if (request == null || preUser == null) return null;
return new RequestWithPreUserDto.Response(
RequestMapper.toResponse(request),
PreUserMapper.toResponse(preUser)
);
}
public static Request toEntity(RequestDto.Request dto) { public static Request toEntity(RequestDto.Request dto) {
if (dto == null) return null; if (dto == null) return null;
Request entity = new Request(); Request entity = new Request();
entity.setType(dto.getType()); entity.setType(dto.getType());
entity.setStatus(dto.getStatus()); entity.setUserId(dto.getUserId());
entity.setRequestedBy(dto.getRequestedBy()); entity.setStatus((byte) 0);
entity.setTargetUserId(dto.getTargetUserId());
if (dto.getMetadata() != null) {
entity.setMetadata(
RequestMetadataMapper.fromDto(dto.getMetadata())
);
}
return entity; return entity;
} }
} }

View File

@@ -0,0 +1,34 @@
package net.miarma.backend.huertos.mapper;
import net.miarma.backend.huertos.dto.RequestMetadataDto;
import net.miarma.backend.huertos.model.RequestMetadata;
public class RequestMetadataMapper {
public static RequestMetadata fromDto(RequestMetadataDto dto) {
if (dto == null) return null;
RequestMetadata metadata = new RequestMetadata();
metadata.setName(dto.name());
metadata.setDni(dto.dni());
metadata.setPhone(dto.phone());
metadata.setMemberNumber(dto.memberNumber());
metadata.setPlotNumber(dto.plotNumber());
return metadata;
}
public static RequestMetadataDto toDto(RequestMetadata entity) {
if (entity == null) return null;
return new RequestMetadataDto(
entity.getId(),
entity.getName(),
entity.getDni(),
entity.getPhone(),
entity.getEmail(),
entity.getMemberNumber(),
entity.getPlotNumber(),
entity.getCreatedAt()
);
}
}

View File

@@ -0,0 +1,18 @@
package net.miarma.backend.huertos.mapper;
import net.miarma.backend.huertos.dto.RequestWithMetadataDto;
import net.miarma.backend.huertos.model.Request;
public class RequestWithMetadataMapper {
public static RequestWithMetadataDto toDto(Request r) {
if (r == null) return null;
return new RequestWithMetadataDto(
r.getRequestId(),
r.getUserId(),
r.getType(),
r.getStatus(),
r.getCreatedAt(),
RequestMetadataMapper.toDto(r.getMetadata())
);
}
}

View File

@@ -1,12 +1,12 @@
package net.miarma.backend.huertos.mapper; package net.miarma.backend.huertos.mapper;
import net.miarma.backend.huertos.dto.HuertosUserMetadataDto; import net.miarma.backend.huertos.dto.UserMetadataDto;
import net.miarma.backend.huertos.model.HuertosUserMetadata; import net.miarma.backend.huertos.model.UserMetadata;
public class HuertosUserMetadataMapper { public class UserMetadataMapper {
public static HuertosUserMetadataDto toDto(HuertosUserMetadata entity) { public static UserMetadataDto toDto(UserMetadata entity) {
HuertosUserMetadataDto dto = new HuertosUserMetadataDto(); UserMetadataDto dto = new UserMetadataDto();
dto.setUserId(entity.getUserId()); dto.setUserId(entity.getUserId());
dto.setMemberNumber(entity.getMemberNumber()); dto.setMemberNumber(entity.getMemberNumber());
dto.setPlotNumber(entity.getPlotNumber()); dto.setPlotNumber(entity.getPlotNumber());
@@ -21,8 +21,8 @@ public class HuertosUserMetadataMapper {
return dto; return dto;
} }
public static HuertosUserMetadata fromDto(HuertosUserMetadataDto dto) { public static UserMetadata fromDto(UserMetadataDto dto) {
HuertosUserMetadata entity = new HuertosUserMetadata(); UserMetadata entity = new UserMetadata();
entity.setUserId(dto.getUserId()); entity.setUserId(dto.getUserId());
entity.setMemberNumber(dto.getMemberNumber()); entity.setMemberNumber(dto.getMemberNumber());
entity.setPlotNumber(dto.getPlotNumber()); entity.setPlotNumber(dto.getPlotNumber());

View File

@@ -1,28 +0,0 @@
package net.miarma.backend.huertos.mapper.view;
import net.miarma.backend.huertos.dto.view.VHuertosMembersDto;
import net.miarma.backend.huertos.model.view.VHuertosMembers;
public class VHuertosMembersMapper {
public static VHuertosMembersDto toResponse(VHuertosMembers entity) {
VHuertosMembersDto dto = new VHuertosMembersDto();
dto.setUserId(entity.getUserId());
dto.setDisplayName(entity.getDisplayName());
dto.setAvatar(entity.getAvatar());
dto.setMemberNumber(entity.getMemberNumber());
dto.setPlotNumber(entity.getPlotNumber());
dto.setDni(entity.getDni());
dto.setPhone(entity.getPhone());
dto.setType(entity.getType());
dto.setRole(entity.getRole());
dto.setCredentialStatus(entity.getCredentialStatus());
dto.setNotes(entity.getNotes());
dto.setCreatedAt(entity.getCreatedAt());
dto.setAssignedAt(entity.getAssignedAt());
dto.setDeactivatedAt(entity.getDeactivatedAt());
dto.setServiceId(entity.getServiceId());
dto.setServiceName(entity.getServiceName());
return dto;
}
}

View File

@@ -1,35 +0,0 @@
package net.miarma.backend.huertos.mapper.view;
import net.miarma.backend.huertos.dto.view.VRequestsWithPreUsersDto;
import net.miarma.backend.huertos.model.view.VRequestsWithPreUsers;
public class VRequestsWithPreUsersMapper {
public static VRequestsWithPreUsersDto toResponse(VRequestsWithPreUsers entity) {
VRequestsWithPreUsersDto dto = new VRequestsWithPreUsersDto();
dto.setRequestId(entity.getRequestId());
dto.setRequestType(entity.getRequestType());
dto.setRequestStatus(entity.getRequestStatus());
dto.setRequestedBy(entity.getRequestedBy());
dto.setRequestedByName(entity.getRequestedByName());
dto.setTargetUserId(entity.getTargetUserId());
dto.setRequestCreatedAt(entity.getRequestCreatedAt());
dto.setPreUserId(entity.getPreUserId());
dto.setPreUserName(entity.getPreUserName());
dto.setPreDisplayName(entity.getPreDisplayName());
dto.setPreDni(entity.getPreDni());
dto.setPrePhone(entity.getPrePhone());
dto.setPreEmail(entity.getPreEmail());
dto.setPreAddress(entity.getPreAddress());
dto.setPreZipCode(entity.getPreZipCode());
dto.setPreCity(entity.getPreCity());
dto.setPreMemberNumber(entity.getPreMemberNumber());
dto.setPrePlotNumber(entity.getPrePlotNumber());
dto.setPreType(entity.getPreType());
dto.setPreRole(entity.getPreRole());
dto.setPreCreatedAt(entity.getPreCreatedAt());
return dto;
}
}

View File

@@ -1,218 +0,0 @@
package net.miarma.backend.huertos.model;
import java.time.Instant;
import java.util.UUID;
import jakarta.persistence.*;
import net.miarma.backlib.util.UuidUtil;
@Entity
@Table(name = "huertos_pre_users")
public class PreUser {
@Id
@Column(name = "pre_user_id", columnDefinition = "BINARY(16)")
private byte[] preUserIdBin;
@Transient
private UUID preUserId;
@Column(name = "request_id", columnDefinition = "BINARY(16)", nullable = false)
private byte[] requestIdBin;
@Transient
private UUID requestId;
@Column(name = "user_name", nullable = false, length = 64)
private String userName;
@Column(name = "display_name", nullable = false, length = 128)
private String displayName;
@Column(name = "dni", nullable = false, length = 9)
private String dni;
@Column(name = "phone", nullable = false, length = 20)
private String phone;
@Column(name = "email", nullable = false, length = 128)
private String email;
@Column(name = "password", length = 256)
private String password;
@Column(name = "address", length = 128)
private String address;
@Column(name = "zip_code", length = 10)
private String zipCode;
@Column(name = "city", length = 64)
private String city;
@Column(name = "member_number")
private Integer memberNumber;
@Column(name = "plot_number")
private Integer plotNumber;
@Column(name = "type", nullable = false)
private Byte type;
@Column(name = "role", nullable = false)
private Byte role;
@Column(name = "created_at", nullable = false)
private Instant createdAt;
@PrePersist
@PreUpdate
private void prePersist() {
if (preUserId != null) {
preUserIdBin = UuidUtil.uuidToBin(preUserId);
}
if (requestId != null) {
requestIdBin = UuidUtil.uuidToBin(requestId);
}
}
@PostLoad
private void postLoad() {
if (preUserIdBin != null) {
preUserId = UuidUtil.binToUUID(preUserIdBin);
}
if (requestIdBin != null) {
requestId = UuidUtil.binToUUID(requestIdBin);
}
}
public UUID getPreUserId() {
return preUserId;
}
public void setPreUserId(UUID preUserId) {
this.preUserId = preUserId;
}
public UUID getRequestId() {
return requestId;
}
public void setRequestId(UUID requestId) {
this.requestId = requestId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Integer getMemberNumber() {
return memberNumber;
}
public void setMemberNumber(Integer memberNumber) {
this.memberNumber = memberNumber;
}
public Integer getPlotNumber() {
return plotNumber;
}
public void setPlotNumber(Integer plotNumber) {
this.plotNumber = plotNumber;
}
public Byte getType() {
return type;
}
public void setType(Byte type) {
this.type = type;
}
public Byte getRole() {
return role;
}
public void setRole(Byte role) {
this.role = role;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
}

View File

@@ -9,64 +9,57 @@ import net.miarma.backlib.util.UuidUtil;
@Entity @Entity
@Table(name = "huertos_requests") @Table(name = "huertos_requests")
public class Request { public class Request {
@Id @Id
@Column(name = "request_id", columnDefinition = "BINARY(16)") @Column(name = "request_id", columnDefinition = "BINARY(16)")
private byte[] requestIdBin; private byte[] requestIdBin;
@Transient @Transient
private UUID requestId; private UUID requestId;
@Column(name = "type", nullable = false) @Column(name = "user_id", columnDefinition = "BINARY(16)")
private Byte type; private byte[] userIdBin; // usuario que hace la solicitud (puede ser null si anon)
@Column(name = "status", nullable = false)
private Byte status;
@Column(name = "requested_by", columnDefinition = "BINARY(16)")
private byte[] requestedByBin;
@Transient @Transient
private UUID requestedBy; private UUID userId;
@Column(name = "target_user_id", columnDefinition = "BINARY(16)") @Column(name = "type", nullable = false)
private byte[] targetUserIdBin; private Byte type;
@Transient @Column(name = "status", nullable = false)
private UUID targetUserId; private Byte status;
@Column(name = "created_at", nullable = false) @Column(name = "created_at", nullable = false)
private Instant createdAt; private Instant createdAt;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "metadata_id")
private RequestMetadata metadata;
@PrePersist @PrePersist
@PreUpdate
private void prePersist() { private void prePersist() {
if (requestId != null) { if (requestId != null) {
requestIdBin = UuidUtil.uuidToBin(requestId); requestIdBin = net.miarma.backlib.util.UuidUtil.uuidToBin(requestId);
}
if (requestedBy != null) {
requestedByBin = UuidUtil.uuidToBin(requestedBy);
}
if (targetUserId != null) {
targetUserIdBin = UuidUtil.uuidToBin(targetUserId);
} }
createdAt = Instant.now();
} }
@PostLoad @PostLoad
private void postLoad() { private void postLoad() {
if (requestIdBin != null) { if (requestIdBin != null) {
requestId = UuidUtil.binToUUID(requestIdBin); requestId = net.miarma.backlib.util.UuidUtil.binToUUID(requestIdBin);
} }
if (userIdBin != null) {
userId = net.miarma.backlib.util.UuidUtil.binToUUID(userIdBin);
}
}
if (requestedByBin != null) { public byte[] getRequestIdBin() {
requestedBy = UuidUtil.binToUUID(requestedByBin); return requestIdBin;
} }
if (targetUserIdBin != null) { public void setRequestIdBin(byte[] requestIdBin) {
targetUserId = UuidUtil.binToUUID(targetUserIdBin); this.requestIdBin = requestIdBin;
}
} }
public UUID getRequestId() { public UUID getRequestId() {
@@ -77,6 +70,22 @@ public class Request {
this.requestId = requestId; this.requestId = requestId;
} }
public byte[] getUserIdBin() {
return userIdBin;
}
public void setUserIdBin(byte[] userIdBin) {
this.userIdBin = userIdBin;
}
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public Byte getType() { public Byte getType() {
return type; return type;
} }
@@ -93,22 +102,6 @@ public class Request {
this.status = status; this.status = status;
} }
public UUID getRequestedBy() {
return requestedBy;
}
public void setRequestedBy(UUID requestedBy) {
this.requestedBy = requestedBy;
}
public UUID getTargetUserId() {
return targetUserId;
}
public void setTargetUserId(UUID targetUserId) {
this.targetUserId = targetUserId;
}
public Instant getCreatedAt() { public Instant getCreatedAt() {
return createdAt; return createdAt;
} }
@@ -116,5 +109,12 @@ public class Request {
public void setCreatedAt(Instant createdAt) { public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt; this.createdAt = createdAt;
} }
public RequestMetadata getMetadata() {
return metadata;
}
public void setMetadata(RequestMetadata metadata) {
this.metadata = metadata;
}
} }

View File

@@ -0,0 +1,93 @@
package net.miarma.backend.huertos.model;
import jakarta.persistence.*;
import java.time.Instant;
@Entity
@Table(name = "huertos_request_metadata")
public class RequestMetadata {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String dni;
private String phone;
private String email;
private Integer memberNumber;
private Integer plotNumber;
private Instant createdAt;
@PrePersist
private void prePersist() {
createdAt = Instant.now();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDni() {
return dni;
}
public void setDni(String dni) {
this.dni = dni;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getMemberNumber() {
return memberNumber;
}
public void setMemberNumber(Integer memberNumber) {
this.memberNumber = memberNumber;
}
public Integer getPlotNumber() {
return plotNumber;
}
public void setPlotNumber(Integer plotNumber) {
this.plotNumber = plotNumber;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
}

View File

@@ -8,9 +8,9 @@ import net.miarma.backlib.util.UuidUtil;
@Entity @Entity
@Table(name = "huertos_user_metadata") @Table(name = "huertos_user_metadata")
public class HuertosUserMetadata { public class UserMetadata {
@Id @Id
@Column(name = "user_id", columnDefinition = "BINARY(16)") @Column(name = "user_id", columnDefinition = "BINARY(16)")
private byte[] userIdBin; private byte[] userIdBin;
@@ -150,4 +150,8 @@ public class HuertosUserMetadata {
public void setDeactivatedAt(Instant deactivatedAt) { public void setDeactivatedAt(Instant deactivatedAt) {
this.deactivatedAt = deactivatedAt; this.deactivatedAt = deactivatedAt;
} }
public void setUserIdBin(byte[] userIdBin) {
this.userIdBin = userIdBin;
}
} }

View File

@@ -1,128 +0,0 @@
package net.miarma.backend.huertos.model.view;
import jakarta.persistence.*;
import net.miarma.backlib.util.UuidUtil;
import org.hibernate.annotations.Immutable;
import java.time.Instant;
import java.util.UUID;
@Entity
@Immutable
@Table(name = "v_huertos_members")
public class VHuertosMembers {
@Id
@Column(name = "user_id", columnDefinition = "BINARY(16)")
private byte[] userIdBin;
@Transient
private UUID userId;
@Column(name = "display_name")
private String displayName;
private String avatar;
@Column(name = "member_number")
private Integer memberNumber;
@Column(name = "plot_number")
private Integer plotNumber;
private String dni;
private String phone;
private Byte type;
private Byte role;
@Column(name = "status")
private Byte credentialStatus;
private String notes;
@Column(name = "created_at")
private Instant createdAt;
@Column(name = "assigned_at")
private Instant assignedAt;
@Column(name = "deactivated_at")
private Instant deactivatedAt;
@Column(name = "service_id")
private Byte serviceId;
@Column(name = "service_name")
private String serviceName;
@PostLoad
private void postLoad() {
if (userIdBin != null) {
userId = UuidUtil.binToUUID(userIdBin);
}
}
public UUID getUserId() {
return userId;
}
public String getDisplayName() {
return displayName;
}
public String getAvatar() {
return avatar;
}
public Integer getMemberNumber() {
return memberNumber;
}
public Integer getPlotNumber() {
return plotNumber;
}
public String getDni() {
return dni;
}
public String getPhone() {
return phone;
}
public Byte getType() {
return type;
}
public Byte getRole() {
return role;
}
public Byte getCredentialStatus() {
return credentialStatus;
}
public String getNotes() {
return notes;
}
public Instant getCreatedAt() {
return createdAt;
}
public Instant getAssignedAt() {
return assignedAt;
}
public Instant getDeactivatedAt() {
return deactivatedAt;
}
public Byte getServiceId() {
return serviceId;
}
public String getServiceName() {
return serviceName;
}
}

View File

@@ -1,194 +0,0 @@
package net.miarma.backend.huertos.model.view;
import jakarta.persistence.*;
import net.miarma.backlib.util.UuidUtil;
import org.hibernate.annotations.Immutable;
import java.time.Instant;
import java.util.UUID;
@Entity
@Immutable
@Table(name = "v_requests_with_pre_users")
public class VRequestsWithPreUsers {
@Id
@Column(name = "request_id", columnDefinition = "BINARY(16)")
private byte[] requestIdBin;
@Transient
private UUID requestId;
@Column(name = "request_type")
private Byte requestType;
@Column(name = "request_status")
private Byte requestStatus;
@Column(name = "requested_by", columnDefinition = "BINARY(16)")
private byte[] requestedByBin;
@Transient
private UUID requestedBy;
@Column(name = "requested_by_name")
private String requestedByName;
@Column(name = "target_user_id", columnDefinition = "BINARY(16)")
private byte[] targetUserIdBin;
@Transient
private UUID targetUserId;
@Column(name = "request_created_at")
private Instant requestCreatedAt;
// --- PreUser ---
@Column(name = "pre_user_id", columnDefinition = "BINARY(16)")
private byte[] preUserIdBin;
@Transient
private UUID preUserId;
@Column(name = "pre_user_name")
private String preUserName;
@Column(name = "pre_display_name")
private String preDisplayName;
@Column(name = "pre_dni")
private String preDni;
@Column(name = "pre_phone")
private String prePhone;
@Column(name = "pre_email")
private String preEmail;
@Column(name = "pre_address")
private String preAddress;
@Column(name = "pre_zip_code")
private String preZipCode;
@Column(name = "pre_city")
private String preCity;
@Column(name = "pre_member_number")
private Integer preMemberNumber;
@Column(name = "pre_plot_number")
private Integer prePlotNumber;
@Column(name = "pre_type")
private Byte preType;
@Column(name = "pre_role")
private Byte preRole;
@Column(name = "pre_created_at")
private Instant preCreatedAt;
@PostLoad
private void postLoad() {
if (requestIdBin != null) {
requestId = UuidUtil.binToUUID(requestIdBin);
}
if (requestedByBin != null) {
requestedBy = UuidUtil.binToUUID(requestedByBin);
}
if (targetUserIdBin != null) {
targetUserId = UuidUtil.binToUUID(targetUserIdBin);
}
if (preUserIdBin != null) {
preUserId = UuidUtil.binToUUID(preUserIdBin);
}
}
public UUID getRequestId() {
return requestId;
}
public Byte getRequestType() {
return requestType;
}
public Byte getRequestStatus() {
return requestStatus;
}
public UUID getRequestedBy() {
return requestedBy;
}
public String getRequestedByName() {
return requestedByName;
}
public UUID getTargetUserId() {
return targetUserId;
}
public Instant getRequestCreatedAt() {
return requestCreatedAt;
}
public UUID getPreUserId() {
return preUserId;
}
public String getPreUserName() {
return preUserName;
}
public String getPreDisplayName() {
return preDisplayName;
}
public String getPreDni() {
return preDni;
}
public String getPrePhone() {
return prePhone;
}
public String getPreEmail() {
return preEmail;
}
public String getPreAddress() {
return preAddress;
}
public String getPreZipCode() {
return preZipCode;
}
public String getPreCity() {
return preCity;
}
public Integer getPreMemberNumber() {
return preMemberNumber;
}
public Integer getPrePlotNumber() {
return prePlotNumber;
}
public Byte getPreType() {
return preType;
}
public Byte getPreRole() {
return preRole;
}
public Instant getPreCreatedAt() {
return preCreatedAt;
}
}

View File

@@ -1,10 +0,0 @@
package net.miarma.backend.huertos.repository;
import net.miarma.backend.huertos.model.HuertosUserMetadata;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface HuertosUserMetadataRepository extends JpaRepository<HuertosUserMetadata, byte[]> {
Optional<HuertosUserMetadata> findByMemberNumber(Integer memberNumber);
}

View File

@@ -1,10 +0,0 @@
package net.miarma.backend.huertos.repository;
import net.miarma.backend.huertos.model.PreUser;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PreUserRepository extends JpaRepository<PreUser, byte[]> {
boolean existsByDni(String dni);
boolean existsByEmail(String email);
}

View File

@@ -0,0 +1,7 @@
package net.miarma.backend.huertos.repository;
import net.miarma.backend.huertos.model.RequestMetadata;
import org.springframework.data.jpa.repository.JpaRepository;
public interface RequestMetadataRepository extends JpaRepository<RequestMetadata, Long> {
}

View File

@@ -0,0 +1,10 @@
package net.miarma.backend.huertos.repository;
import net.miarma.backend.huertos.model.UserMetadata;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserMetadataRepository extends JpaRepository<UserMetadata, byte[]> {
Optional<UserMetadata> findByMemberNumber(Integer memberNumber);
}

View File

@@ -1,12 +0,0 @@
package net.miarma.backend.huertos.repository.view;
import net.miarma.backend.huertos.model.view.VHuertosMembers;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
public interface VHuertosMembersRepository extends Repository<VHuertosMembers, byte[]> {
List<VHuertosMembers> findAll();
Optional<VHuertosMembers> findById(byte[] userId);
}

View File

@@ -1,12 +0,0 @@
package net.miarma.backend.huertos.repository.view;
import net.miarma.backend.huertos.model.view.VRequestsWithPreUsers;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
public interface VRequestsWithPreUsersRepository extends Repository<VRequestsWithPreUsers, byte[]> {
List<VRequestsWithPreUsers> findAll();
Optional<VRequestsWithPreUsers> findById(byte[] requestId);
}

View File

@@ -4,8 +4,8 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import net.miarma.backend.huertos.model.view.VHuertosMembers; import net.miarma.backend.huertos.model.UserMetadata;
import net.miarma.backend.huertos.service.view.VHuertosMembersService; import net.miarma.backend.huertos.service.UserMetadataService;
import net.miarma.backlib.security.JwtService; import net.miarma.backlib.security.JwtService;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
@@ -19,11 +19,11 @@ import java.util.UUID;
public class HuertosJwtFilter extends OncePerRequestFilter { public class HuertosJwtFilter extends OncePerRequestFilter {
private final JwtService jwtService; private final JwtService jwtService;
private final VHuertosMembersService huertosUserService; private final UserMetadataService metadataService;
public HuertosJwtFilter(JwtService jwtService, VHuertosMembersService huertosUserService) { public HuertosJwtFilter(JwtService jwtService, UserMetadataService metadataService) {
this.jwtService = jwtService; this.jwtService = jwtService;
this.huertosUserService = huertosUserService; this.metadataService = metadataService;
} }
@Override @Override
@@ -39,13 +39,13 @@ public class HuertosJwtFilter extends OncePerRequestFilter {
UUID userId = jwtService.getUserId(token); UUID userId = jwtService.getUserId(token);
Byte serviceId = jwtService.getServiceId(token); Byte serviceId = jwtService.getServiceId(token);
VHuertosMembers huertosUser = huertosUserService.getById(userId); UserMetadata metadata = metadataService.getById(userId);
if (huertosUser != null) { if (metadata != null) {
var principal = new HuertosPrincipal( var principal = new HuertosPrincipal(
userId, userId,
huertosUser.getRole(), metadata.getRole(),
huertosUser.getType(), metadata.getType(),
serviceId serviceId
); );

View File

@@ -31,7 +31,7 @@ public class AnnouncementService {
public Announcement getById(UUID announceId) { public Announcement getById(UUID announceId) {
byte[] idBytes = UuidUtil.uuidToBin(announceId); byte[] idBytes = UuidUtil.uuidToBin(announceId);
return announcementRepository.findById(idBytes) return announcementRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Announcement not found")); .orElseThrow(() -> new NotFoundException("Anuncio no encontrado"));
} }
public Announcement create(Announcement announcement) { public Announcement create(Announcement announcement) {
@@ -43,14 +43,17 @@ public class AnnouncementService {
return announcementRepository.save(announcement); return announcementRepository.save(announcement);
} }
public Announcement update(UUID announceId, AnnouncementDto.Request dto) { public Announcement update(UUID announceId, Announcement changes) {
byte[] idBytes = UuidUtil.uuidToBin(announceId); Announcement announcement = getById(announceId);
Announcement announcement = announcementRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Announcement not found"));
if (dto.getBody() != null) announcement.setBody(dto.getBody()); if (changes.getBody() != null)
if (dto.getPriority() != null) announcement.setPriority(dto.getPriority()); announcement.setBody(changes.getBody());
if (dto.getPublishedBy() != null) announcement.setPublishedBy(dto.getPublishedBy());
if (changes.getPriority() != null)
announcement.setPriority(changes.getPriority());
if (changes.getPublishedBy() != null)
announcement.setPublishedBy(changes.getPublishedBy());
return announcementRepository.save(announcement); return announcementRepository.save(announcement);
} }
@@ -58,7 +61,7 @@ public class AnnouncementService {
public void delete(UUID announceId) { public void delete(UUID announceId) {
byte[] idBytes = UuidUtil.uuidToBin(announceId); byte[] idBytes = UuidUtil.uuidToBin(announceId);
if (!announcementRepository.existsById(idBytes)) if (!announcementRepository.existsById(idBytes))
throw new NotFoundException("Announcement not found"); throw new NotFoundException("Anuncio no encontrado");
announcementRepository.deleteById(idBytes); announcementRepository.deleteById(idBytes);
} }
} }

View File

@@ -26,17 +26,17 @@ public class BalanceService {
public Balance get() { public Balance get() {
return balanceRepository.findById((byte) 1) return balanceRepository.findById((byte) 1)
.orElseThrow(() -> new NotFoundException("Balance not found")); .orElseThrow(() -> new NotFoundException("Balance no encontrado"));
} }
public VBalanceWithTotals getWithTotals() { public VBalanceWithTotals getWithTotals() {
return vBalanceWithTotalsRepository.findById((byte) 1) return vBalanceWithTotalsRepository.findById((byte) 1)
.orElseThrow(() -> new NotFoundException("Balance not found")); .orElseThrow(() -> new NotFoundException("Balance no encontrado"));
} }
public Balance create(Balance balance) { public Balance create(Balance balance) {
if (balanceRepository.existsById((byte) 1)) { if (balanceRepository.existsById((byte) 1)) {
throw new ConflictException("Balance already exists"); throw new ConflictException("Ya hay un valor de balance en la base de datos");
} }
balance.setId((byte) 1); balance.setId((byte) 1);
balance.setCreatedAt(Instant.now()); balance.setCreatedAt(Instant.now());
@@ -45,7 +45,7 @@ public class BalanceService {
public Balance update(Balance dto) { public Balance update(Balance dto) {
Balance balance = balanceRepository.findById((byte) 1) Balance balance = balanceRepository.findById((byte) 1)
.orElseThrow(() -> new NotFoundException("Balance not found")); .orElseThrow(() -> new NotFoundException("Balance no encontrado"));
if (dto.getInitialBank() != null) balance.setInitialBank(dto.getInitialBank()); if (dto.getInitialBank() != null) balance.setInitialBank(dto.getInitialBank());
if (dto.getInitialCash() != null) balance.setInitialCash(dto.getInitialCash()); if (dto.getInitialCash() != null) balance.setInitialCash(dto.getInitialCash());
@@ -55,7 +55,7 @@ public class BalanceService {
public void delete() { public void delete() {
if (!balanceRepository.existsById((byte) 1)) { if (!balanceRepository.existsById((byte) 1)) {
throw new NotFoundException("Balance not found"); throw new NotFoundException("Balance no encontrado");
} }
balanceRepository.deleteById((byte) 1); balanceRepository.deleteById((byte) 1);
} }

View File

@@ -30,21 +30,21 @@ public class ExpenseService {
public Expense getById(UUID expenseId) { public Expense getById(UUID expenseId) {
byte[] idBytes = UuidUtil.uuidToBin(expenseId); byte[] idBytes = UuidUtil.uuidToBin(expenseId);
return expenseRepository.findById(idBytes) return expenseRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Expense not found")); .orElseThrow(() -> new NotFoundException("Gasto no encontrado"));
} }
public Expense create(Expense expense) { public Expense create(Expense expense) {
if (expense.getConcept() == null || expense.getConcept().isBlank()) { if (expense.getConcept() == null || expense.getConcept().isBlank()) {
throw new ValidationException("concept", "Concept is required"); throw new ValidationException("concept", "El concepto es obligatorio");
} }
if (expense.getAmount() == null) { if (expense.getAmount() == null) {
throw new ValidationException("amount", "Amount is required"); throw new ValidationException("amount", "La cantidad es obligatoria");
} }
if (expense.getSupplier() == null || expense.getSupplier().isBlank()) { if (expense.getSupplier() == null || expense.getSupplier().isBlank()) {
throw new ValidationException("supplier", "Supplier is required"); throw new ValidationException("supplier", "El proveedor es obligatorio");
} }
if (expense.getInvoice() == null || expense.getInvoice().isBlank()) { if (expense.getInvoice() == null || expense.getInvoice().isBlank()) {
throw new ValidationException("invoice", "Invoice is required"); throw new ValidationException("invoice", "La factura es obligatoria");
} }
expense.setExpenseId(UUID.randomUUID()); expense.setExpenseId(UUID.randomUUID());
@@ -53,16 +53,26 @@ public class ExpenseService {
return expenseRepository.save(expense); return expenseRepository.save(expense);
} }
public Expense update(UUID expenseId, ExpenseDto.Request dto) { public Expense update(UUID expenseId, Expense changes) {
byte[] idBytes = UuidUtil.uuidToBin(expenseId); byte[] idBytes = UuidUtil.uuidToBin(expenseId);
Expense expense = expenseRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Expense not found"));
if (dto.getConcept() != null) expense.setConcept(dto.getConcept()); Expense expense = expenseRepository.findById(idBytes)
if (dto.getAmount() != null) expense.setAmount(dto.getAmount()); .orElseThrow(() -> new NotFoundException("Gasto no encontrado"));
if (dto.getSupplier() != null) expense.setSupplier(dto.getSupplier());
if (dto.getInvoice() != null) expense.setInvoice(dto.getInvoice()); if (changes.getConcept() != null)
if (dto.getType() != null) expense.setType(dto.getType()); expense.setConcept(changes.getConcept());
if (changes.getAmount() != null)
expense.setAmount(changes.getAmount());
if (changes.getSupplier() != null)
expense.setSupplier(changes.getSupplier());
if (changes.getInvoice() != null)
expense.setInvoice(changes.getInvoice());
if (changes.getType() != null)
expense.setType(changes.getType());
return expenseRepository.save(expense); return expenseRepository.save(expense);
} }
@@ -70,7 +80,7 @@ public class ExpenseService {
public void delete(UUID expenseId) { public void delete(UUID expenseId) {
byte[] idBytes = UuidUtil.uuidToBin(expenseId); byte[] idBytes = UuidUtil.uuidToBin(expenseId);
if (!expenseRepository.existsById(idBytes)) { if (!expenseRepository.existsById(idBytes)) {
throw new NotFoundException("Expense not found"); throw new NotFoundException("Gasto no encontrado");
} }
expenseRepository.deleteById(idBytes); expenseRepository.deleteById(idBytes);
} }

View File

@@ -1,110 +0,0 @@
package net.miarma.backend.huertos.service;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import net.miarma.backlib.exception.BadRequestException;
import net.miarma.backlib.exception.ConflictException;
import net.miarma.backlib.exception.NotFoundException;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.model.HuertosUserMetadata;
import net.miarma.backend.huertos.repository.HuertosUserMetadataRepository;
import net.miarma.backlib.util.UuidUtil;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Service
@Transactional
public class HuertosUserMetadataService {
private final HuertosUserMetadataRepository repository;
public HuertosUserMetadataService(HuertosUserMetadataRepository repository) {
this.repository = repository;
}
public List<HuertosUserMetadata> getAll() {
return repository.findAll();
}
public HuertosUserMetadata getById(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
return repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("User metadata not found"));
}
public HuertosUserMetadata getByMemberNumber(Integer memberNumber) {
return repository.findByMemberNumber(memberNumber)
.orElseThrow(() -> new NotFoundException("User metadata not found"));
}
public boolean existsById(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
return repository.existsById(idBytes);
}
public HuertosUserMetadata create(HuertosUserMetadata meta) {
if (meta.getUserId() == null) {
throw new BadRequestException("userId is required");
}
if (repository.existsById(UuidUtil.uuidToBin(meta.getUserId()))) {
throw new ConflictException("Metadata already exists for this user");
}
if (meta.getMemberNumber() == null) throw new BadRequestException("memberNumber required");
if (meta.getPlotNumber() == null) throw new BadRequestException("plotNumber required");
if (meta.getDni() == null || meta.getDni().isBlank()) throw new BadRequestException("dni required");
if (meta.getPhone() == null || meta.getPhone().isBlank()) throw new BadRequestException("phone required");
if (meta.getType() == null) meta.setType((byte) 0);
if (meta.getRole() == null) meta.setRole((byte) 0);
meta.setCreatedAt(Instant.now());
meta.setAssignedAt(null);
meta.setDeactivatedAt(null);
return repository.save(meta);
}
public HuertosUserMetadata update(UUID userId, HuertosUserMetadata dto) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
HuertosUserMetadata meta = repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("User metadata not found"));
if (dto.getMemberNumber() != null) meta.setMemberNumber(dto.getMemberNumber());
if (dto.getPlotNumber() != null) meta.setPlotNumber(dto.getPlotNumber());
if (dto.getDni() != null) meta.setDni(dto.getDni());
if (dto.getPhone() != null) meta.setPhone(dto.getPhone());
if (dto.getType() != null) meta.setType(dto.getType());
if (dto.getRole() != null) meta.setRole(dto.getRole());
if (dto.getNotes() != null) meta.setNotes(dto.getNotes());
if (dto.getAssignedAt() != null) meta.setAssignedAt(dto.getAssignedAt());
if (dto.getDeactivatedAt() != null) meta.setDeactivatedAt(dto.getDeactivatedAt());
return repository.save(meta);
}
public void delete(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
if (!repository.existsById(idBytes)) {
throw new NotFoundException("User metadata not found");
}
repository.deleteById(idBytes);
}
public Integer getLatestMemberNumber() {
return repository.findAll()
.stream()
.map(HuertosUserMetadata::getMemberNumber)
.max(Integer::compareTo)
.get();
}
public Boolean existsByMemberNumber(Integer memberNumber) {
return getByMemberNumber(memberNumber).getUserId() != null;
}
}

View File

@@ -4,9 +4,6 @@ import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import net.miarma.backend.huertos.dto.IncomeDto;
import net.miarma.backend.huertos.model.HuertosUserMetadata;
import net.miarma.backend.huertos.repository.HuertosUserMetadataRepository;
import net.miarma.backlib.exception.BadRequestException; import net.miarma.backlib.exception.BadRequestException;
import net.miarma.backlib.exception.NotFoundException; import net.miarma.backlib.exception.NotFoundException;
import net.miarma.backlib.exception.ValidationException; import net.miarma.backlib.exception.ValidationException;
@@ -22,10 +19,10 @@ import net.miarma.backlib.util.UuidUtil;
public class IncomeService { public class IncomeService {
private final IncomeRepository incomeRepository; private final IncomeRepository incomeRepository;
private final HuertosUserMetadataService metadataService; private final UserMetadataService metadataService;
public IncomeService(IncomeRepository incomeRepository, public IncomeService(IncomeRepository incomeRepository,
HuertosUserMetadataService metadataService) { UserMetadataService metadataService) {
this.incomeRepository = incomeRepository; this.incomeRepository = incomeRepository;
this.metadataService = metadataService; this.metadataService = metadataService;
} }
@@ -37,7 +34,7 @@ public class IncomeService {
public Income getById(UUID incomeId) { public Income getById(UUID incomeId) {
byte[] idBytes = UuidUtil.uuidToBin(incomeId); byte[] idBytes = UuidUtil.uuidToBin(incomeId);
return incomeRepository.findById(idBytes) return incomeRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Income not found")); .orElseThrow(() -> new NotFoundException("Ingreso no encontrado"));
} }
public List<Income> getByUserId(UUID userId) { public List<Income> getByUserId(UUID userId) {
@@ -48,13 +45,13 @@ public class IncomeService {
public Income create(Income income) { public Income create(Income income) {
if (income.getUserId() == null) { if (income.getUserId() == null) {
throw new BadRequestException("userId is required"); throw new BadRequestException("El identificador de usuario es obligatorio");
} }
if (income.getConcept() == null || income.getConcept().isBlank()) { if (income.getConcept() == null || income.getConcept().isBlank()) {
throw new BadRequestException("concept is required"); throw new BadRequestException("El concepto es obligatorio");
} }
if (income.getAmount() == null || income.getAmount().signum() <= 0) { if (income.getAmount() == null || income.getAmount().signum() <= 0) {
throw new ValidationException("amount", "amount must be positive"); throw new ValidationException("amount", "La cantidad debe ser positiva");
} }
income.setIncomeId(UUID.randomUUID()); income.setIncomeId(UUID.randomUUID());
@@ -63,21 +60,21 @@ public class IncomeService {
return incomeRepository.save(income); return incomeRepository.save(income);
} }
public Income update(UUID incomeId, IncomeDto.Request dto) { public Income update(UUID incomeId, Income changes) {
byte[] idBytes = UuidUtil.uuidToBin(incomeId); byte[] idBytes = UuidUtil.uuidToBin(incomeId);
Income income = incomeRepository.findById(idBytes) Income income = incomeRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Income not found")); .orElseThrow(() -> new NotFoundException("Ingreso no encontrado"));
if (dto.getConcept() != null) income.setConcept(dto.getConcept()); if (changes.getConcept() != null) income.setConcept(changes.getConcept());
if (dto.getAmount() != null) { if (changes.getAmount() != null) {
if (dto.getAmount().signum() <= 0) { if (changes.getAmount().signum() <= 0) {
throw new ValidationException("amount", "amount must be positive"); throw new ValidationException("amount", "La cantidad debe ser positiva");
} }
income.setAmount(dto.getAmount()); income.setAmount(changes.getAmount());
} }
if (dto.getType() != null) income.setType(dto.getType()); if (changes.getType() != null) income.setType(changes.getType());
if (dto.getFrequency() != null) income.setFrequency(dto.getFrequency()); if (changes.getFrequency() != null) income.setFrequency(changes.getFrequency());
return incomeRepository.save(income); return incomeRepository.save(income);
} }
@@ -86,7 +83,7 @@ public class IncomeService {
byte[] idBytes = UuidUtil.uuidToBin(incomeId); byte[] idBytes = UuidUtil.uuidToBin(incomeId);
if (!incomeRepository.existsById(idBytes)) { if (!incomeRepository.existsById(idBytes)) {
throw new NotFoundException("Income not found"); throw new NotFoundException("Ingreso no encontrado");
} }
incomeRepository.deleteById(idBytes); incomeRepository.deleteById(idBytes);

View File

@@ -1,163 +1,192 @@
package net.miarma.backend.huertos.service; package net.miarma.backend.huertos.service;
import net.miarma.backend.huertos.client.HuertosWebClient; import net.miarma.backend.huertos.client.HuertosWebClient;
import net.miarma.backend.huertos.dto.IncomeDto; import net.miarma.backend.huertos.dto.*;
import net.miarma.backend.huertos.dto.MemberDto; import net.miarma.backend.huertos.mapper.RequestMapper;
import net.miarma.backend.huertos.dto.WaitlistCensoredDto; import net.miarma.backend.huertos.mapper.UserMetadataMapper;
import net.miarma.backend.huertos.mapper.HuertosUserMetadataMapper; import net.miarma.backend.huertos.mapper.IncomeMapper;
import net.miarma.backend.huertos.mapper.IncomeMapper; import net.miarma.backend.huertos.security.NameCensorer;
import net.miarma.backend.huertos.security.NameCensorer; import net.miarma.backlib.dto.UserWithCredentialDto;
import net.miarma.backlib.dto.UserWithCredentialDto; import net.miarma.backlib.exception.NotFoundException;
import net.miarma.backlib.exception.NotFoundException; import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.Predicate;
@Service @Service
public class MemberService { public class MemberService {
private final HuertosWebClient huertosWebClient; private final HuertosWebClient huertosWebClient;
private final IncomeService incomeService; private final IncomeService incomeService;
private final RequestService requestService; private final RequestService requestService;
private final HuertosUserMetadataService metadataService; private final UserMetadataService metadataService;
public MemberService(HuertosWebClient huertosWebClient, public MemberService(HuertosWebClient huertosWebClient,
IncomeService incomeService, IncomeService incomeService,
RequestService requestService, RequestService requestService,
HuertosUserMetadataService metadataService) { UserMetadataService metadataService) {
this.huertosWebClient = huertosWebClient; this.huertosWebClient = huertosWebClient;
this.incomeService = incomeService; this.incomeService = incomeService;
this.requestService = requestService; this.requestService = requestService;
this.metadataService = metadataService; this.metadataService = metadataService;
}
public MemberDto getById(UUID userId) {
var uwc = huertosWebClient.getUserWithCredential(userId, (byte)1);
if (uwc == null) {
throw new NotFoundException("User not found in core");
} }
var meta = metadataService.getById(userId); @Cacheable(value = "memberById")
if (meta == null) { public MemberDto getById(UUID userId) {
throw new NotFoundException("User metadata not found"); var uwc = huertosWebClient.getUserWithCredential(userId, (byte)1);
} if (uwc == null) {
throw new NotFoundException("Socio no encontrado");
}
return new MemberDto( var meta = metadataService.getById(userId);
uwc.user(), if (meta == null) {
uwc.account(), throw new NotFoundException("User metadata not found");
HuertosUserMetadataMapper.toDto(meta) }
);
}
public List<MemberDto> getAll(Byte serviceId) { return new MemberDto(
List<UserWithCredentialDto> all = huertosWebClient.getAllUsersWithCredentials(serviceId);
return all.stream()
.filter(uwc -> metadataService.existsById(uwc.user().getUserId()))
.map(uwc -> {
var meta = metadataService.getById(uwc.user().getUserId());
return new MemberDto(
uwc.user(), uwc.user(),
uwc.account(), uwc.account(),
HuertosUserMetadataMapper.toDto(meta) UserMetadataMapper.toDto(meta)
); );
}) }
.toList();
}
public Integer getLatestMemberNumber() { @Cacheable("members")
return metadataService.getLatestMemberNumber(); public List<MemberDto> getAll(Byte serviceId) {
} List<UserWithCredentialDto> all = huertosWebClient.getAllUsersWithCredentials(serviceId);
public List<MemberDto> getWaitlist() { return all.stream()
List<UserWithCredentialDto> all = huertosWebClient.getAllUsersWithCredentials((byte)1); .filter(uwc -> metadataService.existsById(uwc.user().getUserId()))
return all.stream()
.filter(uwc -> metadataService.existsById(uwc.user().getUserId()))
.filter(uwc -> uwc.account().getStatus() != 0)
.map(uwc -> { .map(uwc -> {
var meta = metadataService.getById(uwc.user().getUserId()); var meta = metadataService.getById(uwc.user().getUserId());
return new MemberDto(uwc.user(), uwc.account(), return new MemberDto(
HuertosUserMetadataMapper.toDto(meta)); uwc.user(),
uwc.account(),
UserMetadataMapper.toDto(meta)
);
}) })
.filter(dto -> dto.metadata().getType().equals((byte) 0))
.sorted(Comparator.comparing(dto -> dto.metadata().getCreatedAt()))
.toList(); .toList();
} }
public List<WaitlistCensoredDto> getWaitlistLimited() { public MemberProfileDto getMyProfile(UUID userId) {
return getWaitlist().stream() MemberDto member = getById(userId);
.map(dto -> { Integer memberNumber = member.metadata().getMemberNumber();
WaitlistCensoredDto censored = new WaitlistCensoredDto();
censored.setName(NameCensorer.censor(dto.user().getDisplayName()));
return censored;
})
.toList();
}
public MemberDto getByMemberNumber(Integer memberNumber) { List<RequestDto.Response> requests = requestService.getByUserId(userId).stream()
return getAll((byte)1).stream() .map(RequestMapper::toResponse)
.filter(dto -> dto.metadata().getMemberNumber().equals(memberNumber)) .toList();
.findFirst()
.orElseThrow(() -> new NotFoundException("Member not found"));
}
public MemberDto getByPlotNumber(Integer plotNumber) { List<IncomeDto.Response> payments = incomeService.getByMemberNumber(memberNumber).stream()
return getAll((byte)1).stream() .map(IncomeMapper::toResponse)
.filter(dto -> dto.metadata().getPlotNumber().equals(plotNumber)) .toList();
.findFirst()
.orElseThrow(() -> new NotFoundException("Member not found"));
}
public MemberDto getByDni(String dni) { return new MemberProfileDto(
return getAll((byte)1).stream() member.user(),
.filter(dto -> dni.equals(dto.metadata().getDni())) member.account(),
.findFirst() member.metadata(),
.orElseThrow(() -> new NotFoundException("Member not found")); requests,
} payments,
hasCollaborator(memberNumber),
hasGreenhouse(memberNumber),
hasCollaboratorRequest(memberNumber),
hasGreenhouseRequest(memberNumber)
);
}
public List<IncomeDto.Response> getIncomes(Integer memberNumber) { public Integer getLatestMemberNumber() {
return incomeService.getByMemberNumber(memberNumber).stream() return metadataService.getLatestMemberNumber();
.map(IncomeMapper::toResponse) }
@Cacheable("waitlist")
public List<MemberDto> getWaitlist() {
List<UserWithCredentialDto> all = huertosWebClient.getAllUsersWithCredentials((byte)1);
return all.stream()
.filter(uwc -> metadataService.existsById(uwc.user().getUserId()))
.filter(uwc -> uwc.account().getStatus() != 0)
.map(uwc -> {
var meta = metadataService.getById(uwc.user().getUserId());
return new MemberDto(uwc.user(), uwc.account(),
UserMetadataMapper.toDto(meta));
})
.filter(dto -> dto.metadata().getType().equals((byte) 0))
.sorted(Comparator.comparing(dto -> dto.metadata().getCreatedAt()))
.toList();
}
public List<WaitlistCensoredDto> getWaitlistLimited() {
return getWaitlist().stream()
.map(dto -> {
WaitlistCensoredDto censored = new WaitlistCensoredDto();
censored.setName(NameCensorer.censor(dto.user().getDisplayName()));
return censored;
})
.toList(); .toList();
}
public MemberDto getByMemberNumber(Integer memberNumber) {
return getAll((byte)1).stream()
.filter(dto -> dto.metadata().getMemberNumber().equals(memberNumber))
.findFirst()
.orElseThrow(() -> new NotFoundException("No hay socio con ese número"));
}
public MemberDto getByPlotNumber(Integer plotNumber) {
return getAll((byte)1).stream()
.filter(dto -> dto.metadata().getPlotNumber().equals(plotNumber))
.findFirst()
.orElseThrow(() -> new NotFoundException("No hay socio con ese huerto"));
}
public MemberDto getByDni(String dni) {
return getAll((byte)1).stream()
.filter(dto -> dni.equals(dto.metadata().getDni()))
.findFirst()
.orElseThrow(() -> new NotFoundException("No hay socio con ese DNI"));
}
public List<IncomeDto.Response> getIncomes(Integer memberNumber) {
return incomeService.getByMemberNumber(memberNumber).stream()
.map(IncomeMapper::toResponse)
.toList();
}
public Boolean hasPaid(Integer memberNumber) {
return incomeService.hasPaid(memberNumber);
}
public Boolean hasCollaborator(Integer memberNumber) {
List<MemberDto> all = getAll((byte)1);
var member = all.stream()
.filter(dto -> dto.metadata().getMemberNumber().equals(memberNumber))
.findFirst()
.orElse(null);
if (member == null) return false;
Integer plotNumber = member.metadata().getPlotNumber();
if (plotNumber == null) return false;
List<MemberDto> plotMembers = all.stream()
.filter(dto -> plotNumber.equals(dto.metadata().getPlotNumber()))
.toList();
return plotMembers.stream()
.anyMatch(dto -> dto.metadata().getType().equals((byte)3));
}
public Boolean hasGreenhouse(Integer memberNumber) {
return metadataService.getByMemberNumber(memberNumber).getType().equals((byte)2);
}
public Boolean hasCollaboratorRequest(Integer memberNumber) {
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
return requestService.hasPendingCollaboratorRequest(userId);
}
public Boolean hasGreenhouseRequest(Integer memberNumber) {
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
return requestService.hasPendingGreenhouseRequest(userId);
}
} }
public Boolean hasPaid(Integer memberNumber) {
return incomeService.hasPaid(memberNumber);
}
public Boolean hasCollaborator(Integer memberNumber) {
List<MemberDto> all = getAll((byte)1);
var member = all.stream()
.filter(dto -> dto.metadata().getMemberNumber().equals(memberNumber))
.findFirst()
.orElse(null);
if (member == null) return false;
Integer plotNumber = member.metadata().getPlotNumber();
if (plotNumber == null) return false;
List<MemberDto> plotMembers = all.stream()
.filter(dto -> plotNumber.equals(dto.metadata().getPlotNumber()))
.toList();
return plotMembers.stream()
.anyMatch(dto -> dto.metadata().getType().equals((byte)3));
}
public Boolean hasGreenhouse(Integer memberNumber) {
return metadataService.getByMemberNumber(memberNumber).getType().equals((byte)2);
}
public Boolean hasCollaboratorRequest(Integer memberNumber) {
return requestService.existsCollaboratorRequest(memberNumber);
}
public Boolean hasGreenhouseRequest(Integer memberNumber) {
return requestService.existsGreenhouseRequest(memberNumber);
}
}

View File

@@ -1,119 +0,0 @@
package net.miarma.backend.huertos.service;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import net.miarma.backend.huertos.dto.PreUserDto;
import net.miarma.backend.huertos.validation.PreUserValidator;
import net.miarma.backlib.exception.BadRequestException;
import net.miarma.backlib.exception.NotFoundException;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.model.PreUser;
import net.miarma.backend.huertos.repository.PreUserRepository;
import net.miarma.backlib.util.UuidUtil;
@Service
@Transactional
public class PreUserService {
private final PreUserRepository repository;
public PreUserService(PreUserRepository repository) {
this.repository = repository;
}
public List<PreUser> getAll() {
return repository.findAll();
}
public PreUser getById(UUID preUserId) {
byte[] idBytes = UuidUtil.uuidToBin(preUserId);
return repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("PreUser not found"));
}
public List<PreUser> getByRequestId(UUID requestId) {
byte[] idBytes = UuidUtil.uuidToBin(requestId);
return repository.findAll().stream()
.filter(p -> p.getRequestId() != null && p.getRequestId().equals(requestId))
.toList();
}
public PreUser create(PreUser preUser) {
if (preUser.getRequestId() == null) {
throw new BadRequestException("requestId is required");
}
if (preUser.getUserName() == null || preUser.getUserName().isBlank()) {
throw new BadRequestException("userName is required");
}
if (preUser.getDisplayName() == null || preUser.getDisplayName().isBlank()) {
throw new BadRequestException("displayName is required");
}
if (preUser.getDni() == null || preUser.getDni().isBlank()) {
throw new BadRequestException("dni is required");
}
if (preUser.getPhone() == null || preUser.getPhone().isBlank()) {
throw new BadRequestException("phone is required");
}
if (preUser.getEmail() == null || preUser.getEmail().isBlank()) {
throw new BadRequestException("email is required");
}
preUser.setPreUserId(UUID.randomUUID());
preUser.setCreatedAt(Instant.now());
return repository.save(preUser);
}
public PreUser update(UUID preUserId, PreUserDto.Request dto) {
byte[] idBytes = UuidUtil.uuidToBin(preUserId);
PreUser preUser = repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("PreUser not found"));
if (dto.getUserName() != null) preUser.setUserName(dto.getUserName());
if (dto.getDisplayName() != null) preUser.setDisplayName(dto.getDisplayName());
if (dto.getDni() != null) preUser.setDni(dto.getDni());
if (dto.getPhone() != null) preUser.setPhone(dto.getPhone());
if (dto.getEmail() != null) preUser.setEmail(dto.getEmail());
if (dto.getPassword() != null) preUser.setPassword(dto.getPassword());
if (dto.getAddress() != null) preUser.setAddress(dto.getAddress());
if (dto.getZipCode() != null) preUser.setZipCode(dto.getZipCode());
if (dto.getCity() != null) preUser.setCity(dto.getCity());
if (dto.getMemberNumber() != null) preUser.setMemberNumber(dto.getMemberNumber());
if (dto.getPlotNumber() != null) preUser.setPlotNumber(dto.getPlotNumber());
if (dto.getType() != null) preUser.setType(dto.getType());
if (dto.getRole() != null) preUser.setRole(dto.getRole());
return repository.save(preUser);
}
public void delete(UUID preUserId) {
byte[] idBytes = UuidUtil.uuidToBin(preUserId);
if (!repository.existsById(idBytes)) {
throw new NotFoundException("PreUser not found");
}
repository.deleteById(idBytes);
}
public Map<String, String> validate(PreUserDto.Request request) {
Map<String, String> errors = PreUserValidator.validate(request);
if (request.getDni() != null && repository.existsByDni(request.getDni())) {
errors.put("dni", "There is already an user with that NIF/NIE");
}
if (request.getEmail() != null && repository.existsByEmail(request.getEmail())) {
errors.put("email", "There is already an user with that email");
}
return errors;
}
}

View File

@@ -0,0 +1,98 @@
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;
import net.miarma.backend.huertos.model.UserMetadata;
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;
public RequestAcceptanceService(RequestService requestService, UserMetadataService metadataService, HuertosWebClient huertosWebClient) {
this.requestService = requestService;
this.metadataService = metadataService;
this.huertosWebClient = huertosWebClient;
}
@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
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");
}
return request;
}
}

View File

@@ -4,19 +4,19 @@ import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import net.miarma.backend.huertos.dto.PreUserDto;
import net.miarma.backend.huertos.dto.RequestDto; import net.miarma.backend.huertos.dto.RequestDto;
import net.miarma.backend.huertos.mapper.PreUserMapper; import net.miarma.backend.huertos.dto.RequestMetadataDto;
import net.miarma.backend.huertos.mapper.RequestMapper; import net.miarma.backend.huertos.mapper.RequestMapper;
import net.miarma.backend.huertos.model.PreUser; import net.miarma.backend.huertos.mapper.RequestMetadataMapper;
import net.miarma.backend.huertos.repository.PreUserRepository; import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.model.Request;
import net.miarma.backend.huertos.model.RequestMetadata;
import net.miarma.backend.huertos.repository.RequestRepository;
import net.miarma.backend.huertos.repository.RequestMetadataRepository;
import net.miarma.backlib.exception.BadRequestException; import net.miarma.backlib.exception.BadRequestException;
import net.miarma.backlib.exception.NotFoundException; import net.miarma.backlib.exception.NotFoundException;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.model.Request;
import net.miarma.backend.huertos.repository.RequestRepository;
import net.miarma.backlib.util.UuidUtil; import net.miarma.backlib.util.UuidUtil;
@Service @Service
@@ -24,15 +24,12 @@ import net.miarma.backlib.util.UuidUtil;
public class RequestService { public class RequestService {
private final RequestRepository requestRepository; private final RequestRepository requestRepository;
private final PreUserRepository preUserRepository; private final RequestMetadataRepository metadataRepository;
private final HuertosUserMetadataService metadataService;
public RequestService(RequestRepository requestRepository, public RequestService(RequestRepository requestRepository,
PreUserRepository preUserRepository, RequestMetadataRepository metadataRepository) {
HuertosUserMetadataService metadataSertice) {
this.requestRepository = requestRepository; this.requestRepository = requestRepository;
this.preUserRepository = preUserRepository; this.metadataRepository = metadataRepository;
this.metadataService = metadataSertice;
} }
public List<Request> getAll() { public List<Request> getAll() {
@@ -40,107 +37,72 @@ public class RequestService {
} }
public Request getById(UUID requestId) { public Request getById(UUID requestId) {
byte[] idBytes = UuidUtil.uuidToBin(requestId); return requestRepository.findById(UuidUtil.uuidToBin(requestId))
return requestRepository.findById(idBytes) .orElseThrow(() -> new NotFoundException("Solicitud no encontrada"));
.orElseThrow(() -> new NotFoundException("Request not found"));
} }
public List<Request> getByUserId(UUID userId) { public List<Request> getByUserId(UUID userId) {
return requestRepository.findAll().stream() return requestRepository.findAll().stream()
.filter(r -> r.getRequestedBy().equals(userId)) .filter(r -> r.getUserId() != null && r.getUserId().equals(userId))
.toList();
}
public List<Request> getByRequestedBy(UUID requestedBy) {
return requestRepository.findAll().stream()
.filter(r -> r.getRequestedBy() != null && r.getRequestedBy().equals(requestedBy))
.toList();
}
public List<Request> getByTargetUserId(UUID targetUserId) {
return requestRepository.findAll().stream()
.filter(r -> r.getTargetUserId() != null && r.getTargetUserId().equals(targetUserId))
.toList(); .toList();
} }
public Request create(Request request) { public Request create(Request request) {
if (request.getType() == null) { if (request.getType() == null) throw new BadRequestException("Tipo de solicitud obligatorio");
throw new BadRequestException("type is required");
}
if (request.getStatus() == null) {
throw new BadRequestException("status is required");
}
if (request.getRequestedBy() == null) {
throw new BadRequestException("requestedBy is required");
}
request.setRequestId(UUID.randomUUID()); request.setRequestId(UUID.randomUUID());
request.setCreatedAt(Instant.now()); request.setCreatedAt(Instant.now());
return requestRepository.save(request); return requestRepository.save(request);
} }
@Transactional @Transactional
public RequestDto.Response createWithPreUser(RequestDto.Request requestDto, public Request createWithMetadata(RequestDto.Request requestDto,
PreUserDto.Request preUserDto) { RequestMetadataDto metadataDto) {
Request request = requestRepository.save(RequestMapper.toEntity(requestDto)); Request request = RequestMapper.toEntity(requestDto);
PreUser tmpPreUser = PreUserMapper.toEntity(preUserDto); RequestMetadata metadata = RequestMetadataMapper.fromDto(metadataDto);
tmpPreUser.setRequestId(request.getRequestId()); request.setMetadata(metadata);
PreUser preUser = preUserRepository.save(tmpPreUser); request.setRequestId(UUID.randomUUID());
return RequestMapper.toResponse(request); request.setCreatedAt(Instant.now());
return requestRepository.save(request);
} }
public Request update(UUID requestId, RequestDto.Request dto) {
byte[] idBytes = UuidUtil.uuidToBin(requestId);
Request request = requestRepository.findById(idBytes) public Request update(UUID requestId, Request changes) {
.orElseThrow(() -> new NotFoundException("Request not found")); Request request = getById(requestId);
if (dto.getType() != null) request.setType(dto.getType()); if (changes.getType() != null) request.setType(changes.getType());
if (dto.getStatus() != null) request.setStatus(dto.getStatus()); if (changes.getStatus() != null) request.setStatus(changes.getStatus());
if (dto.getRequestedBy() != null) request.setRequestedBy(dto.getRequestedBy()); if (changes.getUserId() != null) request.setUserId(changes.getUserId());
if (dto.getTargetUserId() != null) request.setTargetUserId(dto.getTargetUserId());
return requestRepository.save(request); return requestRepository.save(request);
} }
public Request acceptRequest(UUID requestId) { public Request accept(UUID requestId) {
byte[] idBytes = UuidUtil.uuidToBin(requestId); Request request = getById(requestId);
Request request = requestRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Request not found"));
request.setStatus((byte)1); request.setStatus((byte)1);
return requestRepository.save(request); return requestRepository.save(request);
} }
public Request rejectRequest(UUID requestId) { public Request reject(UUID requestId) {
byte[] idBytes = UuidUtil.uuidToBin(requestId); Request request = getById(requestId);
Request request = requestRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Request not found"));
request.setStatus((byte)2); request.setStatus((byte)2);
return requestRepository.save(request); return requestRepository.save(request);
} }
public void delete(UUID requestId) { public void delete(UUID requestId) {
byte[] idBytes = UuidUtil.uuidToBin(requestId); UUID id = requestId;
if (!requestRepository.existsById(UuidUtil.uuidToBin(id))) {
if (!requestRepository.existsById(idBytes)) { throw new NotFoundException("Solicitud no encontrada");
throw new NotFoundException("Request not found");
} }
requestRepository.deleteById(UuidUtil.uuidToBin(id));
requestRepository.deleteById(idBytes);
} }
public Boolean existsCollaboratorRequest(Integer memberNumber) { public boolean hasPendingGreenhouseRequest(UUID userId) {
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
return getByUserId(userId).stream() return getByUserId(userId).stream()
.anyMatch(r -> r.getType().equals((byte)2) || .anyMatch(r -> r.getType() == 1);
r.getType().equals((byte)3));
} }
public Boolean existsGreenhouseRequest(Integer memberNumber) { public boolean hasPendingCollaboratorRequest(UUID userId) {
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
return getByUserId(userId).stream() return getByUserId(userId).stream()
.anyMatch(r -> r.getType().equals((byte)4) || .anyMatch(r -> r.getType() == 2);
r.getType().equals((byte)5));
} }
} }

View File

@@ -0,0 +1,120 @@
package net.miarma.backend.huertos.service;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import net.miarma.backlib.exception.BadRequestException;
import net.miarma.backlib.exception.ConflictException;
import net.miarma.backlib.exception.NotFoundException;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.model.UserMetadata;
import net.miarma.backend.huertos.repository.UserMetadataRepository;
import net.miarma.backlib.util.UuidUtil;
@Service
@Transactional
public class UserMetadataService {
private final UserMetadataRepository repository;
public UserMetadataService(UserMetadataRepository repository) {
this.repository = repository;
}
public List<UserMetadata> getAll() {
return repository.findAll();
}
@Cacheable("metadataByUserId")
public UserMetadata getById(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
return repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Metadatos de usuario no encontrados"));
}
@Cacheable("metadataByMemberNumber")
public UserMetadata getByMemberNumber(Integer memberNumber) {
return repository.findByMemberNumber(memberNumber)
.orElseThrow(() -> new NotFoundException("Metadatos de usuario no encontrados"));
}
@Cacheable("metadataExists")
public boolean existsById(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
return repository.existsById(idBytes);
}
public UserMetadata create(UserMetadata meta) {
if (meta.getUserId() == null) {
throw new BadRequestException("El identificador de usuario es obligatorio");
}
if (repository.existsById(UuidUtil.uuidToBin(meta.getUserId()))) {
throw new ConflictException("Este usuario ya tiene metadatos asociados");
}
if (meta.getMemberNumber() == null) throw new BadRequestException("El número de socio es obligatorio");
if (meta.getPlotNumber() == null) throw new BadRequestException("El número de huerto es obligatorio");
if (meta.getDni() == null || meta.getDni().isBlank()) throw new BadRequestException("El DNI es obligatorio");
if (meta.getPhone() == null || meta.getPhone().isBlank()) throw new BadRequestException("El teléfono es obligatorio");
if (meta.getType() == null) meta.setType((byte) 0);
if (meta.getRole() == null) meta.setRole((byte) 0);
meta.setCreatedAt(Instant.now());
meta.setAssignedAt(null);
meta.setDeactivatedAt(null);
return repository.save(meta);
}
@CacheEvict(
value = {
"metadataByUserId",
"metadataByMemberNumber",
"metadataExists"
},
key = "#userId"
)
public UserMetadata update(UUID userId, UserMetadata changes) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
UserMetadata metadata = repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Metadatos de usuario no encontrados"));
if (changes.getMemberNumber() != null) metadata.setMemberNumber(changes.getMemberNumber());
if (changes.getPlotNumber() != null) metadata.setPlotNumber(changes.getPlotNumber());
if (changes.getDni() != null) metadata.setDni(changes.getDni());
if (changes.getPhone() != null) metadata.setPhone(changes.getPhone());
if (changes.getType() != null) metadata.setType(changes.getType());
if (changes.getRole() != null) metadata.setRole(changes.getRole());
if (changes.getNotes() != null) metadata.setNotes(changes.getNotes());
if (changes.getAssignedAt() != null) metadata.setAssignedAt(changes.getAssignedAt());
if (changes.getDeactivatedAt() != null) metadata.setDeactivatedAt(changes.getDeactivatedAt());
return repository.save(metadata);
}
public void delete(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
if (!repository.existsById(idBytes)) {
throw new NotFoundException("Metadatos de usuario no encontrados");
}
repository.deleteById(idBytes);
}
public Integer getLatestMemberNumber() {
return repository.findAll()
.stream()
.map(UserMetadata::getMemberNumber)
.max(Integer::compareTo)
.get();
}
public Boolean existsByMemberNumber(Integer memberNumber) {
return getByMemberNumber(memberNumber).getUserId() != null;
}
}

View File

@@ -1,33 +0,0 @@
package net.miarma.backend.huertos.service.view;
import java.util.List;
import java.util.UUID;
import net.miarma.backlib.exception.NotFoundException;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.model.view.VHuertosMembers;
import net.miarma.backend.huertos.repository.view.VHuertosMembersRepository;
import net.miarma.backlib.util.UuidUtil;
@Service
@Transactional
public class VHuertosMembersService {
private final VHuertosMembersRepository repository;
public VHuertosMembersService(VHuertosMembersRepository repository) {
this.repository = repository;
}
public List<VHuertosMembers> getAll() {
return repository.findAll();
}
public VHuertosMembers getById(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
return repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Member not found"));
}
}

View File

@@ -28,7 +28,7 @@ public class VIncomesWithInfoService {
public VIncomesWithInfo getById(UUID incomeId) { public VIncomesWithInfo getById(UUID incomeId) {
byte[] idBytes = UuidUtil.uuidToBin(incomeId); byte[] idBytes = UuidUtil.uuidToBin(incomeId);
return repository.findById(idBytes) return repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Income not found")); .orElseThrow(() -> new NotFoundException("Ingreso no encontrado"));
} }
public List<VIncomesWithInfo> getByUserId(UUID userId) { public List<VIncomesWithInfo> getByUserId(UUID userId) {

View File

@@ -1,39 +0,0 @@
package net.miarma.backend.huertos.service.view;
import java.util.List;
import java.util.UUID;
import net.miarma.backlib.exception.NotFoundException;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
import net.miarma.backend.huertos.model.view.VRequestsWithPreUsers;
import net.miarma.backend.huertos.repository.view.VRequestsWithPreUsersRepository;
import net.miarma.backlib.util.UuidUtil;
@Service
@Transactional
public class VRequestsWithPreUsersService {
private final VRequestsWithPreUsersRepository repository;
public VRequestsWithPreUsersService(VRequestsWithPreUsersRepository repository) {
this.repository = repository;
}
public List<VRequestsWithPreUsers> getAll() {
return repository.findAll();
}
public VRequestsWithPreUsers getById(UUID requestId) {
byte[] idBytes = UuidUtil.uuidToBin(requestId);
return repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Request not found"));
}
public List<VRequestsWithPreUsers> getByRequestType(Byte type) {
return repository.findAll().stream()
.filter(r -> r.getRequestType().equals(type))
.toList();
}
}

View File

@@ -0,0 +1,7 @@
package net.miarma.backend.huertos.util;
public class UsernameGenerator {
public static String generate(String name, Integer number) {
return name.split(" ")[0] + number;
}
}

View File

@@ -1,61 +0,0 @@
package net.miarma.backend.huertos.validation;
import net.miarma.backend.huertos.dto.PreUserDto;
import java.util.HashMap;
import java.util.Map;
public class PreUserValidator {
public static Map<String, String> validate(PreUserDto.Request dto) {
Map<String, String> errors = new HashMap<>();
if (dto.getUserName() == null || dto.getUserName().isBlank()) {
errors.put("userName", "El nombre de usuario es obligatorio");
} else if (dto.getUserName().length() < 3) {
errors.put("userName", "El nombre de usuario debe tener al menos 3 caracteres");
}
if (dto.getDisplayName() == null || dto.getDisplayName().isBlank()) {
errors.put("displayName", "El nombre visible es obligatorio");
}
if (dto.getDni() == null || dto.getDni().isBlank()) {
errors.put("dni", "El DNI es obligatorio");
} else if (!dto.getDni().matches("^[0-9]{8}[A-Za-z]$")) {
errors.put("dni", "DNI inválido");
}
if (dto.getEmail() == null || dto.getEmail().isBlank()) {
errors.put("email", "El email es obligatorio");
} else if (!dto.getEmail().matches("^[\\w-.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
errors.put("email", "Email inválido");
}
if (dto.getPhone() == null || dto.getPhone().isBlank()) {
errors.put("phone", "El teléfono es obligatorio");
} else if (!dto.getPhone().matches("^[0-9]{9}$")) {
errors.put("phone", "Teléfono inválido");
}
if (dto.getAddress() == null || dto.getAddress().isBlank()) {
errors.put("address", "La dirección es obligatoria");
}
if (dto.getZipCode() == null || dto.getZipCode().isBlank()) {
errors.put("zipCode", "El código postal es obligatorio");
}
if (dto.getCity() == null || dto.getCity().isBlank()) {
errors.put("city", "La ciudad es obligatoria");
}
if (dto.getPassword() == null || dto.getPassword().isBlank()) {
errors.put("password", "La contraseña es obligatoria");
} else if (dto.getPassword().length() < 6) {
errors.put("password", "La contraseña debe tener al menos 6 caracteres");
}
return errors;
}
}