Skip to content

feat: add refundHandling data processing purpose (MOB-582) - #302

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/mob-582-react-native-add-the-refundhandling-data-processing-purpose
Open

devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/mob-582-react-native-add-the-refundhandling-data-processing-purpose

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

Adds PLYDataProcessingPurpose.REFUND_HANDLING = 'refund-handling' (MOB-582), mirroring iOS Purchasely/Purchasely-iOS-Sources#804.

  • enums.ts: new member. revokeDataProcessingConsent forwards the string unchanged, no JS change needed.
  • PurchaselyRN.m mapPurposesFromStrings:: "refund-handling"PLYDataProcessingPurpose.refundHandling. Deliberately not folded into the all-non-essentials branch (the native bundle excludes it, same as identifiedAnalytics). Flag-only: no adapter, no local behavior.
  • Android bridge untouched (out of scope); its mapper already drops unknown tokens, so refund-handling is a no-op there.
  • sdk_public_doc.md: new "Data Processing Consent" section documenting the purposes table and the replace semantics (each call overwrites the revoked set; pass the full list; [] re-grants all).
  • Tests: Jest (value, member count 6→7, forwarding, per-call replacement boundary) and XCTest (mapPurposesFromStrings: exposed via a test-only category: both naming conventions, combination, all-non-essentials exclusion, every kebab token, unknown-token drop).

Release sequencing

PLYDataProcessingPurpose.refundHandling does not exist in Purchasely iOS 6.1.0, which the podspec still pins, so the build-ios / iOS Unit Tests (bridge) CI jobs will fail until the iOS release ships and the podspec is bumped. Per agreement, no podspec bump in this PR.

Validated locally against the iOS sources branch of #804 (7c10f9e): built the simulator xcframework via build_spm.sh, pointed the example Podfile at it, and ran react-native-purchasely-Unit-Tests on iOS 26.5 — 88 tests, 0 failures (46 in PurchaselyRNTests, incl. the 5 new ones). yarn lint / yarn typecheck / yarn test (286) green.

Link to Devin session: https://app.devin.ai/sessions/1746697af7274efba1a6b15c2b6c19d6
Open in Devin Desktop: https://app.devin.ai/desktop/session/1746697af7274efba1a6b15c2b6c19d6?variant=devin
Requested by: @kherembourg

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@greptile-apps

greptile-apps Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 2/5

The PR is not safe to merge while it breaks iOS compilation against the declared dependency and silently loses consent updates in documented usage.

Fix All in Claude CodeFindings

  1. P1 Pinned SDK Breaks Compilation
  2. P1 Combined Purpose Is Dropped
  3. P1 Empty Reset Does Nothing
Fix with agent prompt
### Issue 1
packages/purchasely/ios/PurchaselyRN.m:1264
The bridge directly references `PLYDataProcessingPurpose.refundHandling`, but the podspec still pins Purchasely iOS 6.1.0 and the documentation identifies this property as requiring iOS 6.2.0 or later. Normal CocoaPods consumer builds and the iOS CI jobs therefore compile this source against an SDK where the property is unavailable, preventing the iOS target from compiling until the dependency is bumped or the access is made backward-compatible.

Greptile automatically discovered a related ticket stating that tests cannot run until the supporting iOS SDK ships, which informed this comment.

### Issue 2
packages/purchasely/ios/PurchaselyRN.m:1263-1264
`refund-handling` cannot be combined with `all-non-essentials` as the new documentation requires. The mapper returns immediately when it encounters `all-non-essentials`, discarding a refund purpose already mapped and never examining later purposes. As a result, the documented `[ALL_NON_ESSENTIALS, REFUND_HANDLING]` call revokes only the bundle and silently omits refund handling.

Greptile automatically discovered a related ticket stating that refund handling must remain outside `allNonEssentials` and carry its own revoked-consent flag, which informed this comment.

### Issue 3
sdk_public_doc.md:824-825
The new “Grant all purposes back” example is not supported by either bridge. An empty array maps to an empty set, after which both iOS and Android return without invoking the native SDK. Applications following this example therefore leave previously revoked purposes unchanged instead of re-granting consent.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds the refund-handling consent purpose to the TypeScript API and iOS wire-value mapper, together with Jest/XCTest coverage and public consent documentation.

  • Maps the new token to the iOS refundHandling native purpose.
  • Intentionally leaves Android without native support.
  • Documents purpose availability and replacement semantics.
  • Adds tests for enum values, forwarding, normalization, combinations, and unknown tokens.
  • The implementation currently conflicts with the pinned iOS SDK and mishandles the documented combined and empty-set calls.

Greptile automatically discovered a related ticket that helped explain the purpose of this PR: expose the new refund-consent flag independently from allNonEssentials, with Android intentionally out of scope.

Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[JavaScript purpose array] --> B[iOS bridge normalization]
    B --> C{Contains all-non-essentials?}
    C -- Yes --> D[Return allNonEssentials singleton]
    C -- No --> E[Map individual purposes]
    E --> F[refund-handling to refundHandling]
    D --> G[Native consent API]
    F --> G
    H[Empty array] --> I[Empty mapped set]
    I --> J[Bridge skips native call]
Loading

Reviews (1) · Last reviewed commit: "feat: add refundHandling data processing..."

} else if ([p isEqualToString:@"third-party-integration"]) {
[result addObject:PLYDataProcessingPurpose.thirdPartyIntegrations];
} else if ([p isEqualToString:@"refund-handling"]) {
[result addObject:PLYDataProcessingPurpose.refundHandling];

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.

P1 Pinned SDK Breaks Compilation

The bridge directly references PLYDataProcessingPurpose.refundHandling, but the podspec still pins Purchasely iOS 6.1.0 and the documentation identifies this property as requiring iOS 6.2.0 or later. Normal CocoaPods consumer builds and the iOS CI jobs therefore compile this source against an SDK where the property is unavailable, preventing the iOS target from compiling until the dependency is bumped or the access is made backward-compatible.

Greptile automatically discovered a related ticket stating that tests cannot run until the supporting iOS SDK ships, which informed this comment.

Source Used: Linear — [React Native] Add the refundHandling data processing purpose

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/purchasely/ios/PurchaselyRN.m
Line: 1264

Comment:
**Pinned SDK Breaks Compilation**

The bridge directly references `PLYDataProcessingPurpose.refundHandling`, but the podspec still pins Purchasely iOS 6.1.0 and the documentation identifies this property as requiring iOS 6.2.0 or later. Normal CocoaPods consumer builds and the iOS CI jobs therefore compile this source against an SDK where the property is unavailable, preventing the iOS target from compiling until the dependency is bumped or the access is made backward-compatible.

Greptile automatically discovered a related ticket stating that tests cannot run until the supporting iOS SDK ships, which informed this comment.

**Source Used:** Linear — [\[React Native\] Add the refundHandling data processing purpose](https://linear.app/purchasely/issue/MOB-582/react-native-add-the-refundhandling-data-processing-purpose)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Comment on lines +1263 to +1264
} else if ([p isEqualToString:@"refund-handling"]) {
[result addObject:PLYDataProcessingPurpose.refundHandling];

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.

P1 Combined Purpose Is Dropped

refund-handling cannot be combined with all-non-essentials as the new documentation requires. The mapper returns immediately when it encounters all-non-essentials, discarding a refund purpose already mapped and never examining later purposes. As a result, the documented [ALL_NON_ESSENTIALS, REFUND_HANDLING] call revokes only the bundle and silently omits refund handling.

Greptile automatically discovered a related ticket stating that refund handling must remain outside allNonEssentials and carry its own revoked-consent flag, which informed this comment.

Source Used: Linear — [React Native] Add the refundHandling data processing purpose

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/purchasely/ios/PurchaselyRN.m
Line: 1263-1264

Comment:
**Combined Purpose Is Dropped**

`refund-handling` cannot be combined with `all-non-essentials` as the new documentation requires. The mapper returns immediately when it encounters `all-non-essentials`, discarding a refund purpose already mapped and never examining later purposes. As a result, the documented `[ALL_NON_ESSENTIALS, REFUND_HANDLING]` call revokes only the bundle and silently omits refund handling.

Greptile automatically discovered a related ticket stating that refund handling must remain outside `allNonEssentials` and carry its own revoked-consent flag, which informed this comment.

**Source Used:** Linear — [\[React Native\] Add the refundHandling data processing purpose](https://linear.app/purchasely/issue/MOB-582/react-native-add-the-refundhandling-data-processing-purpose)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Comment thread sdk_public_doc.md
Comment on lines +824 to +825
// Grant all purposes back
Purchasely.revokeDataProcessingConsent([]);

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.

P1 Empty Reset Does Nothing

The new “Grant all purposes back” example is not supported by either bridge. An empty array maps to an empty set, after which both iOS and Android return without invoking the native SDK. Applications following this example therefore leave previously revoked purposes unchanged instead of re-granting consent.

Prompt To Fix With AI
This is a comment left during a code review.
Path: sdk_public_doc.md
Line: 824-825

Comment:
**Empty Reset Does Nothing**

The new “Grant all purposes back” example is not supported by either bridge. An empty array maps to an empty set, after which both iOS and Android return without invoking the native SDK. Applications following this example therefore leave previously revoked purposes unchanged instead of re-granting consent.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

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