diff --git a/src/main/java/com/onixbyte/deltaforceguide/DeltaForceGuideApplication.java b/src/main/java/com/onixbyte/deltaforceguide/DeltaForceGuideApplication.java index 4d69512..a23fb88 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/DeltaForceGuideApplication.java +++ b/src/main/java/com/onixbyte/deltaforceguide/DeltaForceGuideApplication.java @@ -3,6 +3,11 @@ package com.onixbyte.deltaforceguide; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +/** + * Entry point for the Delta Force Guide Server application. + * + * @author zihluwang + */ @SpringBootApplication public class DeltaForceGuideApplication { diff --git a/src/main/java/com/onixbyte/deltaforceguide/client/TokenClient.java b/src/main/java/com/onixbyte/deltaforceguide/client/TokenClient.java index d4b745c..a7ad3f1 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/client/TokenClient.java +++ b/src/main/java/com/onixbyte/deltaforceguide/client/TokenClient.java @@ -12,6 +12,11 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; +/** + * Client for generating and verifying JSON Web Tokens using the Auth0 java-jwt library. + * + * @author zihluwang + */ @Component public class TokenClient { diff --git a/src/main/java/com/onixbyte/deltaforceguide/config/CorsConfig.java b/src/main/java/com/onixbyte/deltaforceguide/config/CorsConfig.java index 291695b..1e13243 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/config/CorsConfig.java +++ b/src/main/java/com/onixbyte/deltaforceguide/config/CorsConfig.java @@ -12,10 +12,21 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import java.util.List; import java.util.stream.Stream; +/** + * Configuration for CORS (Cross-Origin Resource Sharing) policies. + * + * @author zihluwang + */ @Configuration @EnableConfigurationProperties({CorsProperties.class}) public class CorsConfig { + /** + * Creates the CORS configuration source with properties from configuration. + * + * @param properties the CORS configuration properties + * @return the CORS configuration source + */ @Bean public CorsConfigurationSource corsConfigurationSource( CorsProperties properties diff --git a/src/main/java/com/onixbyte/deltaforceguide/config/JacksonConfig.java b/src/main/java/com/onixbyte/deltaforceguide/config/JacksonConfig.java index a64a1ea..895bcd1 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/config/JacksonConfig.java +++ b/src/main/java/com/onixbyte/deltaforceguide/config/JacksonConfig.java @@ -6,6 +6,11 @@ import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilde import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +/** + * Configuration for Jackson JSON serialisation and deserialisation settings. + * + * @author zihluwang + */ @Configuration public class JacksonConfig { diff --git a/src/main/java/com/onixbyte/deltaforceguide/config/MyBatisConfig.java b/src/main/java/com/onixbyte/deltaforceguide/config/MyBatisConfig.java index 61acbfc..0e2ae74 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/config/MyBatisConfig.java +++ b/src/main/java/com/onixbyte/deltaforceguide/config/MyBatisConfig.java @@ -3,6 +3,11 @@ package com.onixbyte.deltaforceguide.config; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration; +/** + * Configuration for MyBatis SQL mapping framework integration. + * + * @author zihluwang + */ @Configuration @MapperScan(basePackages = {"com.onixbyte.deltaforceguide.mapper"}) public class MyBatisConfig { diff --git a/src/main/java/com/onixbyte/deltaforceguide/config/SecurityConfig.java b/src/main/java/com/onixbyte/deltaforceguide/config/SecurityConfig.java index 8e8cc50..b32a691 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/config/SecurityConfig.java +++ b/src/main/java/com/onixbyte/deltaforceguide/config/SecurityConfig.java @@ -23,12 +23,23 @@ import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.ExceptionTranslationFilter; import org.springframework.web.cors.CorsConfigurationSource; +/** + * Spring Security configuration defining authentication, authorisation, and filter chains. + * + * @author zihluwang + */ @Configuration @EnableWebSecurity @EnableMethodSecurity @EnableConfigurationProperties({TokenProperties.class, CookieProperties.class}) public class SecurityConfig { + /** + * Configures the HTTP security filter chain including endpoint authorisation and JWT filter. + * + * @param http the HTTP security builder + * @return the configured security filter chain + */ @Bean public SecurityFilterChain securityFilterChain( HttpSecurity httpSecurity, @@ -48,11 +59,20 @@ public class SecurityConfig { .build(); } + /** + * Provides the BCrypt password encoder for credential hashing. + * @return the BCrypt password encoder + */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } + /** + * Provides the authentication manager for the security configuration. + * + * @return the authentication manager + */ @Bean public AuthenticationManager authenticationManager( UsernamePasswordAuthenticationProvider usernamePasswordAuthenticationProvider diff --git a/src/main/java/com/onixbyte/deltaforceguide/config/SpringDataConfig.java b/src/main/java/com/onixbyte/deltaforceguide/config/SpringDataConfig.java index 44e3a4c..1dfe3ff 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/config/SpringDataConfig.java +++ b/src/main/java/com/onixbyte/deltaforceguide/config/SpringDataConfig.java @@ -3,6 +3,11 @@ package com.onixbyte.deltaforceguide.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +/** + * Configuration for Spring Data JPA auditing and repository settings. + * + * @author zihluwang + */ @Configuration @EnableJpaRepositories(basePackages = {"com.onixbyte.deltaforceguide.repository"}) public class SpringDataConfig { diff --git a/src/main/java/com/onixbyte/deltaforceguide/controller/AuthController.java b/src/main/java/com/onixbyte/deltaforceguide/controller/AuthController.java index 86229aa..0a42067 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/controller/AuthController.java +++ b/src/main/java/com/onixbyte/deltaforceguide/controller/AuthController.java @@ -19,6 +19,11 @@ import org.springframework.web.bind.annotation.RestController; import java.time.Duration; +/** + * REST controller for user authentication endpoints (login, logout). + * + * @author zihluwang + */ @Tag(name = "用户鉴权", description = "处理用户登录与退出功能") @RestController @RequestMapping("/auth") diff --git a/src/main/java/com/onixbyte/deltaforceguide/controller/DailyPasswordController.java b/src/main/java/com/onixbyte/deltaforceguide/controller/DailyPasswordController.java index f817f66..527e730 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/controller/DailyPasswordController.java +++ b/src/main/java/com/onixbyte/deltaforceguide/controller/DailyPasswordController.java @@ -8,6 +8,11 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +/** + * REST controller for retrieving daily-generated passwords. + * + * @author zihluwang + */ @Tag(name = "每日密码", description = "获取每日密码信息") @RestController @RequestMapping("/daily-passwords") diff --git a/src/main/java/com/onixbyte/deltaforceguide/controller/FirearmController.java b/src/main/java/com/onixbyte/deltaforceguide/controller/FirearmController.java index 7d95b69..4843c2d 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/controller/FirearmController.java +++ b/src/main/java/com/onixbyte/deltaforceguide/controller/FirearmController.java @@ -15,6 +15,11 @@ import org.springframework.data.domain.Sort; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +/** + * REST controller for firearm CRUD operations. + * + * @author zihluwang + */ @Tag(name = "武器管理", description = "与武器有关的操作") @RestController @RequestMapping("/firearms") diff --git a/src/main/java/com/onixbyte/deltaforceguide/controller/GlobalExceptionHandler.java b/src/main/java/com/onixbyte/deltaforceguide/controller/GlobalExceptionHandler.java index c0b19f1..4edd154 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/controller/GlobalExceptionHandler.java +++ b/src/main/java/com/onixbyte/deltaforceguide/controller/GlobalExceptionHandler.java @@ -6,6 +6,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +/** + * Global exception handler that translates exceptions into standard error responses. + * + * @author zihluwang + */ @RestControllerAdvice public class GlobalExceptionHandler { diff --git a/src/main/java/com/onixbyte/deltaforceguide/controller/ModificationController.java b/src/main/java/com/onixbyte/deltaforceguide/controller/ModificationController.java index b7c7a8d..7eaf94c 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/controller/ModificationController.java +++ b/src/main/java/com/onixbyte/deltaforceguide/controller/ModificationController.java @@ -27,6 +27,11 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; +/** + * REST controller for modification CRUD operations, including batch creation and deletion. + * + * @author zihluwang + */ @Tag(name = "改装管理", description = "对枪械改装的管理") @RestController @RequestMapping("/modifications") diff --git a/src/main/java/com/onixbyte/deltaforceguide/controller/TagController.java b/src/main/java/com/onixbyte/deltaforceguide/controller/TagController.java index e22097d..b9f4e59 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/controller/TagController.java +++ b/src/main/java/com/onixbyte/deltaforceguide/controller/TagController.java @@ -10,6 +10,11 @@ import com.onixbyte.deltaforceguide.service.ModificationService; import java.util.List; +/** + * REST controller for retrieving available modification tags. + * + * @author zihluwang + */ @Tag(name = "标签管理", description = "管理标签信息") @RestController @RequestMapping("/tags") diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/converter/FirearmTypeConverter.java b/src/main/java/com/onixbyte/deltaforceguide/domain/converter/FirearmTypeConverter.java index f6f46f8..8108db3 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/converter/FirearmTypeConverter.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/converter/FirearmTypeConverter.java @@ -4,6 +4,11 @@ import com.onixbyte.deltaforceguide.enumeration.FirearmType; import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; +/** + * JPA attribute converter that maps {@link FirearmType} enum to/from its integer database representation. + * + * @author zihluwang + */ @Converter public class FirearmTypeConverter implements AttributeConverter { diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryRequest.java index 29fa638..b94b61c 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryRequest.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryRequest.java @@ -6,6 +6,11 @@ import jakarta.validation.constraints.NotBlank; import java.util.ArrayList; import java.util.List; +/** + * Request DTO for creating or updating an accessory attached to a modification. + * + * @author zihluwang + */ public record AccessoryRequest( @NotBlank(message = "插槽名称不能为空") String slotName, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryResponse.java index 421410d..ade3eac 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/AccessoryResponse.java @@ -4,6 +4,11 @@ import com.onixbyte.deltaforceguide.domain.entity.Accessory; import java.util.List; +/** + * Response DTO for an accessory attached to a modification. + * + * @author zihluwang + */ public record AccessoryResponse( String slotName, String accessoryName, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPassword.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPassword.java index 2a381ad..edfa9c0 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPassword.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPassword.java @@ -1,5 +1,10 @@ package com.onixbyte.deltaforceguide.domain.dto; +/** + * DTO representing a single daily-generated password for a map. + * + * @author zihluwang + */ public record DailyPassword( String mapName, String password diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordData.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordData.java index c685542..5e3c12f 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordData.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordData.java @@ -3,6 +3,11 @@ package com.onixbyte.deltaforceguide.domain.dto; import java.time.LocalDateTime; import java.util.List; +/** + * DTO containing daily password data including update information and password list. + * + * @author zihluwang + */ public record DailyPasswordData( String updateDate, Integer totalCount, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordMetadata.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordMetadata.java index a2fa36b..9af994f 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordMetadata.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordMetadata.java @@ -1,5 +1,10 @@ package com.onixbyte.deltaforceguide.domain.dto; +/** + * DTO holding metadata about the daily password source and update tracking. + * + * @author zihluwang + */ public record DailyPasswordMetadata( String version, String author diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordResponse.java index 7d29a27..d3ce808 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/DailyPasswordResponse.java @@ -1,5 +1,10 @@ package com.onixbyte.deltaforceguide.domain.dto; +/** + * Response DTO wrapping daily password data with metadata. + * + * @author zihluwang + */ public record DailyPasswordResponse( String status, String message, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ErrorResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ErrorResponse.java index f1efbfa..11879fc 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ErrorResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ErrorResponse.java @@ -1,5 +1,10 @@ package com.onixbyte.deltaforceguide.domain.dto; +/** + * Standard error response body returned on API failures. + * + * @author zihluwang + */ public record ErrorResponse( String message ) { diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmRequest.java index 74e1993..02fb855 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmRequest.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmRequest.java @@ -2,6 +2,11 @@ package com.onixbyte.deltaforceguide.domain.dto; import com.onixbyte.deltaforceguide.enumeration.FirearmType; +/** + * Request DTO for creating or updating a firearm. + * + * @author zihluwang + */ public record FirearmRequest( String name, FirearmType type, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmResponse.java index eb5b1ac..0e9eaba 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/FirearmResponse.java @@ -3,6 +3,11 @@ package com.onixbyte.deltaforceguide.domain.dto; import com.onixbyte.deltaforceguide.domain.entity.Firearm; import com.onixbyte.deltaforceguide.enumeration.FirearmType; +/** + * Response DTO for a firearm record, including associated modifications. + * + * @author zihluwang + */ public record FirearmResponse( Long id, String name, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/LoginRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/LoginRequest.java index ab820ec..106d533 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/LoginRequest.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/LoginRequest.java @@ -3,6 +3,11 @@ package com.onixbyte.deltaforceguide.domain.dto; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +/** + * Login request containing principle (username/email) and credential (password). + * + * @author zihluwang + */ @Schema(description = "登录请求") public record LoginRequest( @NotBlank(message = "登录名称不能为空") diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchCreateRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchCreateRequest.java index cdb3d93..c0aa59f 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchCreateRequest.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchCreateRequest.java @@ -5,6 +5,11 @@ import jakarta.validation.constraints.NotEmpty; import java.util.List; +/** + * Request DTO for batch creation of modifications. + * + * @author zihluwang + */ public record ModificationBatchCreateRequest( @NotEmpty(message = "批量创建列表不能为空") List<@Valid ModificationRequest> modifications diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchDeleteRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchDeleteRequest.java index 7e46400..4243895 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchDeleteRequest.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationBatchDeleteRequest.java @@ -5,6 +5,11 @@ import jakarta.validation.constraints.Positive; import java.util.List; +/** + * Request DTO for batch deletion of modifications by ID. + * + * @author zihluwang + */ public record ModificationBatchDeleteRequest( @NotEmpty(message = "批量删除ID列表不能为空") List<@Positive(message = "ID必须为正数") Long> ids diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationRequest.java index c602dbd..e4f6708 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationRequest.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationRequest.java @@ -8,6 +8,11 @@ import jakarta.validation.constraints.Positive; import java.util.ArrayList; import java.util.List; +/** + * Request DTO for creating or updating a modification. + * + * @author zihluwang + */ public record ModificationRequest( @NotNull(message = "武器ID不能为空") @Positive(message = "武器ID必须为正数") diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationResponse.java index c4d4492..aca6ef5 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/ModificationResponse.java @@ -4,6 +4,11 @@ import com.onixbyte.deltaforceguide.domain.entity.Modification; import java.util.List; +/** + * Response DTO for a modification record including accessories and tags. + * + * @author zihluwang + */ public record ModificationResponse( Long id, Long firearmId, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/PageResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/PageResponse.java index 0eefb62..20738bd 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/PageResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/PageResponse.java @@ -4,6 +4,11 @@ import org.springframework.data.domain.Page; import java.util.List; +/** + * Generic paginated response wrapper for list endpoints. + * + * @author zihluwang + */ public record PageResponse( List items, int page, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningRequest.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningRequest.java index 414becd..a180eb3 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningRequest.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningRequest.java @@ -3,6 +3,11 @@ package com.onixbyte.deltaforceguide.domain.dto; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +/** + * Request DTO for a tuning adjustment on an accessory. + * + * @author zihluwang + */ public record TuningRequest( @NotBlank(message = "调校项名称不能为空") String tuningName, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningResponse.java index 3f6febf..405ecde 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/TuningResponse.java @@ -2,6 +2,11 @@ package com.onixbyte.deltaforceguide.domain.dto; import com.onixbyte.deltaforceguide.domain.entity.Tuning; +/** + * Response DTO for a tuning adjustment on an accessory. + * + * @author zihluwang + */ public record TuningResponse( String tuningName, Double tuningValue diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/UserResponse.java b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/UserResponse.java index 75d9188..b20231b 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/dto/UserResponse.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/dto/UserResponse.java @@ -2,6 +2,11 @@ package com.onixbyte.deltaforceguide.domain.dto; import com.onixbyte.deltaforceguide.domain.entity.User; +/** + * Response DTO for a user account, including associated credentials. + * + * @author zihluwang + */ public record UserResponse( Long id, String username, diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Accessory.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Accessory.java index b76b622..cde914d 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Accessory.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Accessory.java @@ -4,6 +4,11 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +/** + * Entity representing an accessory attached to a modification, stored as JSONB. + * + * @author zihluwang + */ public class Accessory { private String slotName; diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Firearm.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Firearm.java index 65942d3..c71cee7 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Firearm.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Firearm.java @@ -15,6 +15,11 @@ import jakarta.persistence.Table; import java.util.ArrayList; import java.util.List; +/** + * Entity representing a firearm in the Delta Force game. + * + * @author zihluwang + */ @Entity @Table(name = "firearm") public class Firearm { diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Modification.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Modification.java index ed145b5..a1942f7 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Modification.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Modification.java @@ -7,6 +7,11 @@ import org.hibernate.annotations.Type; import java.util.ArrayList; import java.util.List; +/** + * Entity representing a firearm modification or build configuration. + * + * @author zihluwang + */ @Entity @Table( name = "modification", diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Tuning.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Tuning.java index 83eb1b8..a4eb1f1 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Tuning.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Tuning.java @@ -2,6 +2,11 @@ package com.onixbyte.deltaforceguide.domain.entity; import java.util.Objects; +/** + * Entity representing a tuning adjustment for an accessory, stored as JSONB within Accessory. + * + * @author zihluwang + */ public class Tuning { private String tuningName; diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/User.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/User.java index 67142df..d696b2d 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/User.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/User.java @@ -12,6 +12,11 @@ import jakarta.persistence.Table; import java.util.ArrayList; import java.util.List; +/** + * Entity representing an application user with authentication credentials. + * + * @author zihluwang + */ @Entity @Table(name = "app_user") public class User { diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredential.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredential.java index b8a09a6..2ecdd37 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredential.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredential.java @@ -12,6 +12,11 @@ import jakarta.persistence.MapsId; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +/** + * Entity representing a user credential linked to an authentication provider. + * + * @author zihluwang + */ @Entity @Table(name = "app_user_credential") public class UserCredential { @@ -28,7 +33,7 @@ public class UserCredential { @JoinColumn(name = "user_id", nullable = false, foreignKey = @ForeignKey(name = "fk_user_credential_user")) private User user; - @Column(name = "credential", nullable = false, length = 255) + @Column(name = "credential", nullable = false) private String credential; public UserCredentialId getId() { diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredentialId.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredentialId.java index 57a819e..1e25f45 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredentialId.java +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/UserCredentialId.java @@ -5,6 +5,11 @@ import jakarta.persistence.Embeddable; import java.io.Serializable; import java.util.Objects; +/** + * Composite key for the UserCredential entity, combining user ID and provider. + * + * @author zihluwang + */ @Embeddable public class UserCredentialId implements Serializable { diff --git a/src/main/java/com/onixbyte/deltaforceguide/enumeration/FirearmType.java b/src/main/java/com/onixbyte/deltaforceguide/enumeration/FirearmType.java index d4965fa..77bdbdb 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/enumeration/FirearmType.java +++ b/src/main/java/com/onixbyte/deltaforceguide/enumeration/FirearmType.java @@ -1,5 +1,11 @@ package com.onixbyte.deltaforceguide.enumeration; +/** + * Enumeration of firearm types in the Delta Force game. + * Each type is associated with an integer code used for database persistence. + * + * @author zihluwang + */ public enum FirearmType { RIFLE(0), @@ -21,6 +27,13 @@ public enum FirearmType { return code; } + /** + * Resolve a FirearmType from its integer code. + * + * @param code the integer code, may be null + * @return the corresponding FirearmType, or null if the code is null + * @throws IllegalArgumentException if the code does not match any known type + */ public static FirearmType fromCode(Integer code) { if (code == null) { return null; diff --git a/src/main/java/com/onixbyte/deltaforceguide/exeption/BizException.java b/src/main/java/com/onixbyte/deltaforceguide/exeption/BizException.java index aad96d2..d1b7ff2 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/exeption/BizException.java +++ b/src/main/java/com/onixbyte/deltaforceguide/exeption/BizException.java @@ -2,6 +2,11 @@ package com.onixbyte.deltaforceguide.exeption; import org.springframework.http.HttpStatus; +/** + * Custom runtime exception that carries an HTTP status code for API error responses. + * + * @author zihluwang + */ public class BizException extends RuntimeException { /** diff --git a/src/main/java/com/onixbyte/deltaforceguide/filter/TokenAuthenticationFilter.java b/src/main/java/com/onixbyte/deltaforceguide/filter/TokenAuthenticationFilter.java index f4b9220..e2068a6 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/filter/TokenAuthenticationFilter.java +++ b/src/main/java/com/onixbyte/deltaforceguide/filter/TokenAuthenticationFilter.java @@ -16,7 +16,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; -import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -29,6 +28,11 @@ import java.time.Instant; import java.util.Objects; import java.util.Optional; +/** + * Servlet filter that extracts and validates JWT tokens from httpOnly cookies for each request. + * + * @author zihluwang + */ @Component public class TokenAuthenticationFilter extends OncePerRequestFilter { @@ -52,6 +56,13 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter { this.handlerExceptionResolver = handlerExceptionResolver; } + /** + * Extracts JWT from httpOnly cookie, validates it, and sets the security context. + * + * @param request the HTTP request + * @param response the HTTP response + * @param filterChain the filter chain + */ @Override protected void doFilterInternal( @NonNull HttpServletRequest request, diff --git a/src/main/java/com/onixbyte/deltaforceguide/manager/CookieManager.java b/src/main/java/com/onixbyte/deltaforceguide/manager/CookieManager.java index 7bec528..f6ef16f 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/manager/CookieManager.java +++ b/src/main/java/com/onixbyte/deltaforceguide/manager/CookieManager.java @@ -6,6 +6,11 @@ import org.springframework.stereotype.Component; import java.time.Duration; +/** + * Manager providing cookie construction operations with configurable properties. + * + * @author zihluwang + */ @Component public class CookieManager { diff --git a/src/main/java/com/onixbyte/deltaforceguide/manager/DailyPasswordManager.java b/src/main/java/com/onixbyte/deltaforceguide/manager/DailyPasswordManager.java index 3ec28f9..6b6ac59 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/manager/DailyPasswordManager.java +++ b/src/main/java/com/onixbyte/deltaforceguide/manager/DailyPasswordManager.java @@ -17,6 +17,11 @@ import java.time.Duration; import java.time.LocalDate; import java.util.Objects; +/** + * Manager for daily password data access and caching coordination. + * + * @author zihluwang + */ @Component public class DailyPasswordManager { @@ -49,6 +54,10 @@ public class DailyPasswordManager { this.redisTemplate = redisTemplate; } + /** + * Retrieves the daily password from cache or generates a new one. + * @return the daily password response + */ public DailyPasswordResponse getDailyPassword() { var key = CACHE_KEY_PREFIX + LocalDate.now(); diff --git a/src/main/java/com/onixbyte/deltaforceguide/manager/UserCredentialManager.java b/src/main/java/com/onixbyte/deltaforceguide/manager/UserCredentialManager.java index f4aa494..d77c687 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/manager/UserCredentialManager.java +++ b/src/main/java/com/onixbyte/deltaforceguide/manager/UserCredentialManager.java @@ -3,11 +3,15 @@ package com.onixbyte.deltaforceguide.manager; import com.onixbyte.deltaforceguide.domain.entity.UserCredential; import com.onixbyte.deltaforceguide.repository.UserCredentialRepository; import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; +/** + * Manager for user credential persistence and authentication data access. + * + * @author zihluwang + */ @Component public class UserCredentialManager { @@ -17,27 +21,52 @@ public class UserCredentialManager { this.userCredentialRepository = userCredentialRepository; } - @Transactional(readOnly = true) + /** + * Finds all credentials belonging to a specific user. + * + * @param userId the user ID + * @return list of matching credentials + */ public List findAllByUserId(Long userId) { return userCredentialRepository.findAllByUserId(userId); } - @Transactional(readOnly = true) + /** + * Finds a credential for a specific user and provider combination. + * + * @param userId the user ID + * @param provider the authentication provider + * @return the matching credential, if found + */ public Optional findByUserIdAndProvider(Long userId, String provider) { return userCredentialRepository.findByUserIdAndProvider(userId, provider); } - @Transactional + /** + * Persists a new or updated credential. + * + * @param userCredential the credential to save + * @return the saved credential + */ public UserCredential save(UserCredential userCredential) { return userCredentialRepository.save(userCredential); } - @Transactional + /** + * Deletes a credential for a specific user and provider. + * + * @param userId the user ID + * @param provider the authentication provider + */ public void deleteByUserIdAndProvider(Long userId, String provider) { userCredentialRepository.deleteByUserIdAndProvider(userId, provider); } - @Transactional + /** + * Deletes all credentials belonging to a user. + * + * @param userId the user ID + */ public void deleteAllByUserId(Long userId) { userCredentialRepository.deleteAllByUserId(userId); } diff --git a/src/main/java/com/onixbyte/deltaforceguide/manager/UserManager.java b/src/main/java/com/onixbyte/deltaforceguide/manager/UserManager.java index fb8ac56..d63c0f7 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/manager/UserManager.java +++ b/src/main/java/com/onixbyte/deltaforceguide/manager/UserManager.java @@ -8,6 +8,11 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; +/** + * Manager for user entity persistence and query operations. + * + * @author zihluwang + */ @Component public class UserManager { @@ -17,17 +22,30 @@ public class UserManager { this.userRepository = userRepository; } - @Transactional(readOnly = true) + /** + * Finds a user by their ID. + * + * @param id the user ID + * @return the matching user, if found + */ public Optional findById(Long id) { return userRepository.findById(id); } - @Transactional(readOnly = true) + /** + * Retrieves all registered users. + * @return list of all users + */ public List findAll() { return userRepository.findAll(); } - @Transactional(readOnly = true) + /** + * Finds a user by their username. + * + * @param username the username to search for + * @return the matching user, if found + */ public Optional findByUsername(String username) { return userRepository.findByUsername(username); } @@ -37,16 +55,31 @@ public class UserManager { return userRepository.findByEmail(email); } - @Transactional + /** + * Persists a new or updated user. + * + * @param user the user to save + * @return the saved user + */ public User save(User user) { return userRepository.save(user); } - @Transactional + /** + * Deletes a user by their ID. + * + * @param id the user ID to delete + */ public void deleteById(Long id) { userRepository.deleteById(id); } + /** + * Finds a user by their username or email address. + * + * @param principal the username or email to search for + * @return the matching user, if found + */ public Optional findByUsernameOrEmail(String principal) { return userRepository.findByUsernameOrEmail(principal); } diff --git a/src/main/java/com/onixbyte/deltaforceguide/properties/CookieProperties.java b/src/main/java/com/onixbyte/deltaforceguide/properties/CookieProperties.java index 86dab77..0cfde08 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/properties/CookieProperties.java +++ b/src/main/java/com/onixbyte/deltaforceguide/properties/CookieProperties.java @@ -6,6 +6,16 @@ import org.springframework.boot.web.server.Cookie; import java.time.Duration; +/** + * Configuration properties for HTTP cookies used in authentication, prefixed with "app.cookie". + * + * @param httpOnly whether the cookie is httpOnly + * @param secure whether the cookie is secure + * @param path the cookie path + * @param maxAge the maximum age of the cookie + * @param sameSite the SameSite policy for the cookie + * @author zihluwang + */ @ConfigurationProperties(prefix = "app.cookie") public record CookieProperties( @DefaultValue("true") Boolean httpOnly, diff --git a/src/main/java/com/onixbyte/deltaforceguide/properties/CorsProperties.java b/src/main/java/com/onixbyte/deltaforceguide/properties/CorsProperties.java index ff064d5..193640f 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/properties/CorsProperties.java +++ b/src/main/java/com/onixbyte/deltaforceguide/properties/CorsProperties.java @@ -6,6 +6,18 @@ import org.springframework.http.HttpMethod; import java.time.Duration; +/** + * Configuration properties for CORS settings, prefixed with "app.cors". + * + * @param allowedHeaders headers allowed in CORS requests + * @param allowedMethods HTTP methods allowed in CORS requests + * @param allowedOrigins origins permitted to make cross-origin requests + * @param allowCredentials whether credentials are allowed in CORS requests + * @param allowPrivateNetwork whether private network access is permitted + * @param maxAge how long the CORS preflight response may be cached + * @param exposedHeaders headers exposed to the client in CORS responses + * @author zihluwang + */ @ConfigurationProperties(prefix = "app.cors") public record CorsProperties( @DefaultValue({"Content-Type", "Authorization"}) diff --git a/src/main/java/com/onixbyte/deltaforceguide/properties/TokenProperties.java b/src/main/java/com/onixbyte/deltaforceguide/properties/TokenProperties.java index 0d7a618..74c693c 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/properties/TokenProperties.java +++ b/src/main/java/com/onixbyte/deltaforceguide/properties/TokenProperties.java @@ -4,6 +4,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import java.time.Duration; +/** + * Configuration properties for JWT token generation and validation, prefixed with "app.jwt". + * + * @param issuer the JWT issuer claim + * @param secret the signing secret for JWT tokens + * @param validTime the duration for which a token remains valid + * @author zihluwang + */ @ConfigurationProperties(prefix = "app.jwt") public record TokenProperties( String issuer, diff --git a/src/main/java/com/onixbyte/deltaforceguide/repository/FirearmRepository.java b/src/main/java/com/onixbyte/deltaforceguide/repository/FirearmRepository.java index b486703..46c84b9 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/repository/FirearmRepository.java +++ b/src/main/java/com/onixbyte/deltaforceguide/repository/FirearmRepository.java @@ -9,6 +9,11 @@ import org.springframework.stereotype.Repository; import java.util.List; +/** + * Spring Data JPA repository for {@link Firearm} entity operations. + * + * @author zihluwang + */ @Repository public interface FirearmRepository extends JpaRepository { diff --git a/src/main/java/com/onixbyte/deltaforceguide/repository/ModificationRepository.java b/src/main/java/com/onixbyte/deltaforceguide/repository/ModificationRepository.java index d4f891a..3d9fcc0 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/repository/ModificationRepository.java +++ b/src/main/java/com/onixbyte/deltaforceguide/repository/ModificationRepository.java @@ -13,6 +13,12 @@ import org.springframework.stereotype.Repository; import java.util.List; import java.util.Optional; +/** + * Spring Data JPA repository for {@link Modification} entity operations, + * including native JSONB tag filtering for Postgres. + * + * @author zihluwang + */ @Repository public interface ModificationRepository extends JpaRepository { @@ -27,6 +33,14 @@ public interface ModificationRepository extends JpaRepository findById(@NonNull Long id); + /** + * Page query modifications with optional firearm and JSONB tag filtering. + * + * @param firearmId optional firearm ID filter (nullable) + * @param tagsJson optional JSON array of tags to match via Postgres {@code @>} operator (nullable) + * @param pageable pagination information + * @return a page of matching modifications + */ @Query(value = """ SELECT * FROM modification m WHERE (:firearmId IS NULL OR m.firearm_id = :firearmId) @@ -40,6 +54,12 @@ public interface ModificationRepository extends JpaRepository pageQueryByFirearmAndTags(@Param("firearmId") Long firearmId, @Param("tagsJson") String tagsJson, Pageable pageable); + /** + * Retrieve all distinct tag values from modifications, optionally filtered by firearm. + * + * @param firearmId optional firearm ID filter (nullable) + * @return list of distinct tag strings + */ @Query(value = "SELECT DISTINCT jsonb_array_elements_text(cast(tags as jsonb)) FROM modification WHERE (:firearmId IS NULL OR firearm_id = :firearmId)", nativeQuery = true) List findAllTags(@Param("firearmId") Long firearmId); } diff --git a/src/main/java/com/onixbyte/deltaforceguide/repository/UserCredentialRepository.java b/src/main/java/com/onixbyte/deltaforceguide/repository/UserCredentialRepository.java index 94fb8ec..53776e3 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/repository/UserCredentialRepository.java +++ b/src/main/java/com/onixbyte/deltaforceguide/repository/UserCredentialRepository.java @@ -12,9 +12,20 @@ import org.springframework.stereotype.Repository; import java.util.List; import java.util.Optional; +/** + * Spring Data JPA repository for {@link UserCredential} entity operations. + * + * @author zihluwang + */ @Repository public interface UserCredentialRepository extends JpaRepository { + /** + * Find all credentials belonging to a given user. + * + * @param userId the user ID + * @return list of matching credentials + */ @EntityGraph(attributePaths = {"user"}) @Query(""" select uc @@ -23,6 +34,13 @@ public interface UserCredentialRepository extends JpaRepository findAllByUserId(@Param("userId") Long userId); + /** + * Find a specific credential for a user by provider. + * + * @param userId the user ID + * @param provider the authentication provider identifier + * @return an optional containing the matching credential, or empty if not found + */ @EntityGraph(attributePaths = {"user"}) @Query(""" select uc @@ -32,6 +50,12 @@ public interface UserCredentialRepository extends JpaRepository findByUserIdAndProvider(@Param("userId") Long userId, @Param("provider") String provider); + /** + * Delete a specific credential for a user by provider. + * + * @param userId the user ID + * @param provider the authentication provider identifier + */ @Modifying @Query(""" delete from UserCredential uc @@ -40,6 +64,11 @@ public interface UserCredentialRepository extends JpaRepository { @@ -28,6 +33,12 @@ public interface UserRepository extends JpaRepository { boolean existsByEmail(String email); + /** + * Find a user by either username or email. + * + * @param principal the username or email to search for + * @return an optional containing the matching user, or empty if not found + */ @EntityGraph(attributePaths = {"credentials"}) @Query(""" select u diff --git a/src/main/java/com/onixbyte/deltaforceguide/security/annotation/RequiresAuth.java b/src/main/java/com/onixbyte/deltaforceguide/security/annotation/RequiresAuth.java index f022be3..9b6b014 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/security/annotation/RequiresAuth.java +++ b/src/main/java/com/onixbyte/deltaforceguide/security/annotation/RequiresAuth.java @@ -7,6 +7,11 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Annotation to mark controller endpoints that require authentication. + * + * @author zihluwang + */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @PreAuthorize("isAuthenticated()") diff --git a/src/main/java/com/onixbyte/deltaforceguide/security/authentication/UsernamePasswordAuthentication.java b/src/main/java/com/onixbyte/deltaforceguide/security/authentication/UsernamePasswordAuthentication.java index 692efaf..9bd2ae3 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/security/authentication/UsernamePasswordAuthentication.java +++ b/src/main/java/com/onixbyte/deltaforceguide/security/authentication/UsernamePasswordAuthentication.java @@ -8,6 +8,11 @@ import org.springframework.security.core.GrantedAuthority; import java.util.Collection; import java.util.List; +/** + * Custom authentication token for username/password-based login flows. + * + * @author zihluwang + */ public class UsernamePasswordAuthentication implements Authentication, CredentialsContainer { private final String username; private String password; diff --git a/src/main/java/com/onixbyte/deltaforceguide/security/provider/UsernamePasswordAuthenticationProvider.java b/src/main/java/com/onixbyte/deltaforceguide/security/provider/UsernamePasswordAuthenticationProvider.java index d5e9a65..01e6baa 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/security/provider/UsernamePasswordAuthenticationProvider.java +++ b/src/main/java/com/onixbyte/deltaforceguide/security/provider/UsernamePasswordAuthenticationProvider.java @@ -17,6 +17,11 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; +/** + * Authentication provider that validates username/password credentials against stored BCrypt hashes. + * + * @author zihluwang + */ @Component public class UsernamePasswordAuthenticationProvider implements AuthenticationProvider { @@ -36,6 +41,12 @@ public class UsernamePasswordAuthenticationProvider implements AuthenticationPro this.userCredentialRepository = userCredentialRepository; } + /** + * Validates the username/password credentials against stored BCrypt hashes. + * + * @param authentication the authentication request object + * @return a fully authenticated object including user details + */ @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (!(authentication instanceof UsernamePasswordAuthentication usernamePasswordAuthentication)) { @@ -75,6 +86,12 @@ public class UsernamePasswordAuthenticationProvider implements AuthenticationPro return usernamePasswordAuthentication; } + /** + * Checks if this provider supports the given authentication type. + * + * @param authentication the authentication class to check + * @return true if this provider supports the given type + */ @Override public boolean supports(Class authentication) { return UsernamePasswordAuthentication.class.isAssignableFrom(authentication); diff --git a/src/main/java/com/onixbyte/deltaforceguide/service/AuthService.java b/src/main/java/com/onixbyte/deltaforceguide/service/AuthService.java index b1bbfc7..da41902 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/service/AuthService.java +++ b/src/main/java/com/onixbyte/deltaforceguide/service/AuthService.java @@ -10,9 +10,11 @@ import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.stereotype.Service; -import java.util.Objects; -import java.util.Optional; - +/** + * Service handling user authentication, login, and session management. + * + * @author zihluwang + */ @Service public class AuthService { @@ -23,6 +25,16 @@ public class AuthService { this.authenticationManager = authenticationManager; } + /** + * Authenticates a user with the given login credentials. + *

+ * Delegates authentication to Spring Security's {@link AuthenticationManager} and verifies + * that the result is of the expected {@link UsernamePasswordAuthentication} type. + * + * @param request the login credentials containing principle and password + * @return the authenticated {@link User} + * @throws BizException if authentication fails or the result type is unexpected + */ public User login(LoginRequest request) { var _authentication = authenticationManager.authenticate(UsernamePasswordAuthentication .unauthenticated(request.principle(), request.credential())); diff --git a/src/main/java/com/onixbyte/deltaforceguide/service/CookieService.java b/src/main/java/com/onixbyte/deltaforceguide/service/CookieService.java index 764b47b..eb93086 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/service/CookieService.java +++ b/src/main/java/com/onixbyte/deltaforceguide/service/CookieService.java @@ -6,6 +6,11 @@ import org.springframework.stereotype.Service; import java.time.Duration; +/** + * Service for building HTTP cookies with configurable properties. + * + * @author zihluwang + */ @Service public class CookieService { @@ -15,10 +20,25 @@ public class CookieService { this.cookieManager = cookieManager; } + /** + * Builds a response cookie with the default max age from configuration. + * + * @param cookieName the cookie name + * @param value the cookie value + * @return a configured ResponseCookie + */ public ResponseCookie buildCookie(String cookieName, String value) { return buildCookieInternal(cookieName, value, cookieManager.getMaxAge()); } + /** + * Builds a response cookie with a custom valid duration. + * + * @param cookieName the cookie name + * @param value the cookie value + * @param validDuration the cookie's max age + * @return a configured ResponseCookie + */ public ResponseCookie buildCookie(String cookieName, String value, Duration validDuration) { return buildCookieInternal(cookieName, value, validDuration); } diff --git a/src/main/java/com/onixbyte/deltaforceguide/service/DailyPasswordService.java b/src/main/java/com/onixbyte/deltaforceguide/service/DailyPasswordService.java index 3ad3d4e..fa2118d 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/service/DailyPasswordService.java +++ b/src/main/java/com/onixbyte/deltaforceguide/service/DailyPasswordService.java @@ -4,6 +4,11 @@ import com.onixbyte.deltaforceguide.domain.dto.DailyPasswordResponse; import com.onixbyte.deltaforceguide.manager.DailyPasswordManager; import org.springframework.stereotype.Service; +/** + * Service for generating and caching daily rotation passwords. + * + * @author zihluwang + */ @Service public class DailyPasswordService { @@ -13,6 +18,10 @@ public class DailyPasswordService { this.dailyPasswordManager = dailyPasswordManager; } + /** + * Retrieves the daily password for the current day. + * @return the daily password response + */ public DailyPasswordResponse getDailyPassword() { return dailyPasswordManager.getDailyPassword(); } diff --git a/src/main/java/com/onixbyte/deltaforceguide/service/FirearmService.java b/src/main/java/com/onixbyte/deltaforceguide/service/FirearmService.java index 3b69c15..5f5098b 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/service/FirearmService.java +++ b/src/main/java/com/onixbyte/deltaforceguide/service/FirearmService.java @@ -11,9 +11,13 @@ import org.springframework.data.domain.Page; 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 handling firearm business logic including CRUD operations and queries. + * + * @author zihluwang + */ @Service public class FirearmService { @@ -23,7 +27,13 @@ public class FirearmService { this.firearmRepository = firearmRepository; } - @Transactional(readOnly = true) + /** + * Queries firearms with optional type filter and pagination. + * + * @param type optional firearm type filter + * @param pageable pagination parameters + * @return a paginated response of firearm records + */ public PageResponse pageQuery(FirearmType type, Pageable pageable) { Page page = type == null ? firearmRepository.findAll(pageable) @@ -32,13 +42,24 @@ public class FirearmService { return PageResponse.from(page.map(FirearmResponse::from)); } - @Transactional(readOnly = true) + /** + * Finds a firearm by its ID. + * + * @param id the firearm ID + * @return the firearm response + */ public FirearmResponse queryById(Long id) { return firearmRepository.findById(id) .map(FirearmResponse::from) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Firearm not found: " + id)); } + /** + * Creates a new firearm from the provided request data. + * + * @param request the firearm creation request + * @return the created firearm response + */ public FirearmResponse addFirearm(FirearmRequest request) { var firearm = firearmRepository.save(Firearm.builder() .name(request.name()) @@ -54,7 +75,13 @@ public class FirearmService { return FirearmResponse.from(firearm); } - @Transactional + /** + * Updates an existing firearm identified by ID. + * + * @param id the firearm ID + * @param request the updated firearm data + * @return the updated firearm response + */ public FirearmResponse updateFirearm(Long id, FirearmRequest request) { var firearm = firearmRepository.findById(id) .orElseThrow(() -> new BizException(HttpStatus.NOT_FOUND, "Firearm not found: " + id)); @@ -71,7 +98,11 @@ public class FirearmService { return FirearmResponse.from(firearmRepository.save(firearm)); } - @Transactional + /** + * Deletes a firearm by its ID. + * + * @param id the firearm ID to delete + */ public void deleteFirearm(Long id) { Firearm firearm = firearmRepository.findById(id) .orElseThrow(() -> new BizException(HttpStatus.NOT_FOUND, "Firearm not found: " + id)); diff --git a/src/main/java/com/onixbyte/deltaforceguide/service/ModificationService.java b/src/main/java/com/onixbyte/deltaforceguide/service/ModificationService.java index 37aa1d4..9b97e8f 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/service/ModificationService.java +++ b/src/main/java/com/onixbyte/deltaforceguide/service/ModificationService.java @@ -18,7 +18,6 @@ import org.springframework.data.domain.Page; 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; import java.util.ArrayList; @@ -26,6 +25,11 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +/** + * Service handling modification business logic including CRUD, batch operations, and tag filtering. + * + * @author zihluwang + */ @Service public class ModificationService { @@ -46,7 +50,14 @@ public class ModificationService { this.objectMapper = objectMapper; } - @Transactional(readOnly = true) + /** + * Queries modifications with optional firearm and tag filters. + * + * @param firearmId optional firearm ID filter + * @param tags optional tag list filter + * @param pageable pagination parameters + * @return a paginated response of modification records + */ public PageResponse pageQuery(Long firearmId, List tags, Pageable pageable) { String tagsJson = null; if (tags != null && !tags.isEmpty()) { @@ -67,27 +78,55 @@ public class ModificationService { return PageResponse.from(page.map(ModificationResponse::from)); } - @Transactional(readOnly = true) + /** + * Finds a modification by its ID. + * + * @param id the modification ID + * @return the modification response + */ public ModificationResponse queryById(Long id) { return modificationRepository.findById(id) .map(ModificationResponse::from) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Modification not found: " + id)); } - @Transactional(readOnly = true) + /** + * Finds all unique tags across modifications, optionally scoped to a firearm. + * + * @param firearmId optional firearm ID to scope the tag search + * @return list of unique tag strings + */ public List findAllTags(Long firearmId) { return modificationRepository.findAllTags(firearmId); } + /** + * Creates a new modification for a given firearm. + * + * @param request the modification creation request + * @return the created modification response + */ public ModificationResponse create(ModificationRequest request) { return modificationManager.create(request); } + /** + * Creates multiple modifications in a single batch operation. + * + * @param requests list of modification creation requests + * @return list of created modification responses + */ public List batchCreate(List requests) { return modificationManager.batchCreate(requests); } - @Transactional + /** + * Updates an existing modification identified by ID. + * + * @param id the modification ID + * @param request the updated modification data + * @return the updated modification response + */ public ModificationResponse update(Long id, ModificationRequest request) { Modification modification = modificationRepository.findById(id) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Modification not found: " + id)); @@ -106,14 +145,22 @@ public class ModificationService { return ModificationResponse.from(modificationRepository.save(modification)); } - @Transactional + /** + * Deletes a modification by its ID. + * + * @param id the modification ID to delete + */ public void delete(Long id) { Modification modification = modificationRepository.findById(id) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Modification not found: " + id)); modificationRepository.delete(modification); } - @Transactional + /** + * Deletes multiple modifications in a single batch operation. + * + * @param ids list of modification IDs to delete + */ public void batchDelete(List ids) { Set uniqueIds = new LinkedHashSet<>(ids); List modifications = modificationRepository.findAllById(uniqueIds); diff --git a/src/main/java/com/onixbyte/deltaforceguide/service/UserService.java b/src/main/java/com/onixbyte/deltaforceguide/service/UserService.java index c57ce4f..700e26d 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/service/UserService.java +++ b/src/main/java/com/onixbyte/deltaforceguide/service/UserService.java @@ -6,11 +6,15 @@ import com.onixbyte.deltaforceguide.manager.UserCredentialManager; import com.onixbyte.deltaforceguide.manager.UserManager; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import org.springframework.web.server.ResponseStatusException; import java.util.List; +/** + * Service for user account management and profile operations. + * + * @author zihluwang + */ @Service public class UserService { @@ -22,29 +26,53 @@ public class UserService { this.userCredentialManager = userCredentialManager; } - @Transactional(readOnly = true) + /** + * Retrieves all registered users. + * + * @return list of all users + */ public List findAll() { return userManager.findAll(); } - @Transactional(readOnly = true) + /** + * Finds a user by their ID. + * + * @param id the user ID + * @return the user + */ public User queryById(Long id) { return userManager.findById(id) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found: " + id)); } - @Transactional(readOnly = true) + /** + * Finds a user by their username. + * + * @param username the username to search for + * @return the user + */ public User queryByUsername(String username) { return userManager.findByUsername(username) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found: " + username)); } - @Transactional + /** + * Creates a new user account. + * + * @param user the user entity to persist + * @return the saved user entity + */ public User create(User user) { return userManager.save(user); } - @Transactional + /** + * Updates an existing user account. + * + * @param user the user entity with updated fields + * @return the saved user entity + */ public User update(User user) { if (user.getId() == null || userManager.findById(user.getId()).isEmpty()) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found: " + user.getId()); @@ -52,13 +80,24 @@ public class UserService { return userManager.save(user); } - @Transactional(readOnly = true) + /** + * Finds all credentials associated with a user. + * + * @param userId the user ID + * @return list of user credentials + */ public List findCredentials(Long userId) { ensureUserExists(userId); return userCredentialManager.findAllByUserId(userId); } - @Transactional(readOnly = true) + /** + * Queries a specific credential for a user by provider. + * + * @param userId the user ID + * @param provider the authentication provider + * @return the matching credential + */ public UserCredential queryCredential(Long userId, String provider) { ensureUserExists(userId); return userCredentialManager.findByUserIdAndProvider(userId, provider) @@ -67,7 +106,14 @@ public class UserService { "User credential not found: userId=" + userId + ", provider=" + provider)); } - @Transactional + /** + * Creates or updates a credential for a user and provider. + * + * @param userId the user ID + * @param provider the authentication provider + * @param credential the credential value + * @return the saved credential + */ public UserCredential upsertCredential(Long userId, String provider, String credential) { User user = ensureUserExists(userId); UserCredential userCredential = userCredentialManager.findByUserIdAndProvider(userId, provider) @@ -78,13 +124,22 @@ public class UserService { return userCredentialManager.save(userCredential); } - @Transactional + /** + * Deletes a specific credential for a user by provider. + * + * @param userId the user ID + * @param provider the authentication provider + */ public void deleteCredential(Long userId, String provider) { ensureUserExists(userId); userCredentialManager.deleteByUserIdAndProvider(userId, provider); } - @Transactional + /** + * Deletes a user and all associated credentials. + * + * @param id the user ID to delete + */ public void deleteById(Long id) { ensureUserExists(id); userCredentialManager.deleteAllByUserId(id); diff --git a/src/main/java/com/onixbyte/deltaforceguide/shared/CookieName.java b/src/main/java/com/onixbyte/deltaforceguide/shared/CookieName.java index 329852b..26f0112 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/shared/CookieName.java +++ b/src/main/java/com/onixbyte/deltaforceguide/shared/CookieName.java @@ -1,5 +1,10 @@ package com.onixbyte.deltaforceguide.shared; +/** + * Constants for HTTP cookie names used for authentication tokens. + * + * @author zihluwang + */ public class CookieName { public static final String ACCESS_TOKEN = "AccessToken"; diff --git a/src/main/java/com/onixbyte/deltaforceguide/shared/CredentialProvider.java b/src/main/java/com/onixbyte/deltaforceguide/shared/CredentialProvider.java index 115f935..9488536 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/shared/CredentialProvider.java +++ b/src/main/java/com/onixbyte/deltaforceguide/shared/CredentialProvider.java @@ -1,5 +1,10 @@ package com.onixbyte.deltaforceguide.shared; +/** + * Constants for supported authentication provider identifiers. + * + * @author zihluwang + */ public class CredentialProvider { public static final String LOCAL = "LOCAL"; diff --git a/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonModules.java b/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonModules.java index 36332aa..ae47823 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonModules.java +++ b/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonModules.java @@ -13,6 +13,12 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +/** + * Shared Jackson {@link com.fasterxml.jackson.databind.Module} instances for custom date/time + * serialisation and deserialisation across the application. + * + * @author zihluwang + */ public class JacksonModules { public static final SimpleModule DATE_TIME_MODULE = initialiseDateTimeModule(); diff --git a/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonRedisSerialiser.java b/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonRedisSerialiser.java index 5a300ba..4e50c38 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonRedisSerialiser.java +++ b/src/main/java/com/onixbyte/deltaforceguide/shared/JacksonRedisSerialiser.java @@ -4,6 +4,12 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +/** + * Singleton serialiser for Redis cache operations using + * {@link GenericJackson2JsonRedisSerializer} with JavaTime module support. + * + * @author zihluwang + */ public class JacksonRedisSerialiser { public static final GenericJackson2JsonRedisSerializer INSTANCE = initialiseSerializer(); diff --git a/src/main/java/com/onixbyte/deltaforceguide/utils/DateTimeUtil.java b/src/main/java/com/onixbyte/deltaforceguide/utils/DateTimeUtil.java index f1360c8..1d576a5 100644 --- a/src/main/java/com/onixbyte/deltaforceguide/utils/DateTimeUtil.java +++ b/src/main/java/com/onixbyte/deltaforceguide/utils/DateTimeUtil.java @@ -4,8 +4,19 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +/** + * Utility class for date and time operations using system-default time zone. + * + * @author zihluwang + */ public class DateTimeUtil { + /** + * Convert a {@link LocalDateTime} to an {@link Instant} using the system-default time zone. + * + * @param ldt the local date-time to convert + * @return the corresponding instant + */ public static Instant asInstant(LocalDateTime ldt) { return ldt.atZone(ZoneId.systemDefault()) .toInstant();