diff --git a/src/main/java/com/example/chalpu/common/exception/AppVersionException.java b/src/main/java/com/example/chalpu/common/exception/AppVersionException.java new file mode 100644 index 0000000..ee0a45a --- /dev/null +++ b/src/main/java/com/example/chalpu/common/exception/AppVersionException.java @@ -0,0 +1,8 @@ +package com.example.chalpu.common.exception; + +public class AppVersionException extends BaseException { + + public AppVersionException(ErrorMessage errorMessage) { + super(errorMessage); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/chalpu/common/exception/ErrorMessage.java b/src/main/java/com/example/chalpu/common/exception/ErrorMessage.java index 7d0e3dd..98f8f03 100644 --- a/src/main/java/com/example/chalpu/common/exception/ErrorMessage.java +++ b/src/main/java/com/example/chalpu/common/exception/ErrorMessage.java @@ -104,6 +104,9 @@ public enum ErrorMessage { // 앱 버전 관련 에러 APP_VERSION_NOT_FOUND(NOT_FOUND, "앱 버전 정보를 찾을 수 없습니다."), + APP_VERSION_CREATE_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "앱 버전 생성에 실패했습니다."), + APP_VERSION_UPDATE_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "앱 버전 수정에 실패했습니다."), + APP_VERSION_DELETE_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "앱 버전 삭제에 실패했습니다."), // 공지사항 관련 에러 NOTICE_NOT_FOUND(NOT_FOUND, "공지사항을 찾을 수 없습니다."), diff --git a/src/main/java/com/example/chalpu/home/controller/HomeController.java b/src/main/java/com/example/chalpu/home/controller/HomeController.java index f740ca0..cb07885 100644 --- a/src/main/java/com/example/chalpu/home/controller/HomeController.java +++ b/src/main/java/com/example/chalpu/home/controller/HomeController.java @@ -4,6 +4,9 @@ import com.example.chalpu.feedback.dto.AppImprovementFeedbackDto; import com.example.chalpu.feedback.dto.FoodGuideFeedbackDto; import com.example.chalpu.feedback.service.FeedbackService; +import com.example.chalpu.version.dto.AppVersionRequestDTO; +import com.example.chalpu.version.dto.AppVersionResponseDTO; +import com.example.chalpu.version.service.AppVersionService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; @@ -30,6 +33,7 @@ public class HomeController { private final FeedbackService feedbackService; + private final AppVersionService appVersionService; @GetMapping("/tips") public ApiResponse> getAllTips() { @@ -44,4 +48,30 @@ public ApiResponse getTipById(@PathVariable("id") String id) { .map(PhotoTipDto::from) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND))); } + + @GetMapping("/version") + @Operation(summary = "최신 앱 버전 조회", description = "최소 지원 버전과 최신 버전 정보를 조회합니다.") + public ApiResponse getLatestVersion() { + return ApiResponse.success(appVersionService.getLatestVersion()); + } + + @GetMapping("/version/{id}") + @Operation(summary = "특정 버전 정보 조회", description = "ID로 특정 버전 정보를 조회합니다.") + public ApiResponse getVersionById(@PathVariable("id") Long id) { + return ApiResponse.success(appVersionService.getVersionById(id)); + } + + @PostMapping("/version") + @Operation(summary = "새 버전 생성", description = "새로운 앱 버전 정보를 생성합니다.") + public ApiResponse createVersion(@RequestBody AppVersionRequestDTO requestDTO) { + return ApiResponse.success(appVersionService.createVersion(requestDTO)); + } + + @PutMapping("/version/{id}") + @Operation(summary = "버전 정보 수정", description = "기존 버전 정보를 수정합니다.") + public ApiResponse updateVersion( + @PathVariable("id") Long id, + @RequestBody AppVersionRequestDTO requestDTO) { + return ApiResponse.success(appVersionService.updateVersion(id, requestDTO)); + } } diff --git a/src/main/java/com/example/chalpu/oauth/config/SecurityConfig.java b/src/main/java/com/example/chalpu/oauth/config/SecurityConfig.java index 2caa34c..5337e0b 100644 --- a/src/main/java/com/example/chalpu/oauth/config/SecurityConfig.java +++ b/src/main/java/com/example/chalpu/oauth/config/SecurityConfig.java @@ -55,6 +55,8 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers("/api/campaigns/campaign-platforms").permitAll() // 공지사항/홈 광고 배너 관련 경로 .requestMatchers("/api/notices/**").permitAll() + // 앱 버전 관련 경로 + .requestMatchers("/api/home/version/**").permitAll() // 나머지는 인증 필요 .anyRequest().authenticated() ) diff --git a/src/main/java/com/example/chalpu/version/domain/AppVersion.java b/src/main/java/com/example/chalpu/version/domain/AppVersion.java new file mode 100644 index 0000000..442be84 --- /dev/null +++ b/src/main/java/com/example/chalpu/version/domain/AppVersion.java @@ -0,0 +1,33 @@ +package com.example.chalpu.version.domain; + +import com.example.chalpu.common.entity.BaseTimeEntity; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "app_version") +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppVersion extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "min_supported_version", nullable = false, length = 30) + private String minSupportedVersion; + + @Column(name = "latest_version", nullable = false, length = 30) + private String latestVersion; + + @Column(name = "platform", length = 20) + private String platform; + + @Column(name = "description", columnDefinition = "TEXT") + private String description; +} diff --git a/src/main/java/com/example/chalpu/version/dto/AppVersionRequestDTO.java b/src/main/java/com/example/chalpu/version/dto/AppVersionRequestDTO.java new file mode 100644 index 0000000..2624b76 --- /dev/null +++ b/src/main/java/com/example/chalpu/version/dto/AppVersionRequestDTO.java @@ -0,0 +1,17 @@ +package com.example.chalpu.version.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppVersionRequestDTO { + private String minSupportedVersion; + private String latestVersion; + private String platform; + private String description; +} \ No newline at end of file diff --git a/src/main/java/com/example/chalpu/version/dto/AppVersionResponseDTO.java b/src/main/java/com/example/chalpu/version/dto/AppVersionResponseDTO.java new file mode 100644 index 0000000..d4827c5 --- /dev/null +++ b/src/main/java/com/example/chalpu/version/dto/AppVersionResponseDTO.java @@ -0,0 +1,23 @@ +package com.example.chalpu.version.dto; + +import com.example.chalpu.version.domain.AppVersion; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AppVersionResponseDTO { + private String minSupportedVersion; + private String latestVersion; + + public static AppVersionResponseDTO from(AppVersion appVersion) { + return AppVersionResponseDTO.builder() + .minSupportedVersion(appVersion.getMinSupportedVersion()) + .latestVersion(appVersion.getLatestVersion()) + .build(); + } +} diff --git a/src/main/java/com/example/chalpu/version/repository/AppVersionRepository.java b/src/main/java/com/example/chalpu/version/repository/AppVersionRepository.java new file mode 100644 index 0000000..bfaa420 --- /dev/null +++ b/src/main/java/com/example/chalpu/version/repository/AppVersionRepository.java @@ -0,0 +1,15 @@ +package com.example.chalpu.version.repository; + +import com.example.chalpu.version.domain.AppVersion; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface AppVersionRepository extends JpaRepository { + + @Query("SELECT av FROM AppVersion av ORDER BY av.createdAt DESC LIMIT 1") + Optional findLatestVersion(); +} diff --git a/src/main/java/com/example/chalpu/version/service/AppVersionService.java b/src/main/java/com/example/chalpu/version/service/AppVersionService.java new file mode 100644 index 0000000..902e63b --- /dev/null +++ b/src/main/java/com/example/chalpu/version/service/AppVersionService.java @@ -0,0 +1,68 @@ +package com.example.chalpu.version.service; + +import com.example.chalpu.common.exception.AppVersionException; +import com.example.chalpu.common.exception.ErrorMessage; +import com.example.chalpu.version.domain.AppVersion; +import com.example.chalpu.version.dto.AppVersionRequestDTO; +import com.example.chalpu.version.dto.AppVersionResponseDTO; +import com.example.chalpu.version.repository.AppVersionRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class AppVersionService { + + private final AppVersionRepository appVersionRepository; + + /** + * 최신 앱 버전 정보 조회 + */ + public AppVersionResponseDTO getLatestVersion() { + AppVersion latestVersion = appVersionRepository.findLatestVersion() + .orElseThrow(() -> new AppVersionException(ErrorMessage.APP_VERSION_NOT_FOUND)); + + return AppVersionResponseDTO.from(latestVersion); + } + + public AppVersionResponseDTO getVersionById(Long id) { + AppVersion version = appVersionRepository.findById(id) + .orElseThrow(() -> new AppVersionException(ErrorMessage.APP_VERSION_NOT_FOUND)); + + return AppVersionResponseDTO.from(version); + } + + @Transactional + public AppVersionResponseDTO updateVersion(Long id, AppVersionRequestDTO requestDTO) { + AppVersion version = appVersionRepository.findById(id) + .orElseThrow(() -> new AppVersionException(ErrorMessage.APP_VERSION_NOT_FOUND)); + + AppVersion updatedVersion = AppVersion.builder() + .id(version.getId()) + .minSupportedVersion(requestDTO.getMinSupportedVersion()) + .latestVersion(requestDTO.getLatestVersion()) + .platform(requestDTO.getPlatform()) + .description(requestDTO.getDescription()) + .build(); + + AppVersion savedVersion = appVersionRepository.save(updatedVersion); + return AppVersionResponseDTO.from(savedVersion); + } + + @Transactional + public AppVersionResponseDTO createVersion(AppVersionRequestDTO requestDTO) { + AppVersion newVersion = AppVersion.builder() + .minSupportedVersion(requestDTO.getMinSupportedVersion()) + .latestVersion(requestDTO.getLatestVersion()) + .platform(requestDTO.getPlatform()) + .description(requestDTO.getDescription()) + .build(); + + AppVersion savedVersion = appVersionRepository.save(newVersion); + return AppVersionResponseDTO.from(savedVersion); + } +}