diff --git a/src/main/java/com/first/flash/global/config/SecurityConfig.java b/src/main/java/com/first/flash/global/config/SecurityConfig.java index 4f5880cf..09a329fe 100644 --- a/src/main/java/com/first/flash/global/config/SecurityConfig.java +++ b/src/main/java/com/first/flash/global/config/SecurityConfig.java @@ -32,7 +32,8 @@ public class SecurityConfig { "/auth/login", "/swagger-ui/*", "/v1/api-docs/**", - "/flash-climbing-answer-health/**" + "/flash-climbing-answer-health/**", + "/versions" }; private static final String COMPLETE_REGISTRATION = "/members"; private static final String MARKETING_CONSENT = "/members/marketing-consent"; diff --git a/src/main/java/com/first/flash/version/application/VersionService.java b/src/main/java/com/first/flash/version/application/VersionService.java new file mode 100644 index 00000000..270b332d --- /dev/null +++ b/src/main/java/com/first/flash/version/application/VersionService.java @@ -0,0 +1,22 @@ +package com.first.flash.version.application; + +import java.util.NoSuchElementException; +import com.first.flash.version.infrastructure.VersionJpaRepository; +import com.first.flash.version.application.dto.VersionResponseDto; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class VersionService { + + private final VersionJpaRepository versionJpaRepository; + + public VersionResponseDto getLatestVersions() { + return versionJpaRepository.findTopByOrderByIdDesc() + .map(version -> new VersionResponseDto(version.getAndroid(), version.getIos())) + .orElseThrow(() -> new NoSuchElementException("No version information available")); + } +} \ No newline at end of file diff --git a/src/main/java/com/first/flash/version/application/dto/VersionResponseDto.java b/src/main/java/com/first/flash/version/application/dto/VersionResponseDto.java new file mode 100644 index 00000000..bcfbba5f --- /dev/null +++ b/src/main/java/com/first/flash/version/application/dto/VersionResponseDto.java @@ -0,0 +1,4 @@ +package com.first.flash.version.application.dto; + +public record VersionResponseDto(String android, String ios) { +} \ No newline at end of file diff --git a/src/main/java/com/first/flash/version/domain/AppVersion.java b/src/main/java/com/first/flash/version/domain/AppVersion.java new file mode 100644 index 00000000..acff2535 --- /dev/null +++ b/src/main/java/com/first/flash/version/domain/AppVersion.java @@ -0,0 +1,24 @@ +package com.first.flash.version.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class AppVersion { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String android; + private String ios; + +} diff --git a/src/main/java/com/first/flash/version/infrastructure/VersionJpaRepository.java b/src/main/java/com/first/flash/version/infrastructure/VersionJpaRepository.java new file mode 100644 index 00000000..94ff9efa --- /dev/null +++ b/src/main/java/com/first/flash/version/infrastructure/VersionJpaRepository.java @@ -0,0 +1,10 @@ +package com.first.flash.version.infrastructure; + +import com.first.flash.version.domain.AppVersion; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + +public interface VersionJpaRepository extends JpaRepository { + + Optional findTopByOrderByIdDesc(); +} \ No newline at end of file diff --git a/src/main/java/com/first/flash/version/ui/VersionController.java b/src/main/java/com/first/flash/version/ui/VersionController.java new file mode 100644 index 00000000..4a997a8e --- /dev/null +++ b/src/main/java/com/first/flash/version/ui/VersionController.java @@ -0,0 +1,36 @@ +package com.first.flash.version.ui; + +import com.first.flash.climbing.solution.application.dto.SolutionsPageResponseDto; +import com.first.flash.version.application.VersionService; +import com.first.flash.version.application.dto.VersionResponseDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "versions", description = "앱 버전 정보 API") +@RestController +@RequestMapping +@RequiredArgsConstructor +public class VersionController { + + private final VersionService versionService; + + @Operation(summary = "버전 정보 조회", description = "앱 최신 버전 정보 조회") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공적으로 조회함", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = VersionResponseDto.class))) + }) + @GetMapping("versions") + public ResponseEntity getLatestVersions() { + VersionResponseDto versionInfo = versionService.getLatestVersions(); + return ResponseEntity.ok(versionInfo); + } +} \ No newline at end of file