Skip to content

Product repository#140

Merged
aaudin90 merged 6 commits intomasterfrom
ProductRepository
Jan 29, 2026
Merged

Product repository#140
aaudin90 merged 6 commits intomasterfrom
ProductRepository

Conversation

@aaudin90
Copy link
Collaborator

No description provided.

aaudin90 and others added 6 commits January 20, 2026 01:09
… state management

Introduce a sealed class representing all possible states of product loading:
- Idle: Initial state, no loading attempt yet
- Loading: Currently fetching products from billing library
- Success: Products loaded successfully (requires non-empty product list)
- Failed: Loading failed with error code and retriable logic

The sealed class ensures exhaustive when expressions and prevents
invalid state combinations. Includes retry limits check (APPHUD_DEFAULT_RETRIES
and MAX_TOTAL_PRODUCTS_RETRIES) and retriable error code detection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement thread-safe repository using StateFlow for managing product
loading state. Provides MVI-pattern state transitions:

- transitionToLoading(): Derives retry counts from current state
- transitionToSuccess(): Merges new products with existing by productId
- transitionToFailed(): Preserves cached products and retry counts
- markAsResponded(): Marks callbacks as notified
- rollbackRetryCounters(): Decrements counters when no actual request made
- reset(): Returns to Idle state

StateFlow enables reactive observation of state changes throughout the SDK.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…Repository

Add comprehensive test coverage for new product loading state management:

ProductLoadingStateTest:
- State property tests (isFinished, isLoading, products, hasRespondedWithCallback)
- isRetriable logic with all retriable and non-retriable error codes
- Retry limit boundary tests
- Exhaustive when expression verification

ProductRepositoryTest:
- State transition lifecycle tests
- Retry counter increment/decrement logic
- Product merging behavior (no duplicates, preserves existing)
- markAsResponded and reset functionality
- rollbackRetryCounters edge cases

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace scattered mutable state variables (productsStatus, respondedWithProducts,
loadingStoreProducts, productsResponseCode, loadedDetails, etc.) with centralized
ProductRepository.

Changes in ApphudInternal+Products.kt:
- Remove ApphudProductsStatus enum and global state variables
- Use productRepository.state.value for state checks
- Call transitionToLoading/transitionToSuccess/transitionToFailed for state changes
- Replace Thread.sleep with coroutine delay in retryProductsLoad
- Simplify isRetriableProductsRequest using state.isRetriable

Changes in ApphudInternal.kt:
- Add productRepository property via ServiceLocator
- Replace productDetails CopyOnWriteArrayList with computed property
- Remove updateProductState synchronized block (repository handles merging)
- Update logging and error handling to use state.responseCode
- Reset productRepository on logout

Changes in ServiceLocator.kt:
- Add ProductRepository instance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Preserve paywalls and placements in UserRepository.setCurrentUser()
when server returns empty ones. This happens when /subscriptions
endpoint is called for purchase verification - it doesn't return
paywalls, only subscription data.

The fix merges existing paywalls/placements into the new user object
instead of completely replacing it.

Also removed dead code in ApphudInternal (paywallsPrepared variable
was set but never used).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add PrettyHttpLoggingInterceptor for formatted HTTP request/response
logging with unique 8-character traceId to correlate requests with
their responses in logs.

Components added:
- PrettyJsonFormatter: formats JSON with indentation for readability
- PrettyHttpLoggingInterceptor: logs HTTP traffic with traceId prefix
- ServiceLocator: wires up the new interceptor to OkHttp clients

Log format example:
[a1b2c3d4] Start POST request https://api.apphud.com/v2/customers
[a1b2c3d4] Finished POST request ... with response: 200

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
@aaudin90 aaudin90 merged commit c165a5f into master Jan 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant