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
) {
dto.setCredentialId(credentialId);
return ResponseEntity.ok(credentialService.update(credentialId, dto));
return ResponseEntity.ok(
credentialService.update(
credentialId, CredentialMapper.toEntity(dto)));
}
@DeleteMapping("/{credential_id}")

View File

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

View File

@@ -44,9 +44,11 @@ public class UserController {
@PostMapping
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<UserDto> create(@RequestBody UserDto dto) {
public ResponseEntity<UserDto> create(@RequestBody CreateUserDto dto) {
return ResponseEntity.ok(
UserMapper.toDto(userService.create(dto))
UserMapper.toDto(
userService.create(
UserMapper.fromCreateDto(dto)))
);
}
@@ -92,8 +94,12 @@ public class UserController {
@PutMapping("/{user_id}")
@PreAuthorize("hasRole('ADMIN') or #userId == principal.userId")
public ResponseEntity<UserDto> update(@PathVariable("user_id") UUID userId, @RequestBody UserDto dto) {
return ResponseEntity.ok(UserMapper.toDto(userService.update(userId, dto)));
public ResponseEntity<UserDto> update(
@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")

View File

@@ -1,11 +1,35 @@
package net.miarma.backend.core.mapper;
import net.miarma.backend.core.model.User;
import net.miarma.backlib.dto.CreateUserDto;
import net.miarma.backlib.dto.CredentialDto;
import net.miarma.backlib.dto.UserDto;
import net.miarma.backlib.dto.UserWithCredentialDto;
import java.util.UUID;
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) {
if (u == null) return null;

View File

@@ -2,6 +2,7 @@ package net.miarma.backend.core.service;
import java.util.UUID;
import net.miarma.backlib.dto.*;
import net.miarma.backlib.exception.ConflictException;
import net.miarma.backlib.exception.ForbiddenException;
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.model.Credential;
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;
@Service
@@ -39,11 +35,11 @@ public class AuthService {
Credential cred = credentialService.getForLogin(request.serviceId(), request.username());
if (!passwordEncoder.matches(request.password(), cred.getPassword())) {
throw new UnauthorizedException("Invalid credentials");
throw new UnauthorizedException("Credenciales no válidas");
}
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());
@@ -55,17 +51,15 @@ public class AuthService {
public LoginResponse register(RegisterRequest request) {
if (credentialService.existsByUsernameAndService(request.username(), request.serviceId())) {
throw new ConflictException("Username already taken");
throw new ConflictException("Ese usuario ya existe");
}
User user;
try {
user = credentialService.getByEmail(request.email());
} catch (Exception e) {
UserDto dto = new UserDto();
dto.setUserId(UUID.randomUUID());
dto.setDisplayName(request.displayName());
user = userService.create(dto);
CreateUserDto dto = new CreateUserDto(request.displayName(), null);
user = userService.create(UserMapper.fromCreateDto(dto));
}
Credential cred = new Credential();

View File

@@ -33,30 +33,30 @@ public class CredentialService {
public Credential getById(UUID credentialId) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
return credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found"));
.orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
}
public Credential create(Credential credential) {
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]+$")) {
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) {
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) {
throw new ValidationException("serviceId", "ServiceId must be positive");
throw new ValidationException("serviceId", "El identificador de servicio debe ser positivo");
}
boolean existsUsername = credentialRepository.existsByUsernameAndServiceId(
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(
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.setPassword(passwordEncoder.encode(credential.getPassword()));
@@ -78,25 +78,25 @@ public class CredentialService {
public List<Credential> getByUserId(UUID userId) {
List<Credential> creds = credentialRepository.findByUserId(UuidUtil.uuidToBin(userId));
if (creds.isEmpty()) {
throw new NotFoundException("User has no credentials");
throw new NotFoundException("El usuario no tiene cuenta");
}
return creds;
}
public User getByEmail(String email) {
return credentialRepository.findByEmail(email)
.orElseThrow(() -> new NotFoundException("No credential found for email"))
.orElseThrow(() -> new NotFoundException("No hay cuenta asociada a ese email"))
.getUser();
}
public Credential getByUserIdAndService(UUID userId, Byte 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) {
return credentialRepository.findByServiceIdAndUsername(serviceId, username)
.orElseThrow(() -> new BadRequestException("Invalid credentials"));
.orElseThrow(() -> new BadRequestException("Credenciales no válidas"));
}
public boolean existsByUsernameAndService(String username, int serviceId) {
@@ -106,30 +106,30 @@ public class CredentialService {
public boolean isOwner(UUID credentialId, UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
Credential c = credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found"));
.orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
return c.getUserId().equals(userId);
}
public Credential update(UUID credentialId, CredentialDto dto) {
public Credential update(UUID credentialId, Credential changes) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
Credential cred = credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found"));
.orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
if (dto.getUsername() != null && dto.getUsername().isBlank()) {
throw new ValidationException("userName", "Username cannot be blank");
if (changes.getUsername() != null && changes.getUsername().isBlank()) {
throw new ValidationException("userName", "El usuario no puede estar vacío");
}
if (dto.getEmail() != null && !dto.getEmail().matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) {
throw new ValidationException("email", "Invalid email format");
if (changes.getEmail() != null && !changes.getEmail().matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$")) {
throw new ValidationException("email", "Formato de email no válido");
}
if (dto.getServiceId() != null && dto.getServiceId() < 0) {
throw new ValidationException("serviceId", "ServiceId must be positive");
if (changes.getServiceId() != null && changes.getServiceId() < 0) {
throw new ValidationException("serviceId", "El identificador de servicio debe ser positivo");
}
if (dto.getUsername() != null) cred.setUsername(dto.getUsername());
if (dto.getEmail() != null) cred.setEmail(dto.getEmail());
if (dto.getServiceId() != null) cred.setServiceId(dto.getServiceId());
if (dto.getStatus() != null) cred.setStatus(dto.getStatus());
if (changes.getUsername() != null) cred.setUsername(changes.getUsername());
if (changes.getEmail() != null) cred.setEmail(changes.getEmail());
if (changes.getServiceId() != null) cred.setServiceId(changes.getServiceId());
if (changes.getStatus() != null) cred.setStatus(changes.getStatus());
return credentialRepository.save(cred);
}
@@ -138,10 +138,10 @@ public class CredentialService {
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
Credential cred = credentialRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Credential not found"));
.orElseThrow(() -> new NotFoundException("Cuenta no encontrada"));
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()));
@@ -151,19 +151,19 @@ public class CredentialService {
public void delete(UUID credentialId) {
byte[] idBytes = UuidUtil.uuidToBin(credentialId);
if(!credentialRepository.existsById(idBytes))
throw new NotFoundException("Credential not found");
throw new NotFoundException("Cuenta no encontrada");
credentialRepository.deleteById(idBytes);
}
public Byte getStatus(UUID credentialId) {
Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId))
.orElseThrow(() -> new NotFoundException("User not found"));;
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
return credential.getStatus();
}
public void updateStatus(UUID credentialId, Byte status) {
Credential credential = credentialRepository.findById(UuidUtil.uuidToBin(credentialId))
.orElseThrow(() -> new NotFoundException("User not found"));;
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
credential.setStatus(status);
credentialRepository.save(credential);
}

View File

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

View File

@@ -31,44 +31,35 @@ public class UserService {
public User getById(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
return userRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("User not found"));
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
}
public User create(UserDto dto) {
if(dto.getDisplayName() == null || dto.getDisplayName().isBlank()) {
throw new ValidationException("displayName", "Display name is required");
public User create(User user) {
if(user.getDisplayName() == null || user.getDisplayName().isBlank()) {
throw new ValidationException("displayName", "El nombre a mostrar es necesario");
}
User user = new User();
user.setUserId(UUID.randomUUID());
user.setDisplayName(dto.getDisplayName());
user.setAvatar(dto.getAvatar());
user.setGlobalRole(dto.getGlobalRole() != null ? dto.getGlobalRole() : 0);
user.setGlobalStatus(dto.getGlobalStatus() != null ? dto.getGlobalStatus() : 1);
return userRepository.save(user);
}
public User update(UUID userId, UserDto dto) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
User user = userRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("User not found"));
public User update(UUID userId, User changes) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
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 (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);
}
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());
if (changes.getAvatar() != null)
user.setAvatar(changes.getAvatar());
if (changes.getGlobalRole() != null)
user.setGlobalRole(changes.getGlobalRole());
if (changes.getGlobalStatus() != null)
user.setGlobalStatus(changes.getGlobalStatus());
return userRepository.save(user);
}
@@ -76,13 +67,13 @@ public class UserService {
public void delete(UUID userId) {
byte[] idBytes = UuidUtil.uuidToBin(userId);
if(!userRepository.existsById(idBytes))
throw new NotFoundException("User not found");
throw new NotFoundException("Usuario no encontrado");
userRepository.deleteById(idBytes);
}
public UserDto updateAvatar(UUID userId, ChangeAvatarRequest req) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));
user.setAvatar(req.avatar());
userRepository.save(user);
return UserMapper.toDto(user);
@@ -90,26 +81,26 @@ public class UserService {
public Byte getStatus(UUID userId) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));;
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
return user.getGlobalStatus();
}
public void updateStatus(UUID userId, Byte status) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));;
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
user.setGlobalStatus(status);
userRepository.save(user);
}
public Byte getRole(UUID userId) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));;
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
return user.getGlobalRole();
}
public void updateRole(UUID userId, Byte role) {
User user = userRepository.findById(UuidUtil.uuidToBin(userId))
.orElseThrow(() -> new NotFoundException("User not found"));;
.orElseThrow(() -> new NotFoundException("Usuario no encontrado"));;
user.setGlobalRole(role);
userRepository.save(user);
}

View File

@@ -46,6 +46,15 @@
<version>4.0.1</version>
<scope>compile</scope>
</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 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>

View File

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

View File

@@ -1,8 +1,10 @@
package net.miarma.backend.huertos.client;
import net.miarma.backlib.dto.LoginRequest;
import net.miarma.backlib.dto.LoginResponse;
import net.miarma.backlib.dto.UserWithCredentialDto;
import net.miarma.backend.huertos.dto.RequestMetadataDto;
import net.miarma.backend.huertos.model.RequestMetadata;
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.Value;
import org.springframework.stereotype.Component;
@@ -41,4 +43,44 @@ public class HuertosWebClient {
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
.requestMatchers("/auth/login").permitAll()
.requestMatchers("/users/waitlist/limited").permitAll()
.requestMatchers("/requests").permitAll()
.requestMatchers("/pre-users").permitAll()
.requestMatchers("/users/latest-number").permitAll()
.requestMatchers("/pre-users/validate").permitAll()
// PRIVADAS

View File

@@ -46,7 +46,7 @@ public class AnnouncementController {
@RequestBody AnnouncementDto.Request dto
) {
return ResponseEntity.ok(
AnnouncementMapper.toResponse(announcementService.update(announcementId, dto))
AnnouncementMapper.toResponse(announcementService.update(announcementId, AnnouncementMapper.toEntity(dto)))
);
}

View File

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

View File

@@ -1,12 +1,10 @@
package net.miarma.backend.huertos.controller;
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.HuertosUserMetadataDto;
import net.miarma.backend.huertos.mapper.HuertosUserMetadataMapper;
import net.miarma.backend.huertos.model.HuertosUserMetadata;
import net.miarma.backend.huertos.service.HuertosUserMetadataService;
import net.miarma.backend.huertos.mapper.UserMetadataMapper;
import net.miarma.backend.huertos.model.UserMetadata;
import net.miarma.backend.huertos.service.UserMetadataService;
import net.miarma.backlib.dto.LoginRequest;
import net.miarma.backlib.dto.LoginResponse;
import org.springframework.http.ResponseEntity;
@@ -18,10 +16,10 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/auth")
public class HuertosAuthController {
private final HuertosUserMetadataService metadataService;
private final UserMetadataService metadataService;
private final CoreAuthClient authClient;
public HuertosAuthController(HuertosUserMetadataService metadataService,
public HuertosAuthController(UserMetadataService metadataService,
CoreAuthClient authClient) {
this.metadataService = metadataService;
this.authClient = authClient;
@@ -30,13 +28,13 @@ public class HuertosAuthController {
@PostMapping("/login")
public ResponseEntity<HuertosLoginResponse> login(@RequestBody LoginRequest req) {
LoginResponse coreResponse = authClient.login(req);
HuertosUserMetadata metadata = metadataService.getById(coreResponse.user().getUserId());
UserMetadata metadata = metadataService.getById(coreResponse.user().getUserId());
return ResponseEntity.ok(
new HuertosLoginResponse(
coreResponse.token(),
coreResponse.user(),
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.view.VIncomesWithInfoMapper;
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.view.VIncomesWithInfoService;
import net.miarma.backlib.security.JwtService;
@@ -95,8 +94,14 @@ public class IncomeController {
@PutMapping("/{income_id}")
@PreAuthorize("hasAnyRole('HUERTOS_ROLE_ADMIN', 'HUERTOS_ROLE_DEV')")
public ResponseEntity<IncomeDto.Response> update(@PathVariable("income_id") UUID incomeId, @RequestBody IncomeDto.Request dto) {
return ResponseEntity.ok(IncomeMapper.toResponse(incomeService.update(incomeId, dto)));
public ResponseEntity<IncomeDto.Response> update(
@PathVariable("income_id") UUID incomeId,
@RequestBody IncomeDto.Request dto
) {
return ResponseEntity.ok(
IncomeMapper.toResponse(
incomeService.update(
incomeId, IncomeMapper.toEntity(dto))));
}
@DeleteMapping("/{income_id}")

View File

@@ -23,15 +23,9 @@ import java.util.UUID;
public class MemberController {
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.requestService = requestService;
this.incomeService = incomeService;
this.jwtService = jwtService;
}
@GetMapping
@@ -41,41 +35,13 @@ public class MemberController {
}
@GetMapping("/me")
public ResponseEntity<MemberProfileDto> getMe() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
public ResponseEntity<MemberProfileDto> getMe(Authentication authentication) {
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(
new MemberProfileDto(
member.user(),
member.account(),
member.metadata(),
requests,
payments,
memberService.hasCollaborator(memberNumber),
memberService.hasGreenhouse(memberNumber),
memberService.hasCollaboratorRequest(memberNumber),
memberService.hasGreenhouseRequest(memberNumber)
)
memberService.getMyProfile(principal.getUserId())
);
}

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

View File

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

View File

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

View File

@@ -8,7 +8,7 @@ import java.util.List;
public record MemberProfileDto(
UserDto user,
CredentialDto account,
HuertosUserMetadataDto metadata,
UserMetadataDto metadata,
List<RequestDto.Response> requests,
List<IncomeDto.Response> payments,
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 static class Request {
private Byte type;
private Byte status;
private UUID requestedBy;
private UUID userId;
private RequestMetadataDto metadata;
public Byte getType() {
return type;
@@ -19,37 +19,30 @@ public class RequestDto {
this.type = type;
}
public Byte getStatus() {
return status;
public UUID getUserId() {
return userId;
}
public void setStatus(Byte status) {
this.status = status;
public void setUserId(UUID userId) {
this.userId = userId;
}
public UUID getRequestedBy() {
return requestedBy;
public RequestMetadataDto getMetadata() {
return metadata;
}
public void setRequestedBy(UUID requestedBy) {
this.requestedBy = requestedBy;
public void setMetadata(RequestMetadataDto metadata) {
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 {
private UUID requestId;
private Byte type;
private Byte status;
private UUID userId;
private RequestMetadataDto metadata;
private Instant createdAt;
public UUID getRequestId() {
return requestId;
@@ -75,20 +68,20 @@ public class RequestDto {
this.status = status;
}
public UUID getRequestedBy() {
return requestedBy;
public UUID getUserId() {
return userId;
}
public void setRequestedBy(UUID requestedBy) {
this.requestedBy = requestedBy;
public void setUserId(UUID userId) {
this.userId = userId;
}
public UUID getTargetUserId() {
return targetUserId;
public RequestMetadataDto getMetadata() {
return metadata;
}
public void setTargetUserId(UUID targetUserId) {
this.targetUserId = targetUserId;
public void setMetadata(RequestMetadataDto metadata) {
this.metadata = metadata;
}
public Instant getCreatedAt() {
@@ -98,9 +91,5 @@ public class RequestDto {
public void setCreatedAt(Instant 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.util.UUID;
public class HuertosUserMetadataDto {
public class UserMetadataDto {
private UUID userId;
private Integer memberNumber;
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;
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;
public class RequestMapper {
@@ -14,19 +12,16 @@ public class RequestMapper {
dto.setRequestId(entity.getRequestId());
dto.setType(entity.getType());
dto.setStatus(entity.getStatus());
dto.setRequestedBy(entity.getRequestedBy());
dto.setTargetUserId(entity.getTargetUserId());
dto.setUserId(entity.getUserId());
dto.setCreatedAt(entity.getCreatedAt());
return dto;
if (entity.getMetadata() != null) {
dto.setMetadata(
RequestMetadataMapper.toDto(entity.getMetadata())
);
}
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)
);
return dto;
}
public static Request toEntity(RequestDto.Request dto) {
@@ -34,9 +29,15 @@ public class RequestMapper {
Request entity = new Request();
entity.setType(dto.getType());
entity.setStatus(dto.getStatus());
entity.setRequestedBy(dto.getRequestedBy());
entity.setTargetUserId(dto.getTargetUserId());
entity.setUserId(dto.getUserId());
entity.setStatus((byte) 0);
if (dto.getMetadata() != null) {
entity.setMetadata(
RequestMetadataMapper.fromDto(dto.getMetadata())
);
}
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;
import net.miarma.backend.huertos.dto.HuertosUserMetadataDto;
import net.miarma.backend.huertos.model.HuertosUserMetadata;
import net.miarma.backend.huertos.dto.UserMetadataDto;
import net.miarma.backend.huertos.model.UserMetadata;
public class HuertosUserMetadataMapper {
public class UserMetadataMapper {
public static HuertosUserMetadataDto toDto(HuertosUserMetadata entity) {
HuertosUserMetadataDto dto = new HuertosUserMetadataDto();
public static UserMetadataDto toDto(UserMetadata entity) {
UserMetadataDto dto = new UserMetadataDto();
dto.setUserId(entity.getUserId());
dto.setMemberNumber(entity.getMemberNumber());
dto.setPlotNumber(entity.getPlotNumber());
@@ -21,8 +21,8 @@ public class HuertosUserMetadataMapper {
return dto;
}
public static HuertosUserMetadata fromDto(HuertosUserMetadataDto dto) {
HuertosUserMetadata entity = new HuertosUserMetadata();
public static UserMetadata fromDto(UserMetadataDto dto) {
UserMetadata entity = new UserMetadata();
entity.setUserId(dto.getUserId());
entity.setMemberNumber(dto.getMemberNumber());
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

@@ -17,56 +17,49 @@ public class Request {
@Transient
private UUID requestId;
@Column(name = "user_id", columnDefinition = "BINARY(16)")
private byte[] userIdBin; // usuario que hace la solicitud (puede ser null si anon)
@Transient
private UUID userId;
@Column(name = "type", nullable = false)
private Byte type;
@Column(name = "status", nullable = false)
private Byte status;
@Column(name = "requested_by", columnDefinition = "BINARY(16)")
private byte[] requestedByBin;
@Transient
private UUID requestedBy;
@Column(name = "target_user_id", columnDefinition = "BINARY(16)")
private byte[] targetUserIdBin;
@Transient
private UUID targetUserId;
@Column(name = "created_at", nullable = false)
private Instant createdAt;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "metadata_id")
private RequestMetadata metadata;
@PrePersist
@PreUpdate
private void prePersist() {
if (requestId != null) {
requestIdBin = UuidUtil.uuidToBin(requestId);
}
if (requestedBy != null) {
requestedByBin = UuidUtil.uuidToBin(requestedBy);
}
if (targetUserId != null) {
targetUserIdBin = UuidUtil.uuidToBin(targetUserId);
requestIdBin = net.miarma.backlib.util.UuidUtil.uuidToBin(requestId);
}
createdAt = Instant.now();
}
@PostLoad
private void postLoad() {
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) {
requestedBy = UuidUtil.binToUUID(requestedByBin);
public byte[] getRequestIdBin() {
return requestIdBin;
}
if (targetUserIdBin != null) {
targetUserId = UuidUtil.binToUUID(targetUserIdBin);
}
public void setRequestIdBin(byte[] requestIdBin) {
this.requestIdBin = requestIdBin;
}
public UUID getRequestId() {
@@ -77,6 +70,22 @@ public class Request {
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() {
return type;
}
@@ -93,22 +102,6 @@ public class Request {
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() {
return createdAt;
}
@@ -117,4 +110,11 @@ public class Request {
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,7 +8,7 @@ import net.miarma.backlib.util.UuidUtil;
@Entity
@Table(name = "huertos_user_metadata")
public class HuertosUserMetadata {
public class UserMetadata {
@Id
@Column(name = "user_id", columnDefinition = "BINARY(16)")
@@ -150,4 +150,8 @@ public class HuertosUserMetadata {
public void setDeactivatedAt(Instant 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.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.miarma.backend.huertos.model.view.VHuertosMembers;
import net.miarma.backend.huertos.service.view.VHuertosMembersService;
import net.miarma.backend.huertos.model.UserMetadata;
import net.miarma.backend.huertos.service.UserMetadataService;
import net.miarma.backlib.security.JwtService;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -19,11 +19,11 @@ import java.util.UUID;
public class HuertosJwtFilter extends OncePerRequestFilter {
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.huertosUserService = huertosUserService;
this.metadataService = metadataService;
}
@Override
@@ -39,13 +39,13 @@ public class HuertosJwtFilter extends OncePerRequestFilter {
UUID userId = jwtService.getUserId(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(
userId,
huertosUser.getRole(),
huertosUser.getType(),
metadata.getRole(),
metadata.getType(),
serviceId
);

View File

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

View File

@@ -26,17 +26,17 @@ public class BalanceService {
public Balance get() {
return balanceRepository.findById((byte) 1)
.orElseThrow(() -> new NotFoundException("Balance not found"));
.orElseThrow(() -> new NotFoundException("Balance no encontrado"));
}
public VBalanceWithTotals getWithTotals() {
return vBalanceWithTotalsRepository.findById((byte) 1)
.orElseThrow(() -> new NotFoundException("Balance not found"));
.orElseThrow(() -> new NotFoundException("Balance no encontrado"));
}
public Balance create(Balance balance) {
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.setCreatedAt(Instant.now());
@@ -45,7 +45,7 @@ public class BalanceService {
public Balance update(Balance dto) {
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.getInitialCash() != null) balance.setInitialCash(dto.getInitialCash());
@@ -55,7 +55,7 @@ public class BalanceService {
public void delete() {
if (!balanceRepository.existsById((byte) 1)) {
throw new NotFoundException("Balance not found");
throw new NotFoundException("Balance no encontrado");
}
balanceRepository.deleteById((byte) 1);
}

View File

@@ -30,21 +30,21 @@ public class ExpenseService {
public Expense getById(UUID expenseId) {
byte[] idBytes = UuidUtil.uuidToBin(expenseId);
return expenseRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Expense not found"));
.orElseThrow(() -> new NotFoundException("Gasto no encontrado"));
}
public Expense create(Expense expense) {
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) {
throw new ValidationException("amount", "Amount is required");
throw new ValidationException("amount", "La cantidad es obligatoria");
}
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()) {
throw new ValidationException("invoice", "Invoice is required");
throw new ValidationException("invoice", "La factura es obligatoria");
}
expense.setExpenseId(UUID.randomUUID());
@@ -53,16 +53,26 @@ public class ExpenseService {
return expenseRepository.save(expense);
}
public Expense update(UUID expenseId, ExpenseDto.Request dto) {
public Expense update(UUID expenseId, Expense changes) {
byte[] idBytes = UuidUtil.uuidToBin(expenseId);
Expense expense = expenseRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Expense not found"));
if (dto.getConcept() != null) expense.setConcept(dto.getConcept());
if (dto.getAmount() != null) expense.setAmount(dto.getAmount());
if (dto.getSupplier() != null) expense.setSupplier(dto.getSupplier());
if (dto.getInvoice() != null) expense.setInvoice(dto.getInvoice());
if (dto.getType() != null) expense.setType(dto.getType());
Expense expense = expenseRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Gasto no encontrado"));
if (changes.getConcept() != null)
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);
}
@@ -70,7 +80,7 @@ public class ExpenseService {
public void delete(UUID expenseId) {
byte[] idBytes = UuidUtil.uuidToBin(expenseId);
if (!expenseRepository.existsById(idBytes)) {
throw new NotFoundException("Expense not found");
throw new NotFoundException("Gasto no encontrado");
}
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.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.NotFoundException;
import net.miarma.backlib.exception.ValidationException;
@@ -22,10 +19,10 @@ import net.miarma.backlib.util.UuidUtil;
public class IncomeService {
private final IncomeRepository incomeRepository;
private final HuertosUserMetadataService metadataService;
private final UserMetadataService metadataService;
public IncomeService(IncomeRepository incomeRepository,
HuertosUserMetadataService metadataService) {
UserMetadataService metadataService) {
this.incomeRepository = incomeRepository;
this.metadataService = metadataService;
}
@@ -37,7 +34,7 @@ public class IncomeService {
public Income getById(UUID incomeId) {
byte[] idBytes = UuidUtil.uuidToBin(incomeId);
return incomeRepository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Income not found"));
.orElseThrow(() -> new NotFoundException("Ingreso no encontrado"));
}
public List<Income> getByUserId(UUID userId) {
@@ -48,13 +45,13 @@ public class IncomeService {
public Income create(Income income) {
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()) {
throw new BadRequestException("concept is required");
throw new BadRequestException("El concepto es obligatorio");
}
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());
@@ -63,21 +60,21 @@ public class IncomeService {
return incomeRepository.save(income);
}
public Income update(UUID incomeId, IncomeDto.Request dto) {
public Income update(UUID incomeId, Income changes) {
byte[] idBytes = UuidUtil.uuidToBin(incomeId);
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 (dto.getAmount() != null) {
if (dto.getAmount().signum() <= 0) {
throw new ValidationException("amount", "amount must be positive");
if (changes.getConcept() != null) income.setConcept(changes.getConcept());
if (changes.getAmount() != null) {
if (changes.getAmount().signum() <= 0) {
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 (dto.getFrequency() != null) income.setFrequency(dto.getFrequency());
if (changes.getType() != null) income.setType(changes.getType());
if (changes.getFrequency() != null) income.setFrequency(changes.getFrequency());
return incomeRepository.save(income);
}
@@ -86,7 +83,7 @@ public class IncomeService {
byte[] idBytes = UuidUtil.uuidToBin(incomeId);
if (!incomeRepository.existsById(idBytes)) {
throw new NotFoundException("Income not found");
throw new NotFoundException("Ingreso no encontrado");
}
incomeRepository.deleteById(idBytes);

View File

@@ -1,42 +1,42 @@
package net.miarma.backend.huertos.service;
package net.miarma.backend.huertos.service;
import net.miarma.backend.huertos.client.HuertosWebClient;
import net.miarma.backend.huertos.dto.IncomeDto;
import net.miarma.backend.huertos.dto.MemberDto;
import net.miarma.backend.huertos.dto.WaitlistCensoredDto;
import net.miarma.backend.huertos.mapper.HuertosUserMetadataMapper;
import net.miarma.backend.huertos.mapper.IncomeMapper;
import net.miarma.backend.huertos.security.NameCensorer;
import net.miarma.backlib.dto.UserWithCredentialDto;
import net.miarma.backlib.exception.NotFoundException;
import org.springframework.stereotype.Service;
import net.miarma.backend.huertos.client.HuertosWebClient;
import net.miarma.backend.huertos.dto.*;
import net.miarma.backend.huertos.mapper.RequestMapper;
import net.miarma.backend.huertos.mapper.UserMetadataMapper;
import net.miarma.backend.huertos.mapper.IncomeMapper;
import net.miarma.backend.huertos.security.NameCensorer;
import net.miarma.backlib.dto.UserWithCredentialDto;
import net.miarma.backlib.exception.NotFoundException;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
@Service
public class MemberService {
@Service
public class MemberService {
private final HuertosWebClient huertosWebClient;
private final IncomeService incomeService;
private final RequestService requestService;
private final HuertosUserMetadataService metadataService;
private final UserMetadataService metadataService;
public MemberService(HuertosWebClient huertosWebClient,
IncomeService incomeService,
RequestService requestService,
HuertosUserMetadataService metadataService) {
UserMetadataService metadataService) {
this.huertosWebClient = huertosWebClient;
this.incomeService = incomeService;
this.requestService = requestService;
this.metadataService = metadataService;
}
@Cacheable(value = "memberById")
public MemberDto getById(UUID userId) {
var uwc = huertosWebClient.getUserWithCredential(userId, (byte)1);
if (uwc == null) {
throw new NotFoundException("User not found in core");
throw new NotFoundException("Socio no encontrado");
}
var meta = metadataService.getById(userId);
@@ -47,10 +47,11 @@ public class MemberService {
return new MemberDto(
uwc.user(),
uwc.account(),
HuertosUserMetadataMapper.toDto(meta)
UserMetadataMapper.toDto(meta)
);
}
@Cacheable("members")
public List<MemberDto> getAll(Byte serviceId) {
List<UserWithCredentialDto> all = huertosWebClient.getAllUsersWithCredentials(serviceId);
@@ -61,16 +62,42 @@ public class MemberService {
return new MemberDto(
uwc.user(),
uwc.account(),
HuertosUserMetadataMapper.toDto(meta)
UserMetadataMapper.toDto(meta)
);
})
.toList();
}
public MemberProfileDto getMyProfile(UUID userId) {
MemberDto member = 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 new MemberProfileDto(
member.user(),
member.account(),
member.metadata(),
requests,
payments,
hasCollaborator(memberNumber),
hasGreenhouse(memberNumber),
hasCollaboratorRequest(memberNumber),
hasGreenhouseRequest(memberNumber)
);
}
public Integer getLatestMemberNumber() {
return metadataService.getLatestMemberNumber();
}
@Cacheable("waitlist")
public List<MemberDto> getWaitlist() {
List<UserWithCredentialDto> all = huertosWebClient.getAllUsersWithCredentials((byte)1);
@@ -80,7 +107,7 @@ public class MemberService {
.map(uwc -> {
var meta = metadataService.getById(uwc.user().getUserId());
return new MemberDto(uwc.user(), uwc.account(),
HuertosUserMetadataMapper.toDto(meta));
UserMetadataMapper.toDto(meta));
})
.filter(dto -> dto.metadata().getType().equals((byte) 0))
.sorted(Comparator.comparing(dto -> dto.metadata().getCreatedAt()))
@@ -101,21 +128,21 @@ public class MemberService {
return getAll((byte)1).stream()
.filter(dto -> dto.metadata().getMemberNumber().equals(memberNumber))
.findFirst()
.orElseThrow(() -> new NotFoundException("Member not found"));
.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("Member not found"));
.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("Member not found"));
.orElseThrow(() -> new NotFoundException("No hay socio con ese DNI"));
}
public List<IncomeDto.Response> getIncomes(Integer memberNumber) {
@@ -154,10 +181,12 @@ public class MemberService {
}
public Boolean hasCollaboratorRequest(Integer memberNumber) {
return requestService.existsCollaboratorRequest(memberNumber);
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
return requestService.hasPendingCollaboratorRequest(userId);
}
public Boolean hasGreenhouseRequest(Integer memberNumber) {
return requestService.existsGreenhouseRequest(memberNumber);
UUID userId = metadataService.getByMemberNumber(memberNumber).getUserId();
return requestService.hasPendingGreenhouseRequest(userId);
}
}
}

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

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) {
byte[] idBytes = UuidUtil.uuidToBin(incomeId);
return repository.findById(idBytes)
.orElseThrow(() -> new NotFoundException("Income not found"));
.orElseThrow(() -> new NotFoundException("Ingreso no encontrado"));
}
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;
}
}