diff --git a/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabFragment.kt b/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabFragment.kt index 5d25ae1035..7c19399417 100644 --- a/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabFragment.kt +++ b/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabFragment.kt @@ -86,6 +86,7 @@ class InsuranceTabFragment(private val lazyListState: () -> LazyListState? = { n setContent { RenderUiTronDataSecondary(lazyListState) } } observeCtaData() + viewModel.clearCacheOnVersionUpgrade() if ( FirebaseRemoteConfigHelper.getBoolean( key = FirebaseRemoteConfigHelper.ENABLE_REACT_PREFETCH_IN_TAB, diff --git a/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabRepository.kt b/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabRepository.kt index f57ae57eb5..059baa7942 100644 --- a/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabRepository.kt +++ b/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabRepository.kt @@ -13,6 +13,7 @@ import com.navi.common.network.models.RepoResult import com.navi.common.network.retrofit.ResponseCallback import com.navi.common.utils.Constants.GZIP import com.navi.common.utils.TemporaryStorageHelper +import com.navi.insurance.common.models.ClearCacheResponse import com.navi.insurance.common.models.InsuranceTabResponse import com.navi.insurance.common.models.ToastRequestBody import com.navi.insurance.models.response.ClosePolicyCardResponse @@ -50,4 +51,12 @@ constructor(@SuperAppRetroFit private val apiService: RetrofitService) : Respons apiService.closePolicyCard(applicationId = quoteId, target = ModuleName.GI.name) ) } + + suspend fun clearCache(): RepoResult { + return apiResponseCallback( + apiService.clearCache( + target = ModuleName.GI.name, + ) + ) + } } diff --git a/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabViewModel.kt b/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabViewModel.kt index 5848076075..1643567650 100644 --- a/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabViewModel.kt +++ b/android/app/src/main/java/com/naviapp/common/tab/InsuranceTabViewModel.kt @@ -10,6 +10,7 @@ package com.naviapp.common.tab import androidx.lifecycle.viewModelScope import com.google.firebase.crashlytics.FirebaseCrashlytics import com.navi.analytics.utils.NaviTrackEvent +import com.navi.base.cache.repository.NaviCacheRepository import com.navi.base.model.CtaData import com.navi.base.utils.isNotNull import com.navi.base.utils.isNull @@ -20,6 +21,7 @@ import com.navi.common.model.ModuleNameV2 import com.navi.common.network.models.ErrorMetaData import com.navi.common.uitron.model.action.CtaAction import com.navi.common.utils.SingleLiveEvent +import com.navi.common.utils.isValidResponse import com.navi.common.viewmodel.BaseVM import com.navi.insurance.common.models.GiErrorMetaData import com.navi.insurance.common.models.InsuranceTabState @@ -41,6 +43,7 @@ class InsuranceTabViewModel @Inject constructor( private val repository: InsuranceTabRepository, + private val naviCacheRepository: NaviCacheRepository ) : BaseVM() { init { @@ -191,4 +194,36 @@ constructor( private fun handleCtaAction(ctaAction: CtaAction) { ctaAction.ctaData?.let { ctaData -> redirectionCta.postValue(ctaAction.ctaData) } } + + fun clearCacheOnVersionUpgrade() { + viewModelScope.safeLaunch(coroutineContext = Dispatchers.IO) { + val response = repository.clearCache() + if (response.isValidResponse()) { + response.data?.pageVersionList?.forEach { item -> + val entity = naviCacheRepository.get(key = item.pageName.orEmpty()) + entity?.let { + if (it.version != item.version.orZero()) { + naviCacheRepository.clear(key = item.pageName.orEmpty()) + } + } + } + } else { + val errorUnifiedResponse = + getErrorUnifiedResponse( + errors = response.errors, + error = response.error, + errorMetaData = + ErrorMetaData( + methodName = ApiErrorTagType.INSURANCE_TAB_SCREEN_PAGE_ERROR.value, + flowName = GiErrorMetaData.INSURANCE_TAB_FLOW + ) + ) + sendFailureEvent( + NaviAnalytics.INSURANCE_TAB_INIT, + errorUnifiedResponse, + ModuleNameV2.Insurance.name + ) + } + } + } } diff --git a/android/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt b/android/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt index 29d958d2ec..bd24277421 100644 --- a/android/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt +++ b/android/app/src/main/java/com/naviapp/network/retrofit/RetrofitService.kt @@ -57,6 +57,7 @@ import com.navi.common.utils.Constants.HEADER_VERTICAL_TYPE import com.navi.common.utils.Constants.HEADER_X_PLATFORM import com.navi.common.utils.Constants.HEADER_X_TENANT_ID import com.navi.common.utils.Constants.ScreenLockConstants.X_IS_MOBILE_SCREEN_LOCK_SET +import com.navi.insurance.common.models.ClearCacheResponse import com.navi.insurance.common.models.InsuranceTabResponse import com.navi.insurance.common.models.ToastRequestBody import com.navi.insurance.models.request.FlagUpdateRequest @@ -1836,6 +1837,11 @@ interface RetrofitService { @Header("X-Target") target: String = ModuleName.SAPHYRA.name, ): Response> + @GET("/gi/static-pages/versions") + suspend fun clearCache( + @Header("X-Target") target: String + ): Response> + @GET("/forge/screen/{screenId}") suspend fun fetchInvestmentTabForgeScreen( @Header(X_IS_MOBILE_SCREEN_LOCK_SET) isMobileScreenLockSet: Boolean? = null, diff --git a/android/navi-common/src/main/java/com/navi/common/constants/DBCacheConstants.kt b/android/navi-common/src/main/java/com/navi/common/constants/DBCacheConstants.kt index 6a0ead9720..e373ff6dad 100644 --- a/android/navi-common/src/main/java/com/navi/common/constants/DBCacheConstants.kt +++ b/android/navi-common/src/main/java/com/navi/common/constants/DBCacheConstants.kt @@ -12,7 +12,9 @@ object DBCacheConstants { const val NAVI_HL_INTRO_SCREEN_CACHE_KEY = "NAVI_HL_INTRO_SCREEN_CACHE_KEY" const val NAVI_GI_LANDING_PAGE_CACHE_KEY = "NAVI_GI_LANDING_PAGE_CACHE_KEY" const val NAVI_GI_BENEFIT_PAGE_CACHE_KEY = "NAVI_GI_BENEFIT_PAGE_CACHE_KEY" - const val GI_PRE_DIAB_RESULT_CACHE_KEY = "GI_PRE_DIAB_RESULT_CACHE_KEY" + const val DIGITAL_CLAIMS_PRE_PURCHASE_DATA = "DIGITAL_CLAIMS_PRE_PURCHASE_DATA" + const val NAVI_GI_AUTOPAY_SUMMARY_SCREEN_CACHE_KEY = "NAVI_GI_AUTOPAY_SUMMARY_SCREEN_CACHE_KEY" + const val PD_QUESTIONNAIRE_PAGE = "PD_QUESTIONNAIRE_PAGE" const val GI_PRE_DIAB_QUESTION_CACHE_KEY = "GI_PRE_DIAB_QUESTION_CACHE_KEY" const val COIN_HOME_SCREEN_CACHE_KEY = "COIN_HOME_SCREEN_CACHE_KEY" const val LEADERBOARD_SCREEN_CACHE_KEY = "LEADERBOARD_SCREEN_CACHE_KEY" diff --git a/android/navi-insurance/src/main/java/com/navi/insurance/common/models/ClearCacheResponse.kt b/android/navi-insurance/src/main/java/com/navi/insurance/common/models/ClearCacheResponse.kt new file mode 100644 index 0000000000..f57c252b82 --- /dev/null +++ b/android/navi-insurance/src/main/java/com/navi/insurance/common/models/ClearCacheResponse.kt @@ -0,0 +1,19 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.insurance.common.models + +import com.google.gson.annotations.SerializedName + +data class ClearCacheResponse( + @SerializedName("pageVersions") val pageVersionList: List? = null, +) + +data class PageVersion( + @SerializedName("pageName") val pageName: String? = null, + @SerializedName("version") val version: Int? = null, +) diff --git a/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/IncentiviseAutopayVM.kt b/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/IncentiviseAutopayVM.kt index d84906d58d..b04b782ae7 100644 --- a/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/IncentiviseAutopayVM.kt +++ b/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/IncentiviseAutopayVM.kt @@ -14,6 +14,7 @@ import com.google.gson.Gson import com.navi.base.cache.model.NaviCacheAltSourceEntity import com.navi.base.cache.repository.NaviCacheRepository import com.navi.base.model.CtaData +import com.navi.common.constants.DBCacheConstants import com.navi.common.constants.VENDOR_NAVI_API import com.navi.common.di.CoroutineDispatcherProvider import com.navi.common.model.ModuleName @@ -114,8 +115,14 @@ constructor( if (type.equals(SUMMARY_INSURANCE_TAB)) { val cachedResponse = naviCacheRepository.getDataOrFetchFromAltSource( - SUMMARY_INSURANCE_TAB, - getDataFromAltSource = { getPageResponseFromAPI(type, policyId) } + key = DBCacheConstants.NAVI_GI_AUTOPAY_SUMMARY_SCREEN_CACHE_KEY, + getDataFromAltSource = { + getPageResponseFromAPI( + type, + policyId, + key = DBCacheConstants.NAVI_GI_AUTOPAY_SUMMARY_SCREEN_CACHE_KEY + ) + } ) RepoResult( statusCode = 200, @@ -151,8 +158,10 @@ constructor( private suspend fun getPageResponseFromAPI( pageType: String?, - policyId: String? + policyId: String?, + key: String ): NaviCacheAltSourceEntity { + val version = 1 val response = incentiviseAutopayRepository.fetchIncentiviseAutopayResponse(pageType, policyId) @@ -173,7 +182,7 @@ constructor( return NaviCacheAltSourceEntity( value = Gson().toJson(response.data!!), isSuccess = true, - version = 1 + version = version ) } diff --git a/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/LandingPageInfoViewModel.kt b/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/LandingPageInfoViewModel.kt index 4f7814ce91..85e18f35a5 100644 --- a/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/LandingPageInfoViewModel.kt +++ b/android/navi-insurance/src/main/java/com/navi/insurance/common/viewmodel/LandingPageInfoViewModel.kt @@ -63,7 +63,7 @@ constructor( val landingPageResponse = if (requestPageType == LandingPageInfoFragment.STATIC_BENEFITS_SCREEN) { naviCacheRepository.getDataOrFetchFromAltSource( - key = DBCacheConstants.NAVI_GI_BENEFIT_PAGE_CACHE_KEY + tabId.orEmpty(), + key = DBCacheConstants.NAVI_GI_BENEFIT_PAGE_CACHE_KEY, version = cacheVersion.toLong(), getDataFromAltSource = { fetchStaticBenefitsResponseFromApi( @@ -71,7 +71,8 @@ constructor( applicationType, tabId, preQuoteExists, - cacheVersion + cacheVersion, + DBCacheConstants.NAVI_GI_BENEFIT_PAGE_CACHE_KEY ) } ) @@ -150,11 +151,13 @@ constructor( applicationType: String? = null, tabId: String? = null, preQuoteExists: Boolean? = null, - cacheVersion: Int + cacheVersion: Int, + key: String ): NaviCacheAltSourceEntity { + val version = cacheVersion if (requestPageType.isNullOrEmpty()) { _landingInfoPageResponseStateFlow.emit(LandingPageInfoState.Error) - return NaviCacheAltSourceEntity(value = null, version = cacheVersion, isSuccess = true) + return NaviCacheAltSourceEntity(value = null, version = version, isSuccess = true) } val response = landingPageInfoRepository.fetchBenefitPageInfo( @@ -166,7 +169,7 @@ constructor( if (response.error == null && response.errors.isNullOrEmpty() && response.data != null) { return NaviCacheAltSourceEntity( value = Gson().toJson(response.data), - version = response.data?.screenVersion ?: 1, + version = version, isSuccess = true ) // TODO remove @@ -182,7 +185,7 @@ constructor( ) ) } - return NaviCacheAltSourceEntity(value = null, version = cacheVersion, isSuccess = true) + return NaviCacheAltSourceEntity(value = null, version = version, isSuccess = true) } private fun saveFooterCta(landingPageInfoResponse: LandingPageInfoResponse?) { diff --git a/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/models/PdResultsData.kt b/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/models/PdResultsData.kt index a54e9be398..aebed65a75 100644 --- a/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/models/PdResultsData.kt +++ b/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/models/PdResultsData.kt @@ -15,5 +15,6 @@ data class PdResultsData( @SerializedName("screenVersion") val screenVersion: Int? = null, @SerializedName("widgetData") val widgetData: List? = null, @SerializedName("footerWidget") val footerWidget: GenericWidgetDataInfo? = null, - @SerializedName("resultBackButtonCta") val resultBackButtonCta: CtaData? = null + @SerializedName("resultBackButtonCta") val resultBackButtonCta: CtaData? = null, + @SerializedName("pageVersion") val pageVersion: Int? = null, ) diff --git a/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/viewmodel/PreDiabetesVM.kt b/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/viewmodel/PreDiabetesVM.kt index 45d455a212..9cd7946cd6 100644 --- a/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/viewmodel/PreDiabetesVM.kt +++ b/android/navi-insurance/src/main/java/com/navi/insurance/engagement/pre_diabetes_check/viewmodel/PreDiabetesVM.kt @@ -120,7 +120,12 @@ constructor( naviCacheRepository.getDataOrFetchFromAltSource( key = DBCacheConstants.GI_PRE_DIAB_QUESTION_CACHE_KEY, version = cacheVersion.toLong(), - getDataFromAltSource = { getQuestionnaireDataFromApi(cacheVersion) } + getDataFromAltSource = { + getQuestionnaireDataFromApi( + cacheVersion, + key = DBCacheConstants.GI_PRE_DIAB_QUESTION_CACHE_KEY + ) + } ) response?.let { naviCacheEntity -> @@ -136,7 +141,11 @@ constructor( } } - private suspend fun getQuestionnaireDataFromApi(cacheVersion: Int): NaviCacheAltSourceEntity { + private suspend fun getQuestionnaireDataFromApi( + cacheVersion: Int, + key: String + ): NaviCacheAltSourceEntity { + val version = cacheVersion val response = repository.getQuestionnaireData() if (response.error == null && response.errors.isNullOrEmpty() && response.data != null) { @@ -158,7 +167,7 @@ constructor( ) ) } - return NaviCacheAltSourceEntity(value = null, version = cacheVersion, isSuccess = true) + return NaviCacheAltSourceEntity(value = null, version = version, isSuccess = true) } fun getResultScreenData(cacheVersion: Int = 0, overrideScoreType: String? = null) { @@ -187,12 +196,10 @@ constructor( _scoreRangeFlow.emit(overrideScoreType ?: scoreType) val response = naviCacheRepository.getDataOrFetchFromAltSource( - key = - DBCacheConstants.GI_PRE_DIAB_RESULT_CACHE_KEY + - (overrideScoreType ?: scoreType), + key = DBCacheConstants.PD_QUESTIONNAIRE_PAGE + (overrideScoreType ?: scoreType), version = cacheVersion.toLong(), getDataFromAltSource = { - getResultScreenDataFromApi((overrideScoreType ?: scoreType), cacheVersion) + getResultScreenDataFromApi((overrideScoreType ?: scoreType)) } ) @@ -210,14 +217,13 @@ constructor( private suspend fun getResultScreenDataFromApi( scoreType: String, - cacheVersion: Int ): NaviCacheAltSourceEntity { val response = repository.getResultScreenData(scoreType) if (response.error == null && response.errors.isNullOrEmpty() && response.data != null) { return NaviCacheAltSourceEntity( value = Gson().toJson(response.data), - version = 1, + version = response.data?.pageVersion ?: 1, isSuccess = true ) } else { @@ -233,7 +239,11 @@ constructor( ) ) } - return NaviCacheAltSourceEntity(value = null, version = cacheVersion, isSuccess = true) + return NaviCacheAltSourceEntity( + value = null, + version = response.data?.pageVersion ?: 1, + isSuccess = true + ) } private fun saveScoreToBackend(score: Float?) { diff --git a/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/model/DigitalClaimScreenResponse.kt b/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/model/DigitalClaimScreenResponse.kt index 43ae5ab55f..233bd33758 100644 --- a/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/model/DigitalClaimScreenResponse.kt +++ b/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/model/DigitalClaimScreenResponse.kt @@ -24,6 +24,7 @@ data class DigitalClaimScreenResponse( @SerializedName("bulletIcon") val bulletIcon: ImageFieldData? = null, @SerializedName("firstTabContent") val firstTabContent: TabContent? = null, @SerializedName("secondTabContent") val secondTabContent: TabContent? = null, + @SerializedName("pageVersion") val pageVersion: Int? = null, ) @Parcelize diff --git a/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/viewmodel/DigitalClaimVM.kt b/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/viewmodel/DigitalClaimVM.kt index c7b80b7c3c..609d06890d 100644 --- a/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/viewmodel/DigitalClaimVM.kt +++ b/android/navi-insurance/src/main/java/com/navi/insurance/static_digital_claim/viewmodel/DigitalClaimVM.kt @@ -12,6 +12,7 @@ import com.google.gson.Gson import com.navi.base.cache.model.NaviCacheAltSourceEntity import com.navi.base.cache.repository.NaviCacheRepository import com.navi.common.ResponseState +import com.navi.common.constants.DBCacheConstants import com.navi.common.di.CoroutineDispatcherProvider import com.navi.common.model.ModuleName import com.navi.common.network.models.RepoResult @@ -20,7 +21,6 @@ import com.navi.common.utils.CommonNaviAnalytics import com.navi.insurance.common.GiBaseVM import com.navi.insurance.common.models.GiErrorMetaData import com.navi.insurance.common.util.ActionHandler -import com.navi.insurance.common.util.NavigationHandler import com.navi.insurance.network.ApiErrorTagType import com.navi.insurance.static_digital_claim.model.DigitalClaimScreenResponse import com.navi.insurance.static_digital_claim.repository.DigitalClaimRepository @@ -83,7 +83,7 @@ constructor( _responseDataFlow.emit(ResponseState.Loading) val cachedResponse = naviCacheRepository.getDataOrFetchFromAltSource( - NavigationHandler.URL_STATIC_DIGITAL_CLAIM, + DBCacheConstants.DIGITAL_CLAIMS_PRE_PURCHASE_DATA, getDataFromAltSource = { getPageResponseFromAPI() } ) val response = @@ -135,7 +135,7 @@ constructor( return NaviCacheAltSourceEntity( value = Gson().toJson(response.data!!), isSuccess = true, - version = 1 + version = response.data?.pageVersion ?: 1 ) } diff --git a/network/NetworkService.ts b/network/NetworkService.ts index ddf3a3cbff..99ecaa084d 100644 --- a/network/NetworkService.ts +++ b/network/NetworkService.ts @@ -25,7 +25,7 @@ export const get = async ( baseURL: baseUrl ? baseUrl : BASE_URL, timeout: 10000, headers: requestConfig.headers, - signal: newAbortSignal(11000) + signal: newAbortSignal(11000), }); addBundleVersionToHeader(axiosInstance); @@ -52,7 +52,7 @@ export const post = async ( baseURL: baseUrl ? baseUrl : BASE_URL, timeout: 10000, headers: requestConfig.headers, - signal: newAbortSignal(11000) + signal: newAbortSignal(11000), }); addBundleVersionToHeader(axiosInstance); @@ -83,7 +83,7 @@ export const patch = async ( baseURL: baseUrl ? baseUrl : BASE_URL, timeout: 10000, headers: requestConfig.headers, - signal: newAbortSignal(11000) + signal: newAbortSignal(11000), }); addBundleVersionToHeader(axiosInstance);