fix: harden store API follow-up - #300
Conversation
|
Important Review skippedNo new commits to review since the last review. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThe PR adds canonical KISS/SSOT review rules, interval-based ChangesCanonical review guidance
Apple promoted-purchase offer leasing
Google Activity-aware store lifecycle
Store API metadata and documentation
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant PromotedProductListener
participant ProductAPI
participant PurchaseRequest
participant StoreKit
PromotedProductListener->>ProductAPI: fetch promoted SKU with all query type
ProductAPI-->>PromotedProductListener: return product or subscription
PromotedProductListener->>PurchaseRequest: build matching request type
PurchaseRequest->>StoreKit: submit purchase
sequenceDiagram
participant ComposeScreen
participant IapContext
participant OpenIapStore
participant HorizonBilling
ComposeScreen->>IapContext: resolve current Activity
IapContext->>OpenIapStore: bind Activity by owner
OpenIapStore->>HorizonBilling: initialize with current Activity
HorizonBilling-->>OpenIapStore: return billing state
OpenIapStore-->>ComposeScreen: provide shared store
Possibly related PRs
Suggested labels: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx (1)
75-99: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winHandle failures inside each asynchronous listener.
fetchProductsandrequestPurchasecan fail. TypeScript and Dart discard the async listener result. C# uses anasync voidcallback. An uncaught Kotlin exception cancels the collector. Catch failures inside each listener so later promoted-product events still work.
packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx#L75-L99: add atry/catcharound the query and purchase flow.packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx#L160-L199: catch failures insidecollect.packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx#L208-L239: catch failures inside the stream callback.packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx#L253-L283: catch failures inside theSubscribecallback.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx` around lines 75 - 99, Wrap the asynchronous promoted-product handling in try/catch blocks so listener failures are contained and later events continue: in packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx lines 75-99, protect the query and purchase flow around the promotedProductListenerIOS callback; in lines 160-199, catch failures inside collect; in lines 208-239, catch failures inside the stream callback; and in lines 253-283, catch failures inside the Subscribe callback. Handle each caught failure using the surrounding implementation’s established error-reporting behavior.
🧹 Nitpick comments (1)
packages/apple/Sources/Helpers/IapState.swift (1)
270-296: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd the
IOSsuffix to the iOS-only lease operations.
record,lease,release, andconsumemanage ApplePurchaseIntentoffer state. Rename them with a finalIOSsuffix. Update the purchase flow and tests with the new names.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/apple/Sources/Helpers/IapState.swift` around lines 270 - 296, Rename the IapState methods record, lease, release, and consume to recordIOS, leaseIOS, releaseIOS, and consumeIOS, preserving their behavior. Update every purchase-flow call site and test reference to use the new IOS-suffixed names.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.codex/skills/review-self/SKILL.md:
- Line 112: Update the prohibition in review-pr.md for the PR fallback to
disallow any recurring loop, not only a five-minute loop, matching the broader
rule in the recurring workflow contract and preventing nested polling or
duplicate reviewer requests.
- Around line 132-137: Update the scheduled re-entry state capsule described in
the review-self skill to include both the user-requested interval and the
currently active interval. Ensure each wake-up reads and validates these
interval values before scheduling or continuing the recheck, preserving
non-default intervals instead of falling back to the five-minute default.
In `@libraries/maui-iap/src/OpenIap.Maui/Types.cs`:
- Around line 2248-2251: Update the generator or GraphQL source mapping for
AdvancedCommerceInfoIOS.Period so all subscription-period documentation is
emitted within one XML <summary> element; then regenerate Types.cs from
packages/gql and do not edit the generated file directly.
In `@packages/docs/src/pages/docs/updates/releases.tsx`:
- Line 28: Defer the August 10, 2026 release content until publication: in
packages/docs/src/pages/docs/updates/releases.tsx lines 28-28, remove or gate
the docs-3.1.0 link; in lines 39-49, defer storeApiFollowupReleases; and in
lines 195-206, remove the release note or rewrite it as planned-release content
without public package links.
In
`@packages/google/Example/src/main/java/dev/hyo/martie/screens/PurchaseFlowScreen.kt`:
- Line 60: Update currentOpenIapStore usage in PurchaseFlowScreen.kt at line 60
to bind the explicit storeParam to the current Activity before purchase
operations, or require a provider-managed store. Apply the same explicit-store
binding rule in SubscriptionFlowScreen.kt at line 96 so subscription requests
use an Activity-bound billing store.
In `@packages/google/openiap/src/main/java/dev/hyo/openiap/store/OpenIapStore.kt`:
- Around line 251-252: Add the same OpenIapError.MissingCurrentActivity `@throws`
KDoc entry to the no-argument initConnection() overload, which delegates to
initConnection(null), matching the documentation on the existing overload.
---
Outside diff comments:
In `@packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx`:
- Around line 75-99: Wrap the asynchronous promoted-product handling in
try/catch blocks so listener failures are contained and later events continue:
in packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx
lines 75-99, protect the query and purchase flow around the
promotedProductListenerIOS callback; in lines 160-199, catch failures inside
collect; in lines 208-239, catch failures inside the stream callback; and in
lines 253-283, catch failures inside the Subscribe callback. Handle each caught
failure using the surrounding implementation’s established error-reporting
behavior.
---
Nitpick comments:
In `@packages/apple/Sources/Helpers/IapState.swift`:
- Around line 270-296: Rename the IapState methods record, lease, release, and
consume to recordIOS, leaseIOS, releaseIOS, and consumeIOS, preserving their
behavior. Update every purchase-flow call site and test reference to use the new
IOS-suffixed names.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f2e690ce-080c-434d-977f-3ba518dc403d
⛔ Files ignored due to path filters (6)
packages/gql/src/generated/Types.csis excluded by!**/generated/**packages/gql/src/generated/Types.ktis excluded by!**/generated/**packages/gql/src/generated/Types.swiftis excluded by!**/generated/**packages/gql/src/generated/types.dartis excluded by!**/generated/**packages/gql/src/generated/types.gdis excluded by!**/generated/**packages/gql/src/generated/types.tsis excluded by!**/generated/**
📒 Files selected for processing (37)
.claude/commands/audit-code.md.claude/commands/review-pr.md.claude/skills/review-self/SKILL.md.codex/skills/openiap-workflows/SKILL.md.codex/skills/review-self/SKILL.md.codex/skills/review-self/agents/openai.yamlAGENTS.mdknowledge/_claude-context/context.mdknowledge/internal/03-coding-style.mdlibraries/expo-iap/src/types.tslibraries/flutter_inapp_purchase/lib/types.dartlibraries/godot-iap/addons/godot-iap/types.gdlibraries/kmp-iap/library/src/commonMain/kotlin/io/github/hyochan/kmpiap/openiap/Types.ktlibraries/maui-iap/src/OpenIap.Maui/Types.cslibraries/react-native-iap/src/types.tspackages/apple/Sources/Helpers/IapState.swiftpackages/apple/Sources/Models/Types.swiftpackages/apple/Sources/OpenIapModule.swiftpackages/apple/Tests/OpenIapTests.swiftpackages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsxpackages/docs/src/pages/docs/updates/releases.tsxpackages/google/Example/src/main/java/dev/hyo/martie/MainActivity.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/AllProductsScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/AvailablePurchasesScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/OfferCodeScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/OpenIapStoreContext.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/PurchaseFlowScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/SubscriptionFlowScreen.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/IapContext.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/OpenIapViewModel.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/Types.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/store/OpenIapStore.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/utils/ActivityUtils.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/utils/OwnerScopedValueBinding.ktpackages/google/openiap/src/test/java/dev/hyo/openiap/utils/OwnerScopedValueBindingTest.ktpackages/google/openiap/src/testHorizon/java/dev/hyo/openiap/utils/ActivityUtilsTest.ktpackages/gql/src/type-ios.graphql
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/google/Example/src/main/java/dev/hyo/martie/screens/OfferCodeScreen.kt (1)
39-43: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winHandle
initConnection()failures before resume reconciliation.
initConnection()returns a Boolean result fromOpenIapStore.initConnection(), and the resume path callsgetAvailablePurchases(null). If initialization fails, reconciliation can also fail while both failures are discarded. Store or surface the init error or retry before relying on the resume reconciliation result.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/google/Example/src/main/java/dev/hyo/martie/screens/OfferCodeScreen.kt` around lines 39 - 43, Update the LaunchedEffect around iapStore.initConnection() to inspect its Boolean result and handle initialization failure before allowing resume reconciliation to depend on getAvailablePurchases(null). Preserve successful initialization behavior, but retain or surface the initialization error and retry or stop reconciliation when initConnection() fails instead of discarding both failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In
`@packages/google/Example/src/main/java/dev/hyo/martie/screens/OfferCodeScreen.kt`:
- Around line 39-43: Update the LaunchedEffect around iapStore.initConnection()
to inspect its Boolean result and handle initialization failure before allowing
resume reconciliation to depend on getAvailablePurchases(null). Preserve
successful initialization behavior, but retain or surface the initialization
error and retry or stop reconciliation when initConnection() fails instead of
discarding both failures.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b16064c6-1df0-4693-8f38-7bfb07871860
⛔ Files ignored due to path filters (1)
packages/gql/src/generated/Types.csis excluded by!**/generated/**
📒 Files selected for processing (13)
.claude/commands/review-pr.md.codex/skills/review-self/SKILL.mdlibraries/maui-iap/src/OpenIap.Maui/Types.cspackages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsxpackages/google/Example/src/main/java/dev/hyo/martie/screens/AllProductsScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/AvailablePurchasesScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/OfferCodeScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/OpenIapStoreContext.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/PurchaseFlowScreen.ktpackages/google/Example/src/main/java/dev/hyo/martie/screens/SubscriptionFlowScreen.ktpackages/google/openiap/src/main/java/dev/hyo/openiap/store/OpenIapStore.ktpackages/gql/codegen/plugins/csharp.tspackages/gql/src/codegen-defaults.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- packages/google/Example/src/main/java/dev/hyo/martie/screens/OpenIapStoreContext.kt
- .claude/commands/review-pr.md
- packages/google/Example/src/main/java/dev/hyo/martie/screens/AllProductsScreen.kt
- .codex/skills/review-self/SKILL.md
- packages/google/openiap/src/main/java/dev/hyo/openiap/store/OpenIapStore.kt
- packages/docs/src/pages/docs/events/ios/promoted-product-listener-ios.tsx
- packages/google/Example/src/main/java/dev/hyo/martie/screens/PurchaseFlowScreen.kt
Summary
Changes
Store contracts and Apple
AdvancedCommerceInfoIOS.periodavailability and regenerate all synchronized SDK types.Google and Horizon
Guidance and documentation
knowledge/internal/03-coding-style.md.Test plan
audit:docs,audit:parity, andaudit:release-statepassedPreview
No new interactive UI is introduced. The visible documentation changes are release text and language code samples; the build, typecheck, generated-sync, and audit results above are the applicable proof.
Summary by CodeRabbit
New Features
Documentation