Skip to content

refactor(remote-config): manifest persistence, request body handling#3612

Draft
tonidero wants to merge 3 commits into
mainfrom
06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling
Draft

refactor(remote-config): manifest persistence, request body handling#3612
tonidero wants to merge 3 commits into
mainfrom
06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling

Conversation

@tonidero

@tonidero tonidero commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Description

This PR is part of the stack to support the new Remote configuration endpoint.

In this PR, we add support to cache the Manifest in the remote config response, and then post it back in the request so the backend can decide what needs updating.


Note

Medium Risk
Changes the remote config network contract and adds on-disk state that must stay consistent with server diffs; impact is limited while RemoteConfigManager is not yet wired into SDK lifecycle.

Overview
Adds manifest replay for /v2/config: Backend.getRemoteConfig now takes a RemoteConfiguration.Manifest, serializes it into a { "manifest": … } request body (instead of null), and treats HTTP 204 as “no change” via a null RCContainer callback.

Introduces RemoteConfigDiskCache to persist the last manifest plus merged topic bodies under noBackupFilesDir/RevenueCat/, and RemoteConfigManager to read that cache, send the persisted manifest (or a default app domain on first run), merge/prune topics on 200, and skip writes on 204, errors, or parse failures. RemoteConfiguration.parse(ByteBuffer) duplicates the buffer so RC container views are not consumed.

Lifecycle wiring and blob/topic handlers are not hooked up yet; this PR is the persistence + request/response handling layer, with expanded backend and unit tests.

Reviewed by Cursor Bugbot for commit 4d924bb. Bugbot is set up for automated code reviews on this repo. Configure here.

@tonidero tonidero changed the title Phase 2: /v2/config manifest persistence, request body + 204 handling refactor(remote-config): manifest persistence, request body + 204 handling Jun 16, 2026
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from 83d0b57 to b8c0117 Compare June 16, 2026 10:44
@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.42857% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.25%. Comparing base (b6031a0) to head (0c7d740).

Files with missing lines Patch % Lines
...hases/common/remoteconfig/RemoteConfigDiskCache.kt 66.66% 9 Missing and 3 partials ⚠️
.../kotlin/com/revenuecat/purchases/common/Backend.kt 40.00% 5 Missing and 1 partial ⚠️
...rchases/common/remoteconfig/RemoteConfigManager.kt 90.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@                                                  Coverage Diff                                                   @@
##           06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding    #3612      +/-   ##
======================================================================================================================
- Coverage                                                                               80.25%   80.25%   -0.01%     
======================================================================================================================
  Files                                                                                     379      381       +2     
  Lines                                                                                   15530    15599      +69     
  Branches                                                                                 2163     2172       +9     
======================================================================================================================
+ Hits                                                                                    12464    12519      +55     
- Misses                                                                                   2202     2209       +7     
- Partials                                                                                  864      871       +7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tonidero tonidero changed the base branch from 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding to graphite-base/3612 June 16, 2026 11:08
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from b8c0117 to d112e22 Compare June 16, 2026 11:09
@tonidero tonidero force-pushed the graphite-base/3612 branch from fb82861 to dd4061d Compare June 16, 2026 11:09
@tonidero tonidero changed the base branch from graphite-base/3612 to 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding June 16, 2026 11:09
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from d112e22 to b5b7b6e Compare June 16, 2026 11:23
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch from dd4061d to e4eb551 Compare June 16, 2026 11:23
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch from e4eb551 to f50eab9 Compare June 16, 2026 14:20
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch 2 times, most recently from 2f56a66 to b7eccb8 Compare June 16, 2026 14:40
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch from f50eab9 to 1468860 Compare June 16, 2026 14:40
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from b7eccb8 to 9e3d8b1 Compare June 17, 2026 13:05
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch 2 times, most recently from a8a7b1f to db36f20 Compare June 18, 2026 10:02
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch 2 times, most recently from b9c0e74 to e40a0c5 Compare June 18, 2026 10:27
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch 2 times, most recently from 6a666b9 to cea3fa5 Compare June 18, 2026 10:57
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from e40a0c5 to cbd6ee9 Compare June 18, 2026 10:57
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch from cea3fa5 to a7bc2cc Compare June 18, 2026 13:24
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from cbd6ee9 to 41560da Compare June 18, 2026 13:24
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch from a7bc2cc to aad99b8 Compare June 18, 2026 13:46
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from 41560da to 65f283e Compare June 18, 2026 13:46
@emerge-tools

emerge-tools Bot commented Jun 18, 2026

Copy link
Copy Markdown

📸 Snapshot Test

593 unchanged

Name Added Removed Modified Renamed Unchanged Errored Approval
TestPurchasesUIAndroidCompatibility
com.revenuecat.testpurchasesuiandroidcompatibility
0 0 0 0 335 0 N/A
TestPurchasesUIAndroidCompatibility Paparazzi
com.revenuecat.testpurchasesuiandroidcompatibility.paparazzi
0 0 0 0 258 0 N/A

🛸 Powered by Emerge Tools

@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from 65f283e to a475265 Compare June 18, 2026 15:57
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch from aad99b8 to 99fa878 Compare June 18, 2026 15:57
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from a475265 to 54dc5f5 Compare June 19, 2026 09:13
@tonidero tonidero force-pushed the 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding branch from 99fa878 to c8d4706 Compare June 19, 2026 09:13
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from 54dc5f5 to ef7cc7f Compare June 19, 2026 09:50

private fun persist(previous: PersistedRemoteConfig?, response: RemoteConfiguration) {
val previousTopics = previous?.topics ?: emptyMap()
// Changed bodies overwrite previous ones; topics dropped from the new manifest are pruned.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for now just in progress. This is not actually resolving the topics or anything, just assuming they are all already resolved.

Base automatically changed from 06-16-phase_1__v2_config_wire-format_models_remove_stale_remote-config_scaffolding to main June 19, 2026 10:50
tonidero and others added 2 commits June 19, 2026 12:55
Make the remote-config sync stateful:
- Backend.getRemoteConfig now accepts a ConfigManifest, replays it in full as
  the {"manifest": {...}} request body (serialized via kotlinx so the model's
  @SerialName fields are the single source of truth), and surfaces 204 No
  Content as a null RCContainer (no-change) distinct from a 200 binary response.
- Add a ConfigurationResponse.parse(ByteBuffer) overload.
- New RemoteConfigDiskCache persists the manifest + resolved topic bodies to
  noBackupFilesDir/RevenueCat/remote_config.json (atomic write, lenient read).
- New RemoteConfigManager replays the persisted manifest, and on 200 persists
  the server manifest plus merged/pruned topic bodies; on 204/error keeps cache.

Not wired into the SDK lifecycle yet (Phase 7). Blob extraction (Phase 3) and
topic-handler dispatch (Phase 4) are intentionally not done here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tonidero tonidero force-pushed the 06-16-phase_2__v2_config_manifest_persistence_request_body_204_handling branch from 0c7d740 to 4d924bb Compare June 19, 2026 10:56
@tonidero tonidero marked this pull request as ready for review June 19, 2026 10:57
@tonidero tonidero requested a review from a team as a code owner June 19, 2026 10:57
@tonidero tonidero requested a review from rickvdl June 19, 2026 10:57
@tonidero tonidero changed the title refactor(remote-config): manifest persistence, request body + 204 handling refactor(remote-config): manifest persistence, request body handling Jun 19, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 4d924bb. Configure here.

@tonidero tonidero marked this pull request as draft June 19, 2026 11:01
@tonidero

Copy link
Copy Markdown
Contributor Author

Moving back to draft since I'm still missing some things sorry for the noise!

@tonidero

Copy link
Copy Markdown
Contributor Author

This PR might need to change to make the manifest a client-abstracted format instead of what we do right now, but we can iterate on this after I would say.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant