diff --git a/update-service/src/main/java/com/xuqm/update/repository/AppVersionRepository.java b/update-service/src/main/java/com/xuqm/update/repository/AppVersionRepository.java index f01fa24..7a42bb2 100644 --- a/update-service/src/main/java/com/xuqm/update/repository/AppVersionRepository.java +++ b/update-service/src/main/java/com/xuqm/update/repository/AppVersionRepository.java @@ -39,8 +39,9 @@ public interface AppVersionRepository extends JpaRepository findAllWithUnderReviewStores(); - // Also used by poll to detect pre-existing live versions on REJECTED stores - @Query(value = "SELECT * FROM update_app_version WHERE store_review_status LIKE '%UNDER_REVIEW%' OR store_review_status LIKE '%REJECTED%'", nativeQuery = true) + // Also used by poll to detect pre-existing live versions on REJECTED stores, + // and to clean stale nonCurrentRelease/preExisting marks on APPROVED stores. + @Query(value = "SELECT * FROM update_app_version WHERE store_review_status LIKE '%UNDER_REVIEW%' OR store_review_status LIKE '%REJECTED%' OR store_review_status LIKE '%nonCurrentRelease%' OR store_review_status LIKE '%preExisting%'", nativeQuery = true) List findAllWithUnderReviewOrRejectedStores(); List findByAppKeyAndPlatformAndVersionCodeAndIdNot( diff --git a/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java b/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java index 728662a..fea4af8 100644 --- a/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java +++ b/update-service/src/main/java/com/xuqm/update/service/StoreSubmissionService.java @@ -687,7 +687,7 @@ public class StoreSubmissionService { public void pollStoreReviewStatus() { List candidates = versionRepo.findAllWithUnderReviewOrRejectedStores(); if (candidates.isEmpty()) return; - log.info("Store review poll: checking {} version(s) with UNDER_REVIEW/REJECTED stores", candidates.size()); + log.info("Store review poll: checking {} version(s) with UNDER_REVIEW/REJECTED/stale-marked stores", candidates.size()); for (AppVersionEntity v : candidates) { Map reviewMap; try { @@ -703,7 +703,9 @@ public class StoreSubmissionService { String state = info.get("state") instanceof String s ? s : ""; boolean isUnderReview = "UNDER_REVIEW".equals(state); boolean isRejected = "REJECTED".equals(state); - if (!isUnderReview && !isRejected) continue; + boolean hasStaleMark = Boolean.TRUE.equals(info.get("nonCurrentRelease")) + || Boolean.TRUE.equals(info.get("preExisting")); + if (!isUnderReview && !isRejected && !hasStaleMark) continue; AppStoreConfigEntity cfg; try { cfg = configRepo.findTopByAppKeyAndStoreTypeOrderByUpdatedAtDesc(v.getAppKey(), @@ -717,7 +719,28 @@ public class StoreSubmissionService { StoreRemoteState polled = queryRemoteState(storeType, v, creds); if (polled == null) { log.debug("Store review poll: {}/{} returned null (no poll API for this store)", v.getId(), storeType); - } else if (isUnderReview) { + continue; + } + // Stale-state cleanup for APPROVED stores that still carry nonCurrentRelease/preExisting + // from an earlier buggy write. This can happen when a webhook pushed APPROVED before the + // version-comparison fix was deployed, leaving stale marks that block new submissions. + if (hasStaleMark && !isUnderReview && !isRejected) { + if (!polled.getOnlineVersionCode().isBlank()) { + int cmp = compareVersionCodes(polled.getOnlineVersionCode(), String.valueOf(v.getVersionCode())); + if (cmp < 0) { + log.info("Store review poll: {}/{} clearing stale nonCurrentRelease/preExisting — online {} < submitted {}", + v.getId(), storeType, polled.getOnlineVersionCode(), v.getVersionCode()); + storeService.clearStoreReview(v.getId(), storeType); + continue; + } + } else if (!polled.isCurrentSubmissionLive()) { + log.info("Store review poll: {}/{} clearing stale nonCurrentRelease/preExisting — onlineVersionCode blank and not current live", + v.getId(), storeType); + storeService.clearStoreReview(v.getId(), storeType); + continue; + } + } + if (isUnderReview) { AppVersionEntity.StoreReviewState mappedState = mapToStoreReviewState(polled.getReviewState()); if (mappedState != AppVersionEntity.StoreReviewState.UNDER_REVIEW) { log.info("Store review poll: {}/{} status changed to {}", v.getId(), storeType, mappedState);