Complete re-validation remediation: KMP architecture, iOS platform, XCUITest rewrite
Phases 1-6 of fixes.md — closes all 13 issues from codex_issues_2.md re-validation: KMP Architecture: - Fix subscription purchase/restore response contract (VerificationResponse aligned) - Add feature benefits auth token + APILayer init flow - Remove ResidenceFormScreen direct API bypass (use APILayer) - Wire paywall purchase/restore to real SubscriptionApi calls iOS Platform: - Add iOS Keychain token storage via Swift KeychainHelper - Implement Google Sign-In via ASWebAuthenticationSession (GoogleSignInManager) - DocumentViewModelWrapper observes DataManager for auto-updates - Add missing accessibility identifiers (document, task columns, Google Sign-In) XCUITest Rewrite: - Rewrite test infrastructure: zero sleep() calls, accessibility ID lookups - Create AuthCriticalPathTests and NavigationCriticalPathTests - Delete 14 legacy brittle test files (Suite0-10, templates) - Fix CaseraTests module import (@testable import Casera) All platforms build clean. TEST BUILD SUCCEEDED. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package com.example.casera.platform
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.example.casera.ui.subscription.UpgradeScreen
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
actual fun PlatformUpgradeScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onSubscriptionChanged: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val activity = context as? Activity
|
||||
val billingManager = remember { BillingManager.getInstance(context) }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
// Load products on launch
|
||||
LaunchedEffect(Unit) {
|
||||
billingManager.startConnection(
|
||||
onSuccess = {
|
||||
scope.launch { billingManager.loadProducts() }
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Watch for successful purchase
|
||||
val purchasedProductIDs by billingManager.purchasedProductIDs.collectAsState()
|
||||
var initialPurchaseCount by remember { mutableStateOf(purchasedProductIDs.size) }
|
||||
|
||||
LaunchedEffect(purchasedProductIDs) {
|
||||
if (purchasedProductIDs.size > initialPurchaseCount) {
|
||||
onSubscriptionChanged()
|
||||
onNavigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
UpgradeScreen(
|
||||
onNavigateBack = onNavigateBack,
|
||||
onPurchase = { planId ->
|
||||
val product = billingManager.getProduct(planId)
|
||||
if (product != null && activity != null) {
|
||||
billingManager.launchPurchaseFlow(activity, product)
|
||||
}
|
||||
},
|
||||
onRestorePurchases = {
|
||||
scope.launch {
|
||||
val restored = billingManager.restorePurchases()
|
||||
if (restored) {
|
||||
onSubscriptionChanged()
|
||||
onNavigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user