fix(dtos): annotate records with @RegisterForReflection for native Jackson
CI / Build Native (push) Successful in 6m18s

Las clases record NO se serializan bien en Quarkus 3.20.1 native-image
aunque Jackson 2.17+ las soporta en JVM. GraalVM strip-ea la metadata
<Erecord> del bytecode mas los accessors auto-generados, y Jackson no
puede detectar que la clase es un record -> cae al BeanSerializer
clasico -> 'no properties discovered to create BeanSerializer'.

@RegisterForReflection le indica a Quarkus: incluí esta clase en la
metadata de reflexion del native-image, asi Jackson la ve completa.

Aplicado a los 16 DTOs (records + nested records):
- auth: AuthMeResponse, AdminUserSummary, Credentials,
        ChangePasswordRequest, AdminResetPasswordRequest, ErrorBody,
        MustChangeBody
- history: RunSummary, RunDetails, RunItem, RunSnapshot, RunIn,
           HistoryStats
- state: AppState + Insumos + FormulaDto (nested)
This commit is contained in:
2026-08-15 01:10:47 -04:00
parent 017c58a2b2
commit cc09fe8943
14 changed files with 41 additions and 0 deletions
@@ -1,4 +1,7 @@
package com.l2.shots.auth; package com.l2.shots.auth;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public record AdminResetPasswordRequest(String username, String newPassword) { public record AdminResetPasswordRequest(String username, String newPassword) {
} }
@@ -1,8 +1,11 @@
package com.l2.shots.auth; package com.l2.shots.auth;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.time.Instant; import java.time.Instant;
import java.util.UUID; import java.util.UUID;
@RegisterForReflection
public record AdminUserSummary( public record AdminUserSummary(
UUID id, UUID id,
String username, String username,
@@ -1,8 +1,11 @@
package com.l2.shots.auth; package com.l2.shots.auth;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.time.Instant; import java.time.Instant;
import java.util.UUID; import java.util.UUID;
@RegisterForReflection
public record AuthMeResponse( public record AuthMeResponse(
UUID id, UUID id,
String username, String username,
@@ -180,6 +180,7 @@ public class AuthResource {
.build(); .build();
} }
@io.quarkus.runtime.annotations.RegisterForReflection
public record ErrorBody(String error) { public record ErrorBody(String error) {
} }
} }
@@ -1,4 +1,7 @@
package com.l2.shots.auth; package com.l2.shots.auth;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public record ChangePasswordRequest(String currentPassword, String newPassword) { public record ChangePasswordRequest(String currentPassword, String newPassword) {
} }
@@ -1,4 +1,7 @@
package com.l2.shots.auth; package com.l2.shots.auth;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public record Credentials(String username, String password) { public record Credentials(String username, String password) {
} }
@@ -11,6 +11,7 @@ import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
import org.eclipse.microprofile.jwt.JsonWebToken; import org.eclipse.microprofile.jwt.JsonWebToken;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.util.Optional; import java.util.Optional;
@@ -60,6 +61,7 @@ public class MustChangePasswordFilter implements ContainerRequestFilter {
.build()); .build());
} }
@RegisterForReflection
public record MustChangeBody(String error, boolean mustChangePassword) { public record MustChangeBody(String error, boolean mustChangePassword) {
public MustChangeBody() { public MustChangeBody() {
this("Debe cambiar la contraseña antes de continuar", true); this("Debe cambiar la contraseña antes de continuar", true);
@@ -1,5 +1,8 @@
package com.l2.shots.history; package com.l2.shots.history;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public record HistoryStats( public record HistoryStats(
int totalRuns, int totalRuns,
long totalCost, long totalCost,
@@ -1,9 +1,12 @@
package com.l2.shots.history; package com.l2.shots.history;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@RegisterForReflection
public record RunDetails( public record RunDetails(
UUID id, UUID id,
Instant createdAt, Instant createdAt,
@@ -1,7 +1,10 @@
package com.l2.shots.history; package com.l2.shots.history;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.util.List; import java.util.List;
@RegisterForReflection
public record RunIn( public record RunIn(
String label, String label,
long totalCost, long totalCost,
@@ -1,5 +1,8 @@
package com.l2.shots.history; package com.l2.shots.history;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public record RunItem( public record RunItem(
String tipo, String tipo,
String grado, String grado,
@@ -1,8 +1,11 @@
package com.l2.shots.history; package com.l2.shots.history;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@RegisterForReflection
public record RunSnapshot( public record RunSnapshot(
Map<String, Object> insumos, Map<String, Object> insumos,
List<Map<String, Object>> formulas) { List<Map<String, Object>> formulas) {
@@ -1,8 +1,11 @@
package com.l2.shots.history; package com.l2.shots.history;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.time.Instant; import java.time.Instant;
import java.util.UUID; import java.util.UUID;
@RegisterForReflection
public record RunSummary( public record RunSummary(
UUID id, UUID id,
Instant createdAt, Instant createdAt,
@@ -1,13 +1,17 @@
package com.l2.shots.state; package com.l2.shots.state;
import io.quarkus.runtime.annotations.RegisterForReflection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@RegisterForReflection
public record AppState( public record AppState(
Insumos insumos, Insumos insumos,
List<FormulaDto> formulas, List<FormulaDto> formulas,
Map<String, Map<String, Integer>> disponibles) { Map<String, Map<String, Integer>> disponibles) {
@RegisterForReflection
public record Insumos( public record Insumos(
Map<String, Integer> cristales, Map<String, Integer> cristales,
int soulOre, int soulOre,
@@ -15,6 +19,7 @@ public record AppState(
Map<String, Map<String, Integer>> venta) { Map<String, Map<String, Integer>> venta) {
} }
@RegisterForReflection
public record FormulaDto( public record FormulaDto(
String id, String id,
String tipo, String tipo,