feat: enhance Firearm entity and add query services with controllers
This commit is contained in:
@@ -23,12 +23,16 @@ public class CorsConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**")
|
||||
.allowedOrigins(properties.allowedOrigins())
|
||||
.allowedHeaders(properties.allowedHeaders())
|
||||
.allowedOrigins(toSafeArray(properties.allowedOrigins()))
|
||||
.allowedHeaders(toSafeArray(properties.allowedHeaders()))
|
||||
.allowedMethods(toHttpMethodNames(properties.allowedMethods()))
|
||||
.allowCredentials(properties.allowCredentials())
|
||||
.maxAge(properties.maxAge().toSeconds())
|
||||
.exposedHeaders(properties.exposedHeaders());
|
||||
.exposedHeaders(toSafeArray(properties.exposedHeaders()));
|
||||
}
|
||||
|
||||
private static String[] toSafeArray(String[] values) {
|
||||
return values == null ? new String[0] : values;
|
||||
}
|
||||
|
||||
private static String[] toHttpMethodNames(HttpMethod[] methods) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.onixbyte.deltaforceguide.controller;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.dto.FirearmResponse;
|
||||
import com.onixbyte.deltaforceguide.domain.dto.PageResponse;
|
||||
import com.onixbyte.deltaforceguide.service.FirearmQueryService;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/firearms")
|
||||
public class FirearmQueryController {
|
||||
|
||||
private final FirearmQueryService firearmQueryService;
|
||||
|
||||
public FirearmQueryController(FirearmQueryService firearmQueryService) {
|
||||
this.firearmQueryService = firearmQueryService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public PageResponse<FirearmResponse> pageQuery(
|
||||
@RequestParam(defaultValue = "0") @Min(0) int page,
|
||||
@RequestParam(defaultValue = "20") @Min(1) @Max(100) int size,
|
||||
@RequestParam(defaultValue = "id") String sortBy,
|
||||
@RequestParam(defaultValue = "DESC") Sort.Direction direction
|
||||
) {
|
||||
return firearmQueryService.pageQuery(PageRequest.of(page, size, Sort.by(direction, sortBy)));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public FirearmResponse queryById(@PathVariable Long id) {
|
||||
return firearmQueryService.queryById(id);
|
||||
}
|
||||
}
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.onixbyte.deltaforceguide.controller;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.dto.ModificationResponse;
|
||||
import com.onixbyte.deltaforceguide.domain.dto.PageResponse;
|
||||
import com.onixbyte.deltaforceguide.service.ModificationQueryService;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/modifications")
|
||||
public class ModificationQueryController {
|
||||
|
||||
private final ModificationQueryService modificationQueryService;
|
||||
|
||||
public ModificationQueryController(ModificationQueryService modificationQueryService) {
|
||||
this.modificationQueryService = modificationQueryService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public PageResponse<ModificationResponse> pageQuery(
|
||||
@RequestParam(defaultValue = "0") @Min(0) int page,
|
||||
@RequestParam(defaultValue = "20") @Min(1) @Max(100) int size,
|
||||
@RequestParam(defaultValue = "id") String sortBy,
|
||||
@RequestParam(defaultValue = "DESC") Sort.Direction direction
|
||||
) {
|
||||
return modificationQueryService.pageQuery(PageRequest.of(page, size, Sort.by(direction, sortBy)));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ModificationResponse queryById(@PathVariable Long id) {
|
||||
return modificationQueryService.queryById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.onixbyte.deltaforceguide.domain.converter;
|
||||
|
||||
import com.onixbyte.deltaforceguide.enumeration.FirearmType;
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Converter;
|
||||
|
||||
@Converter
|
||||
public class FirearmTypeConverter implements AttributeConverter<FirearmType, Integer> {
|
||||
|
||||
@Override
|
||||
public Integer convertToDatabaseColumn(FirearmType attribute) {
|
||||
return attribute == null ? null : attribute.getCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirearmType convertToEntityAttribute(Integer dbData) {
|
||||
return FirearmType.fromCode(dbData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.onixbyte.deltaforceguide.domain.dto;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.entity.Firearm;
|
||||
import com.onixbyte.deltaforceguide.enumeration.FirearmType;
|
||||
|
||||
public record FirearmResponse(
|
||||
Long id,
|
||||
String name,
|
||||
FirearmType type,
|
||||
String level,
|
||||
String review
|
||||
) {
|
||||
public static FirearmResponse from(Firearm firearm) {
|
||||
return new FirearmResponse(
|
||||
firearm.getId(),
|
||||
firearm.getName(),
|
||||
firearm.getType(),
|
||||
firearm.getLevel(),
|
||||
firearm.getReview()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.onixbyte.deltaforceguide.domain.dto;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.entity.Modification;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record ModificationResponse(
|
||||
Long id,
|
||||
Long firearmId,
|
||||
String name,
|
||||
String code,
|
||||
List<String> tags,
|
||||
String note,
|
||||
String author,
|
||||
String videoUrl
|
||||
) {
|
||||
public static ModificationResponse from(Modification modification) {
|
||||
return new ModificationResponse(
|
||||
modification.getId(),
|
||||
modification.getFirearm().getId(),
|
||||
modification.getName(),
|
||||
modification.getCode(),
|
||||
modification.getTags(),
|
||||
modification.getNote(),
|
||||
modification.getAuthor(),
|
||||
modification.getVideoUrl()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.onixbyte.deltaforceguide.domain.dto;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record PageResponse<T>(
|
||||
List<T> items,
|
||||
int page,
|
||||
int size,
|
||||
long totalElements,
|
||||
int totalPages
|
||||
) {
|
||||
public static <T> PageResponse<T> from(Page<T> source) {
|
||||
return new PageResponse<>(
|
||||
source.getContent(),
|
||||
source.getNumber(),
|
||||
source.getSize(),
|
||||
source.getTotalElements(),
|
||||
source.getTotalPages()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.onixbyte.deltaforceguide.domain.entity;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.converter.FirearmTypeConverter;
|
||||
import com.onixbyte.deltaforceguide.enumeration.FirearmType;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Convert;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
@@ -24,10 +27,11 @@ public class Firearm {
|
||||
private String name;
|
||||
|
||||
@Column(name = "type", nullable = false)
|
||||
private Integer type;
|
||||
@Convert(converter = FirearmTypeConverter.class)
|
||||
private FirearmType type;
|
||||
|
||||
@Column(name = "level", nullable = false)
|
||||
private Integer level;
|
||||
private String level;
|
||||
|
||||
@Column(name = "review", columnDefinition = "TEXT")
|
||||
private String review;
|
||||
@@ -51,19 +55,19 @@ public class Firearm {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getType() {
|
||||
public FirearmType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(Integer type) {
|
||||
public void setType(FirearmType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getLevel() {
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(Integer level) {
|
||||
public void setLevel(String level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.onixbyte.deltaforceguide.enumeration;
|
||||
|
||||
public enum FirearmType {
|
||||
|
||||
RIFLE(0),
|
||||
SUB_MACHINE_GUN(1),
|
||||
SHOTGUN(2),
|
||||
LIGHT_MACHINE_GUN(3),
|
||||
DESIGNATED_MARKSMAN_RIFLE(4),
|
||||
SNIPER_RIFLE(5),
|
||||
PISTOL(6),
|
||||
SPECIAL(7);
|
||||
|
||||
private final int code;
|
||||
|
||||
FirearmType(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public static FirearmType fromCode(Integer code) {
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (FirearmType type : values()) {
|
||||
if (type.code == code) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown FirearmType code: " + code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.onixbyte.deltaforceguide.repository;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.entity.Firearm;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface FirearmRepository extends JpaRepository<Firearm, Long> {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.onixbyte.deltaforceguide.repository;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.entity.Modification;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.EntityGraph;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ModificationRepository extends JpaRepository<Modification, Long> {
|
||||
|
||||
@EntityGraph(attributePaths = {"firearm"})
|
||||
Page<Modification> findAllBy(Pageable pageable);
|
||||
|
||||
@Override
|
||||
@EntityGraph(attributePaths = {"firearm"})
|
||||
Optional<Modification> findById(Long id);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.onixbyte.deltaforceguide.service;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.dto.FirearmResponse;
|
||||
import com.onixbyte.deltaforceguide.domain.dto.PageResponse;
|
||||
import com.onixbyte.deltaforceguide.repository.FirearmRepository;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
@Service
|
||||
public class FirearmQueryService {
|
||||
|
||||
private final FirearmRepository firearmRepository;
|
||||
|
||||
public FirearmQueryService(FirearmRepository firearmRepository) {
|
||||
this.firearmRepository = firearmRepository;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public PageResponse<FirearmResponse> pageQuery(Pageable pageable) {
|
||||
return PageResponse.from(
|
||||
firearmRepository.findAll(pageable)
|
||||
.map(FirearmResponse::from)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FirearmResponse queryById(Long id) {
|
||||
return firearmRepository.findById(id)
|
||||
.map(FirearmResponse::from)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Firearm not found: " + id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.onixbyte.deltaforceguide.service;
|
||||
|
||||
import com.onixbyte.deltaforceguide.domain.dto.ModificationResponse;
|
||||
import com.onixbyte.deltaforceguide.domain.dto.PageResponse;
|
||||
import com.onixbyte.deltaforceguide.repository.ModificationRepository;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
@Service
|
||||
public class ModificationQueryService {
|
||||
|
||||
private final ModificationRepository modificationRepository;
|
||||
|
||||
public ModificationQueryService(ModificationRepository modificationRepository) {
|
||||
this.modificationRepository = modificationRepository;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public PageResponse<ModificationResponse> pageQuery(Pageable pageable) {
|
||||
return PageResponse.from(
|
||||
modificationRepository.findAllBy(pageable)
|
||||
.map(ModificationResponse::from)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public ModificationResponse queryById(Long id) {
|
||||
return modificationRepository.findById(id)
|
||||
.map(ModificationResponse::from)
|
||||
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Modification not found: " + id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE firearm
|
||||
MODIFY level VARCHAR(2) NOT NULL;
|
||||
Reference in New Issue
Block a user