From 017c58a2b22f4a994a1a65f0c467775e0c9c86ee Mon Sep 17 00:00:00 2001 From: Daniel Arroyo Date: Sat, 15 Aug 2026 00:46:19 -0400 Subject: [PATCH] refactor(dtos): convert all DTOs to Java records for native-mode Jackson En Quarkus native-image, Jackson no introspecta public fields de clases con normales (deja de refleccionar field metadata). Salia error: No serializer found for class com.l2.shots.auth.AuthMeResponse and no properties discovered to create BeanSerializer Los records tienen auto-accessors (id(), username(), etc) que Jackson serializa nativamente, sin necesidad de reflection o @RegisterForReflection. Convertidos: - auth: AuthMeResponse, AdminUserSummary, Credentials, ChangePasswordRequest, AdminResetPasswordRequest, ErrorBody, MustChangeBody - history: RunSummary, RunDetails, RunItem, RunSnapshot, RunIn, HistoryStats - state: AppState (con Insumos y FormulaDto anidados) Callers actualizados para usar accessors en vez de field access: - AuthService.listUsersForAdmin -> AdminUserSummary.from - AuthService.saveRun -> RunSummary.from / RunDetails.of - AuthResource.register/login -> creds.username() / creds.password() - HistoryResource.saveRun -> input.items() etc Notas: - RunDetails NO puede extender RunSummary en records (JLS no permite extends entre records). Va como record independiente con todos los campos. El JSON que produce matchea la interface RunDetails del frontend (que extendia RunSummary). - HistoryStats ahora se construye de una sola vez al final de computeStats en lugar de ir mutando campos. - MustChangeBody quedo con un constructor no-canonico no-arg para mantener el call site original (new MustChangeBody()). --- .../shots/auth/AdminResetPasswordRequest.java | 4 +- .../com/l2/shots/auth/AdminUserSummary.java | 31 ++++---- .../com/l2/shots/auth/AuthMeResponse.java | 22 ++---- .../java/com/l2/shots/auth/AuthResource.java | 17 ++--- .../java/com/l2/shots/auth/AuthService.java | 2 +- .../l2/shots/auth/ChangePasswordRequest.java | 4 +- .../java/com/l2/shots/auth/Credentials.java | 4 +- .../shots/auth/MustChangePasswordFilter.java | 7 +- .../com/l2/shots/history/HistoryResource.java | 8 +-- .../com/l2/shots/history/HistoryService.java | 71 ++++++++----------- .../com/l2/shots/history/HistoryStats.java | 26 +++---- .../java/com/l2/shots/history/RunDetails.java | 36 +++++++--- src/main/java/com/l2/shots/history/RunIn.java | 20 +++--- .../java/com/l2/shots/history/RunItem.java | 39 +++------- .../com/l2/shots/history/RunSnapshot.java | 13 +--- .../java/com/l2/shots/history/RunSummary.java | 43 ++++++----- .../java/com/l2/shots/state/AppState.java | 66 +++++------------ .../com/l2/shots/state/StateResource.java | 4 +- 18 files changed, 173 insertions(+), 244 deletions(-) diff --git a/src/main/java/com/l2/shots/auth/AdminResetPasswordRequest.java b/src/main/java/com/l2/shots/auth/AdminResetPasswordRequest.java index 789b71b..bcb1f32 100644 --- a/src/main/java/com/l2/shots/auth/AdminResetPasswordRequest.java +++ b/src/main/java/com/l2/shots/auth/AdminResetPasswordRequest.java @@ -1,6 +1,4 @@ package com.l2.shots.auth; -public class AdminResetPasswordRequest { - public String username; - public String newPassword; +public record AdminResetPasswordRequest(String username, String newPassword) { } diff --git a/src/main/java/com/l2/shots/auth/AdminUserSummary.java b/src/main/java/com/l2/shots/auth/AdminUserSummary.java index 35181f8..587a311 100644 --- a/src/main/java/com/l2/shots/auth/AdminUserSummary.java +++ b/src/main/java/com/l2/shots/auth/AdminUserSummary.java @@ -3,22 +3,21 @@ package com.l2.shots.auth; import java.time.Instant; import java.util.UUID; -public class AdminUserSummary { - public UUID id; - public String username; - public Instant createdAt; - public Instant lastLoginAt; - public boolean isAdmin; - public boolean mustChangePassword; +public record AdminUserSummary( + UUID id, + String username, + Instant createdAt, + Instant lastLoginAt, + boolean isAdmin, + boolean mustChangePassword) { - public AdminUserSummary() {} - - public AdminUserSummary(User u) { - this.id = u.id; - this.username = u.username; - this.createdAt = u.createdAt; - this.lastLoginAt = u.lastLoginAt; - this.isAdmin = u.isAdmin; - this.mustChangePassword = u.mustChangePassword; + public static AdminUserSummary from(User u) { + return new AdminUserSummary( + u.id, + u.username, + u.createdAt, + u.lastLoginAt, + u.isAdmin, + u.mustChangePassword); } } diff --git a/src/main/java/com/l2/shots/auth/AuthMeResponse.java b/src/main/java/com/l2/shots/auth/AuthMeResponse.java index 2c925bb..40184a1 100644 --- a/src/main/java/com/l2/shots/auth/AuthMeResponse.java +++ b/src/main/java/com/l2/shots/auth/AuthMeResponse.java @@ -3,20 +3,10 @@ package com.l2.shots.auth; import java.time.Instant; import java.util.UUID; -public class AuthMeResponse { - public UUID id; - public String username; - public Instant createdAt; - public boolean mustChangePassword; - public boolean isAdmin; - - public AuthMeResponse() {} - - public AuthMeResponse(UUID id, String username, Instant createdAt, boolean mustChangePassword, boolean isAdmin) { - this.id = id; - this.username = username; - this.createdAt = createdAt; - this.mustChangePassword = mustChangePassword; - this.isAdmin = isAdmin; - } +public record AuthMeResponse( + UUID id, + String username, + Instant createdAt, + boolean mustChangePassword, + boolean isAdmin) { } diff --git a/src/main/java/com/l2/shots/auth/AuthResource.java b/src/main/java/com/l2/shots/auth/AuthResource.java index e8fc729..e41585f 100644 --- a/src/main/java/com/l2/shots/auth/AuthResource.java +++ b/src/main/java/com/l2/shots/auth/AuthResource.java @@ -42,7 +42,7 @@ public class AuthResource { @POST @Path("/register") public Response register(Credentials creds) { - Optional result = authService.register(creds.username, creds.password); + Optional result = authService.register(creds.username(), creds.password()); if (result.isEmpty()) { return Response.status(409) .entity(new ErrorBody("username no disponible o datos inválidos")) @@ -58,7 +58,7 @@ public class AuthResource { @POST @Path("/login") public Response login(Credentials creds) { - Optional result = authService.authenticate(creds.username, creds.password); + Optional result = authService.authenticate(creds.username(), creds.password()); if (result.isEmpty()) { return Response.status(401) .entity(new ErrorBody("credenciales inválidas")) @@ -83,7 +83,7 @@ public class AuthResource { @Path("/change-password") @Authenticated public Response changePassword(@Context HttpHeaders headers, ChangePasswordRequest body) { - if (body == null || body.currentPassword == null || body.newPassword == null) { + if (body == null || body.currentPassword() == null || body.newPassword() == null) { return Response.status(400).entity(new ErrorBody("Faltan campos requeridos")).build(); } Optional jwt = jwtCookieAuth.extractToken(headers); @@ -91,7 +91,7 @@ public class AuthResource { Optional user = authService.getEntityFromToken(jwt.get()); if (user.isEmpty()) return Response.status(401).build(); AuthService.ChangePasswordResult result = authService.changePassword( - user.get().id, body.currentPassword, body.newPassword); + user.get().id, body.currentPassword(), body.newPassword()); switch (result) { case OK: User refreshed = User.findById(user.get().id); @@ -116,7 +116,7 @@ public class AuthResource { @Path("/admin/reset-password") @RolesAllowed("admin") public Response adminResetPassword(AdminResetPasswordRequest body) { - if (body == null || body.username == null || body.newPassword == null) { + if (body == null || body.username() == null || body.newPassword() == null) { return Response.status(400).entity(new ErrorBody("Faltan campos requeridos")).build(); } UUID requesterId; @@ -125,7 +125,7 @@ public class AuthResource { } catch (Exception e) { return Response.status(401).build(); } - boolean ok = authService.resetPasswordAsAdmin(requesterId, body.username, body.newPassword); + boolean ok = authService.resetPasswordAsAdmin(requesterId, body.username(), body.newPassword()); if (!ok) { return Response.status(400).entity(new ErrorBody("Usuario no encontrado o contraseña inválida")).build(); } @@ -180,9 +180,6 @@ public class AuthResource { .build(); } - public static class ErrorBody { - public String error; - public ErrorBody() {} - public ErrorBody(String error) { this.error = error; } + public record ErrorBody(String error) { } } diff --git a/src/main/java/com/l2/shots/auth/AuthService.java b/src/main/java/com/l2/shots/auth/AuthService.java index 15349c7..395d94e 100644 --- a/src/main/java/com/l2/shots/auth/AuthService.java +++ b/src/main/java/com/l2/shots/auth/AuthService.java @@ -77,7 +77,7 @@ public class AuthService { public java.util.List listUsersForAdmin() { return User.listAll().stream() - .map(AdminUserSummary::new) + .map(AdminUserSummary::from) .collect(java.util.stream.Collectors.toList()); } diff --git a/src/main/java/com/l2/shots/auth/ChangePasswordRequest.java b/src/main/java/com/l2/shots/auth/ChangePasswordRequest.java index cc66d9b..817f9db 100644 --- a/src/main/java/com/l2/shots/auth/ChangePasswordRequest.java +++ b/src/main/java/com/l2/shots/auth/ChangePasswordRequest.java @@ -1,6 +1,4 @@ package com.l2.shots.auth; -public class ChangePasswordRequest { - public String currentPassword; - public String newPassword; +public record ChangePasswordRequest(String currentPassword, String newPassword) { } diff --git a/src/main/java/com/l2/shots/auth/Credentials.java b/src/main/java/com/l2/shots/auth/Credentials.java index 21f7dcd..369d3d2 100644 --- a/src/main/java/com/l2/shots/auth/Credentials.java +++ b/src/main/java/com/l2/shots/auth/Credentials.java @@ -1,6 +1,4 @@ package com.l2.shots.auth; -public class Credentials { - public String username; - public String password; +public record Credentials(String username, String password) { } diff --git a/src/main/java/com/l2/shots/auth/MustChangePasswordFilter.java b/src/main/java/com/l2/shots/auth/MustChangePasswordFilter.java index d2dfcf1..699d44f 100644 --- a/src/main/java/com/l2/shots/auth/MustChangePasswordFilter.java +++ b/src/main/java/com/l2/shots/auth/MustChangePasswordFilter.java @@ -60,8 +60,9 @@ public class MustChangePasswordFilter implements ContainerRequestFilter { .build()); } - public static class MustChangeBody { - public String error = "Debe cambiar la contraseña antes de continuar"; - public boolean mustChangePassword = true; + public record MustChangeBody(String error, boolean mustChangePassword) { + public MustChangeBody() { + this("Debe cambiar la contraseña antes de continuar", true); + } } } diff --git a/src/main/java/com/l2/shots/history/HistoryResource.java b/src/main/java/com/l2/shots/history/HistoryResource.java index 0cdd162..ffc4d2c 100644 --- a/src/main/java/com/l2/shots/history/HistoryResource.java +++ b/src/main/java/com/l2/shots/history/HistoryResource.java @@ -36,16 +36,16 @@ public class HistoryResource { Optional userId = extractUserId(headers); if (userId.isEmpty()) return Response.status(401).build(); - if (input == null || input.items == null || input.snapshot == null) { + if (input == null || input.items() == null || input.snapshot() == null) { return Response.status(400).entity("{\"error\":\"payload inválido\"}").build(); } - if (input.items.size() > 100) { + if (input.items().size() > 100) { return Response.status(400).entity("{\"error\":\"demasiados items\"}").build(); } - if (input.label != null && input.label.length() > 100) { + if (input.label() != null && input.label().length() > 100) { return Response.status(400).entity("{\"error\":\"label demasiado largo\"}").build(); } - if (input.totalCristalesUsed <= 0) { + if (input.totalCristalesUsed() <= 0) { return Response.status(400).entity("{\"error\":\"no hay cristales usados\"}").build(); } diff --git a/src/main/java/com/l2/shots/history/HistoryService.java b/src/main/java/com/l2/shots/history/HistoryService.java index 9f48f69..9db887d 100644 --- a/src/main/java/com/l2/shots/history/HistoryService.java +++ b/src/main/java/com/l2/shots/history/HistoryService.java @@ -18,7 +18,7 @@ public class HistoryService { public List listForUser(UUID userId) { return ProductionRun.list("userId = ?1 ORDER BY createdAt DESC", userId) .stream() - .map(RunSummary::new) + .map(RunSummary::from) .toList(); } @@ -29,7 +29,7 @@ public class HistoryService { List items = mapper.readValue(entity.itemsJson, mapper.getTypeFactory() .constructCollectionType(List.class, RunItem.class)); RunSnapshot snapshot = mapper.readValue(entity.snapshotJson, RunSnapshot.class); - return Optional.of(new RunDetails(entity, items, snapshot)); + return Optional.of(RunDetails.of(entity, items, snapshot)); } catch (JsonProcessingException e) { return Optional.empty(); } @@ -41,21 +41,21 @@ public class HistoryService { entity.id = UUID.randomUUID(); entity.userId = userId; entity.createdAt = Instant.now(); - entity.label = input.label; - entity.totalCost = input.totalCost; - entity.totalSale = input.totalSale; - entity.totalProfit = input.totalProfit; - entity.totalShots = input.totalShots; - entity.totalCristalesUsed = input.totalCristalesUsed; - entity.totalOreUsed = input.totalOreUsed; + entity.label = input.label(); + entity.totalCost = input.totalCost(); + entity.totalSale = input.totalSale(); + entity.totalProfit = input.totalProfit(); + entity.totalShots = input.totalShots(); + entity.totalCristalesUsed = input.totalCristalesUsed(); + entity.totalOreUsed = input.totalOreUsed(); try { - entity.itemsJson = mapper.writeValueAsString(input.items); - entity.snapshotJson = mapper.writeValueAsString(input.snapshot); + entity.itemsJson = mapper.writeValueAsString(input.items()); + entity.snapshotJson = mapper.writeValueAsString(input.snapshot()); } catch (JsonProcessingException e) { throw new RuntimeException("Failed to serialize run payload", e); } entity.persist(); - return new RunSummary(entity); + return RunSummary.from(entity); } @Transactional @@ -67,22 +67,8 @@ public class HistoryService { List runs = ProductionRun.list( "userId = ?1 ORDER BY createdAt DESC", userId); - HistoryStats stats = new HistoryStats(); - stats.totalRuns = runs.size(); - if (runs.isEmpty()) { - stats.totalCost = 0; - stats.totalSale = 0; - stats.totalProfit = 0; - stats.totalShots = 0; - stats.avgProfit = 0; - stats.avgCost = 0; - stats.avgSale = 0; - stats.bestRun = null; - stats.worstRun = null; - stats.last5Avg = 0; - stats.last10Avg = 0; - return stats; + return new HistoryStats(0, 0, 0, 0, 0, 0, 0, 0, null, null, 0, 0); } long totalCost = 0; @@ -101,27 +87,28 @@ public class HistoryService { if (r.totalProfit < worst.totalProfit) worst = r; } - stats.totalCost = totalCost; - stats.totalSale = totalSale; - stats.totalProfit = totalProfit; - stats.totalShots = totalShots; - stats.avgProfit = totalProfit / runs.size(); - stats.avgCost = totalCost / runs.size(); - stats.avgSale = totalSale / runs.size(); - stats.bestRun = new RunSummary(best); - stats.worstRun = new RunSummary(worst); - - int n5 = Math.min(5, runs.size()); - int n10 = Math.min(10, runs.size()); + int n = runs.size(); + int n5 = Math.min(5, n); + int n10 = Math.min(10, n); long sum5 = 0; long sum10 = 0; for (int i = 0; i < n10; i++) { sum10 += runs.get(i).totalProfit; if (i < n5) sum5 += runs.get(i).totalProfit; } - stats.last5Avg = n5 > 0 ? sum5 / n5 : 0; - stats.last10Avg = n10 > 0 ? sum10 / n10 : 0; - return stats; + return new HistoryStats( + n, + totalCost, + totalSale, + totalProfit, + totalShots, + totalProfit / n, + totalCost / n, + totalSale / n, + RunSummary.from(best), + RunSummary.from(worst), + n5 > 0 ? sum5 / n5 : 0, + n10 > 0 ? sum10 / n10 : 0); } } diff --git a/src/main/java/com/l2/shots/history/HistoryStats.java b/src/main/java/com/l2/shots/history/HistoryStats.java index 2b7b2a1..72a6ed9 100644 --- a/src/main/java/com/l2/shots/history/HistoryStats.java +++ b/src/main/java/com/l2/shots/history/HistoryStats.java @@ -1,16 +1,16 @@ package com.l2.shots.history; -public class HistoryStats { - public int totalRuns; - public long totalCost; - public long totalSale; - public long totalProfit; - public long totalShots; - public long avgProfit; - public long avgCost; - public long avgSale; - public RunSummary bestRun; - public RunSummary worstRun; - public long last5Avg; - public long last10Avg; +public record HistoryStats( + int totalRuns, + long totalCost, + long totalSale, + long totalProfit, + long totalShots, + long avgProfit, + long avgCost, + long avgSale, + RunSummary bestRun, + RunSummary worstRun, + long last5Avg, + long last10Avg) { } diff --git a/src/main/java/com/l2/shots/history/RunDetails.java b/src/main/java/com/l2/shots/history/RunDetails.java index 4980b55..5a0fac0 100644 --- a/src/main/java/com/l2/shots/history/RunDetails.java +++ b/src/main/java/com/l2/shots/history/RunDetails.java @@ -1,16 +1,34 @@ package com.l2.shots.history; +import java.time.Instant; import java.util.List; +import java.util.UUID; -public class RunDetails extends RunSummary { - public List items; - public RunSnapshot snapshot; +public record RunDetails( + UUID id, + Instant createdAt, + String label, + long totalCost, + long totalSale, + long totalProfit, + long totalShots, + long totalCristalesUsed, + long totalOreUsed, + List items, + RunSnapshot snapshot) { - public RunDetails() {} - - public RunDetails(ProductionRun r, List items, RunSnapshot snapshot) { - super(r); - this.items = items; - this.snapshot = snapshot; + public static RunDetails of(ProductionRun r, List items, RunSnapshot snapshot) { + return new RunDetails( + r.id, + r.createdAt, + r.label, + r.totalCost, + r.totalSale, + r.totalProfit, + r.totalShots, + r.totalCristalesUsed, + r.totalOreUsed, + items, + snapshot); } } diff --git a/src/main/java/com/l2/shots/history/RunIn.java b/src/main/java/com/l2/shots/history/RunIn.java index f758e06..21649fc 100644 --- a/src/main/java/com/l2/shots/history/RunIn.java +++ b/src/main/java/com/l2/shots/history/RunIn.java @@ -2,14 +2,14 @@ package com.l2.shots.history; import java.util.List; -public class RunIn { - public String label; - public long totalCost; - public long totalSale; - public long totalProfit; - public long totalShots; - public long totalCristalesUsed; - public long totalOreUsed; - public List items; - public RunSnapshot snapshot; +public record RunIn( + String label, + long totalCost, + long totalSale, + long totalProfit, + long totalShots, + long totalCristalesUsed, + long totalOreUsed, + List items, + RunSnapshot snapshot) { } diff --git a/src/main/java/com/l2/shots/history/RunItem.java b/src/main/java/com/l2/shots/history/RunItem.java index 4e50daf..e578332 100644 --- a/src/main/java/com/l2/shots/history/RunItem.java +++ b/src/main/java/com/l2/shots/history/RunItem.java @@ -1,31 +1,14 @@ package com.l2.shots.history; -public class RunItem { - public String tipo; - public String grado; - public int cristalesDisponibles; - public int cristalesUsados; - public int oreNecesario; - public int crafteosPosibles; - public int shotsObtenidos; - public long costoTotal; - public long valorVenta; - public long ganancia; - - public RunItem() {} - - public RunItem(String tipo, String grado, int cristalesDisponibles, int cristalesUsados, - int oreNecesario, int crafteosPosibles, int shotsObtenidos, - long costoTotal, long valorVenta, long ganancia) { - this.tipo = tipo; - this.grado = grado; - this.cristalesDisponibles = cristalesDisponibles; - this.cristalesUsados = cristalesUsados; - this.oreNecesario = oreNecesario; - this.crafteosPosibles = crafteosPosibles; - this.shotsObtenidos = shotsObtenidos; - this.costoTotal = costoTotal; - this.valorVenta = valorVenta; - this.ganancia = ganancia; - } +public record RunItem( + String tipo, + String grado, + int cristalesDisponibles, + int cristalesUsados, + int oreNecesario, + int crafteosPosibles, + int shotsObtenidos, + long costoTotal, + long valorVenta, + long ganancia) { } diff --git a/src/main/java/com/l2/shots/history/RunSnapshot.java b/src/main/java/com/l2/shots/history/RunSnapshot.java index 0243d2a..8bbaf46 100644 --- a/src/main/java/com/l2/shots/history/RunSnapshot.java +++ b/src/main/java/com/l2/shots/history/RunSnapshot.java @@ -3,14 +3,7 @@ package com.l2.shots.history; import java.util.List; import java.util.Map; -public class RunSnapshot { - public Map insumos; - public List> formulas; - - public RunSnapshot() {} - - public RunSnapshot(Map insumos, List> formulas) { - this.insumos = insumos; - this.formulas = formulas; - } +public record RunSnapshot( + Map insumos, + List> formulas) { } diff --git a/src/main/java/com/l2/shots/history/RunSummary.java b/src/main/java/com/l2/shots/history/RunSummary.java index 4b219c1..e0ef5c2 100644 --- a/src/main/java/com/l2/shots/history/RunSummary.java +++ b/src/main/java/com/l2/shots/history/RunSummary.java @@ -3,28 +3,27 @@ package com.l2.shots.history; import java.time.Instant; import java.util.UUID; -public class RunSummary { - public UUID id; - public Instant createdAt; - public String label; - public long totalCost; - public long totalSale; - public long totalProfit; - public long totalShots; - public long totalCristalesUsed; - public long totalOreUsed; +public record RunSummary( + UUID id, + Instant createdAt, + String label, + long totalCost, + long totalSale, + long totalProfit, + long totalShots, + long totalCristalesUsed, + long totalOreUsed) { - public RunSummary() {} - - public RunSummary(ProductionRun r) { - this.id = r.id; - this.createdAt = r.createdAt; - this.label = r.label; - this.totalCost = r.totalCost; - this.totalSale = r.totalSale; - this.totalProfit = r.totalProfit; - this.totalShots = r.totalShots; - this.totalCristalesUsed = r.totalCristalesUsed; - this.totalOreUsed = r.totalOreUsed; + public static RunSummary from(ProductionRun r) { + return new RunSummary( + r.id, + r.createdAt, + r.label, + r.totalCost, + r.totalSale, + r.totalProfit, + r.totalShots, + r.totalCristalesUsed, + r.totalOreUsed); } } diff --git a/src/main/java/com/l2/shots/state/AppState.java b/src/main/java/com/l2/shots/state/AppState.java index 64268a5..f137392 100644 --- a/src/main/java/com/l2/shots/state/AppState.java +++ b/src/main/java/com/l2/shots/state/AppState.java @@ -3,57 +3,25 @@ package com.l2.shots.state; import java.util.List; import java.util.Map; -public class AppState { +public record AppState( + Insumos insumos, + List formulas, + Map> disponibles) { - public Insumos insumos; - public List formulas; - public Map> disponibles; - - public AppState() {} - - public AppState(Insumos insumos, List formulas, Map> disponibles) { - this.insumos = insumos; - this.formulas = formulas; - this.disponibles = disponibles; + public record Insumos( + Map cristales, + int soulOre, + int spiritOre, + Map> venta) { } - public static class Insumos { - public Map cristales; - public int soulOre; - public int spiritOre; - public Map> venta; - - public Insumos() {} - - public Insumos(Map cristales, int soulOre, int spiritOre, - Map> venta) { - this.cristales = cristales; - this.soulOre = soulOre; - this.spiritOre = spiritOre; - this.venta = venta; - } - } - - public static class FormulaDto { - public String id; - public String tipo; - public String grado; - public int cristalesReq; - public Integer soulOreReq; - public Integer spiritOreReq; - public int shotsObtenidos; - - public FormulaDto() {} - - public FormulaDto(String id, String tipo, String grado, int cristalesReq, - Integer soulOreReq, Integer spiritOreReq, int shotsObtenidos) { - this.id = id; - this.tipo = tipo; - this.grado = grado; - this.cristalesReq = cristalesReq; - this.soulOreReq = soulOreReq; - this.spiritOreReq = spiritOreReq; - this.shotsObtenidos = shotsObtenidos; - } + public record FormulaDto( + String id, + String tipo, + String grado, + int cristalesReq, + Integer soulOreReq, + Integer spiritOreReq, + int shotsObtenidos) { } } diff --git a/src/main/java/com/l2/shots/state/StateResource.java b/src/main/java/com/l2/shots/state/StateResource.java index b0b14fd..b64d7e2 100644 --- a/src/main/java/com/l2/shots/state/StateResource.java +++ b/src/main/java/com/l2/shots/state/StateResource.java @@ -43,10 +43,10 @@ public class StateResource { Optional userId = extractUserId(headers); if (userId.isEmpty()) return Response.status(401).build(); - if (state == null || state.insumos == null || state.formulas == null || state.disponibles == null) { + if (state == null || state.insumos() == null || state.formulas() == null || state.disponibles() == null) { return Response.status(400).entity("{\"error\":\"estado inválido\"}").build(); } - if (state.formulas.size() > 200) { + if (state.formulas().size() > 200) { return Response.status(400).entity("{\"error\":\"estado demasiado grande\"}").build(); } stateService.saveForUser(userId.get(), state);