ProductRequest.java
package com.rbctcsworld.ecommerce.product;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;
import java.math.BigDecimal;
public record ProductRequest(
@NotBlank @Size(max = 255) String name,
@NotBlank @Size(max = 100) String sku,
@Size(max = 100) String category,
@NotNull @Positive @Digits(integer = 10, fraction = 2) BigDecimal price,
@NotNull @Min(0) Integer stock,
/**
* Optional picture: the storefront's own image (/products/name.svg|png|jpg|webp) or an https:// link.
* Anything else (javascript:, data:, http://, quotes or spaces) is refused with 400.
*/
@Size(max = 500)
@Pattern(regexp = "^(/products/[a-z0-9][a-z0-9-]*\\.(svg|png|jpg|webp)|https://[^\\s\"'<>]+)$",
message = "must be /products/<name>.svg|png|jpg|webp or an https:// link")
String imageUrl,
/** Variant group shared by the options of one item: letters, digits and dashes, 2-40 (stored in upper case). */
@Size(max = 40) @Pattern(regexp = "^\\s*$|^\\s*[A-Za-z0-9][A-Za-z0-9-]{1,39}\\s*$",
message = "must be 2-40 letters, digits or dashes") String variantGroup,
/** S, M, XL, 10.5, 12 oz ... */
@Size(max = 20) @Pattern(regexp = "^[\\p{L}\\p{N} ./-]*$", message = "may only contain letters, digits, spaces, . / and -")
String size,
/** Navy, Heather Grey ... */
@Size(max = 30) @Pattern(regexp = "^[\\p{L} -]*$", message = "may only contain letters, spaces and -")
String color,
/** Optional flash deal: a price below the normal price between two UTC times (all three, or none). */
@Positive @Digits(integer = 10, fraction = 2) BigDecimal dealPrice,
java.time.LocalDateTime dealStartsAt,
java.time.LocalDateTime dealEndsAt) {
/** Without a deal (older clients, tests). */
public ProductRequest(String name, String sku, String category, BigDecimal price, Integer stock, String imageUrl,
String variantGroup, String size, String color) {
this(name, sku, category, price, stock, imageUrl, variantGroup, size, color, null, null, null);
}
/** Without variant (older clients, tests). */
public ProductRequest(String name, String sku, String category, BigDecimal price, Integer stock, String imageUrl) {
this(name, sku, category, price, stock, imageUrl, null, null, null, null, null, null);
}
/** Without a picture (older clients, tests). */
public ProductRequest(String name, String sku, String category, BigDecimal price, Integer stock) {
this(name, sku, category, price, stock, null);
}
}