feat(surveys): collect partial responses and resume unfinished surveys - #768
Open
lucasheriques wants to merge 6 commits into
Open
feat(surveys): collect partial responses and resume unfinished surveys#768lucasheriques wants to merge 6 commits into
lucasheriques wants to merge 6 commits into
Conversation
Decode enable_partial_responses and emit cumulative answers after each submitted question when enabled. Keep a submission UUID across sent/dismissed events and set $survey_completed using branching. Preserve completion-only behavior by default and legacy response keys. Verified regression tests fail before and pass after implementation. Passed CI=true make compile, SDK/Compose module builds, API and formatting checks. Core: 943 tests; Android debug/release: 359 each (3 skipped); Compose: 9. CodeScene passed with stable legacy integration-file health.
Contributor
Prompt To Fix All With AI### Issue 1
posthog/src/main/java/com/posthog/surveys/Survey.kt:32-33
**Public JVM ABI breaks**
Adding `enablePartialResponses` to this public data class replaces the previous JVM constructor and `copy` method descriptors, as shown in the API snapshot. Because `posthog` is declared as a minor update, an application compiled against either old signature can upgrade without recompiling and then fail at runtime with `NoSuchMethodError`. Please preserve the old ABI or publish this as a breaking release.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "feat(surveys): collect partial responses..." | Re-trigger Greptile |
Contributor
posthog-android Compliance ReportDate: 2026-09-09 18:40:06 UTC ✅ All Tests Passed!46/46 tests passed Capture Tests✅ 29/29 tests passed View Details
Feature_Flags Tests✅ 17/17 tests passed View Details
|
Preserve the previous JVM constructor, copy, and Kotlin default-argument signatures when adding enablePartialResponses. Forward copies with the new setting intact. Keep overloads visible for Java source compatibility too. Verification: reflection regression tests exercise all four old descriptors; Kotlin copy calls preserve/override the new field. Format/API snapshot and focused core/event-payload tests pass. CodeScene exception: the 17-argument copy compatibility overload triggers the argument-count gate. Its exact signature is required for binary compatibility; shortening it would restore the runtime failure.
Save progress after nonterminal answers and restore the submission ID, answers, answer-time text/language and branching destination. Clear state on completion, dismissal, reset and incompatible survey updates. Keep unfinished attempts eligible and honor initialQuestionIndex in Compose. Preserve legacy display-model constructor/copy descriptors and API 23 hash compatibility. Fix jumps to the final question completing too early. Verified: CI=true make compile, full Android debug tests after final callback simplification, make format, make checkFormat, make api, legacy ABI regression tests and API descriptor comparison. CodeScene exceptions: legacy integration size/aggregate complexity remains degraded despite lower showSurvey complexity; broader extraction is deferred. Compatibility copy argument counts preserve existing ABI.
Invalidate delayed callbacks on reset, serialize preference mutations, and reject stale snapshots after reentrant preference reads. Defer reconciliation while credential-protected storage is unavailable. Prepare event snapshots before dispatch and keep client callbacks outside state locks; stale shown callbacks cannot close a newer renderer. Keep Compose survey state across host Activity destruction and restore on the next foreground Activity. Explicit close still dismisses exactly once. Add mounted lifecycle coverage and an explicit CI debug-host test target. Validation: deterministic reset/store/callback regressions, mounted lifecycle tests, full CI=true make compile, format/API checks, and CodeScene pre-commit review.
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
2 tasks
Notify the actual Compose renderer after SDK reset, including the renderer discovered automatically. Bind UI state to an installed session, configuration and reset generation so stale callbacks, pending shows, retained Activity input and late cleanup cannot reach a new presentation. Keep custom delegate callbacks outside SDK monitors. Preserve the existing delegate interface and add an internal optional session/presentation capability. Atomically bind the owner and reset generation to avoid missing a concurrent reset, and preserve delegate reuse with a new configuration. Verification: full CI=true make compile; focused ABI/Java/reset, Android survey and mounted Compose tests; final bind/reset regression; format, API snapshot, checkFormat and CodeScene safeguard. Existing size penalties remain unchanged. Mounted UI uses Robolectric. The broad build precedes the final focused bind/reset adjustment.
Only deliver cached survey configuration during setup when it is available. An unknown cache must not erase unfinished answers through reconciliation; successful empty configuration remains authoritative. Exercise fresh SDK setup with production preferences, cumulative saved and new answers, submission IDs, and completion/dismissal language attribution. Strengthen mounted draft restoration, zero stale-response forwarding, session retirement and cleanup ownership, and legacy argument forwarding. Consolidate overlapping cases and move the restart journey into a focused test class. Replace private-monitor assertions with bounded behavior. Validation: 41 focused tests passed. CI=true make compile testSurveyUI passed: core 948, Android release 374 (3 skipped), Compose release 9, server 540, Compose debug 15; zero failures. Format, API, checkFormat, and CodeScene passed; no API snapshot changes. Removing session invalidation and the actual inline submit guard each failed the intended assertion; both mutations were restored before final validation. Fresh SDK recreation runs within Robolectric and captures via beforeSend; physical-device process death and network ingestion are outside this test scope. Native null-answer omission remains unchanged.
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
Add partial responses and persistent resume to Android surveys, moving toward survey feature parity across all PostHog SDKs, with posthog-js as the reference. Closes #390. Auto-submit is separate in #769.
After submitting an answer, users can restart and resume at the next branching destination with saved answers and the same
$survey_submission_id. Withenable_partial_responses=true, each answer emits a cumulativesurvey sentevent; false/absent emits only on completion. Resume works in both modes.Key behavior:
initialQuestionIndex. Existing constructor/copy signatures remain compatible; custom delegates can opt into the separate reset capability.Review path
💚 How did you test it?
Passed:
CI=true make compile testSurveyUI(zero failures; 3 skipped tests), formatting, API checks and CodeScene. Coverage includes fresh SDK resume, mounted draft restoration, reset races and Kotlin/Java compatibility. Removing session invalidation or the submit guard made the corresponding regressions fail.Restart tests use real SDK/preferences instances within Robolectric and capture through
beforeSend; they do not exercise physical-device process death or network ingestion.📝 Checklist
🤖 Agent context
Autonomy: Human-driven (agent-assisted). Codex implemented the changes with independent QA agents; human review is required.