Skip to content

Add Workflows list endpoint#3509

Merged
vegaro merged 7 commits into
mainfrom
cesar/workflows-response-support-1
May 27, 2026
Merged

Add Workflows list endpoint#3509
vegaro merged 7 commits into
mainfrom
cesar/workflows-response-support-1

Conversation

@vegaro

@vegaro vegaro commented May 27, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds WorkflowSummary and WorkflowsListResponse models (id, display_name, offering_id, prefetch) with kotlinx.serialization and ignoreUnknownKeys for forward compatibility
  • Adds WorkflowJsonParser.parseWorkflowsListResponse()
  • Adds Endpoint.GetWorkflows and Backend.getWorkflows() with background-aware callback deduplication (same pattern as the existing getWorkflow() implementation)

Part 1 of 2 — Part 2: #3508


Note

Low Risk
Additive networking and parsing alongside existing workflow detail APIs, with broad test coverage and no changes to purchase or auth flows.

Overview
Adds client support for listing subscriber workflows via GET /v1/subscribers/{userId}/workflows, including an optional type query filter.

New kotlinx-serialization models WorkflowSummary and WorkflowsListResponse (with parseWorkflowsListResponse) describe list entries (id, display_name, offering_id, prefetch). Endpoint.GetWorkflows is wired for signature verification like the single-workflow endpoint, and Backend.getWorkflows performs the request with the same background-aware callback deduplication pattern as getWorkflow. Tests cover path encoding, deserialization edge cases, HTTP errors, and concurrent call coalescing.

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

vegaro and others added 4 commits May 26, 2026 17:51
Adds new model classes to handle the GET /v1/subscribers/{userId}/workflows
endpoint response. The WorkflowSummary model includes:
- id: unique workflow identifier
- display_name: user-facing workflow name
- offering_id: optional nullable offering identifier
- prefetch: boolean flag for prefetch support (defaults to false)

The WorkflowsListResponse wraps a list of WorkflowSummary objects.
Both models use kotlinx.serialization with proper deserialization
handling for missing/null fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vegaro vegaro added the pr:feat A new feature label May 27, 2026
@vegaro vegaro changed the title feat: add WorkflowSummary, WorkflowsListResponse models, and Backend.getWorkflows() endpoint Add Workflows list endpoint May 27, 2026
@vegaro vegaro marked this pull request as ready for review May 27, 2026 01:20
@vegaro vegaro requested a review from a team as a code owner May 27, 2026 01:20

@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 1 potential issue.

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 a089a9e. Configure here.

@facumenzella facumenzella left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks solid

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.92593% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.87%. Comparing base (aa1c14c) to head (b27d7cd).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
.../kotlin/com/revenuecat/purchases/common/Backend.kt 73.17% 9 Missing and 2 partials ⚠️
...uecat/purchases/common/workflows/WorkflowModels.kt 60.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3509      +/-   ##
==========================================
- Coverage   79.89%   79.87%   -0.02%     
==========================================
  Files         369      369              
  Lines       14875    14929      +54     
  Branches     2048     2057       +9     
==========================================
+ Hits        11884    11925      +41     
- Misses       2158     2167       +9     
- Partials      833      837       +4     

☔ View full report in Codecov by Sentry.
📢 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.

vegaro and others added 2 commits May 27, 2026 10:31
Adds an optional `type` parameter to `Endpoint.GetWorkflows` and
`Backend.getWorkflows()` so callers can filter by workflow type
(e.g. `?type=paywall`).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vegaro vegaro added this pull request to the merge queue May 27, 2026
Merged via the queue into main with commit 61618ee May 27, 2026
36 checks passed
@vegaro vegaro deleted the cesar/workflows-response-support-1 branch May 27, 2026 21:38
facumenzella added a commit to RevenueCat/purchases-ios that referenced this pull request May 28, 2026
* feat(networking): add getWorkflows list endpoint

Port of RevenueCat/purchases-android#3509

Adds WorkflowSummary and WorkflowsListResponse models, GetWorkflowsListOperation,
and WorkflowsAPI.getWorkflows() to support listing a subscriber's workflows via
GET /v1/subscribers/{userId}/workflows. Includes request deduplication and
background-aware delay, matching the existing getWorkflow(by id) pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add WorkflowsListCallback and GetWorkflowsListOperation to Xcode project

Register the two new source files in the root RevenueCat.xcodeproj so
xcodebuild (used by CI) can find them. SPM discovers them automatically
but the tracked root project needs explicit file references and build
file entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix snapshots: remove ?type=paywall query param from getWorkflows endpoint

The getWorkflows endpoint does not send a type filter query parameter.
The snapshots were created from an earlier design and needed to be
updated to match the actual request URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix WorkflowSummary decoding with JSONDecoder.default convertFromSnakeCase

JSONDecoder.default uses .convertFromSnakeCase, which converts JSON keys to
camelCase before matching against CodingKey raw values. The explicit CodingKeys
had snake_case raw values (e.g. "display_name"), causing a mismatch since the
decoder would convert display_name to displayName before the lookup.

Removing the explicit CodingKeys lets Swift synthesize them with camelCase raw
values, which correctly match the converted keys.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(networking): add type filter parameter and deserialization robustness tests

- Add optional `type: String?` parameter to `getWorkflows` path, operation,
  API method, and mock, matching Android PR #3509 which supports
  `?type=<value>` query filtering on the list endpoint
- Include `type` in the operation deduplication cache key so calls with
  different types are not coalesced
- Add `testGetWorkflowsWithTypePassesQueryParameter` with snapshots for all
  OS variants
- Add `WorkflowSummaryDecodingTests` covering explicit-null `offering_id`,
  absent `prefetch` default, and unknown-field tolerance for both
  `WorkflowSummary` and `WorkflowsListResponse`
- Remove unnecessary `import Foundation` from `WorkflowsListCallback.swift`

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Address review: enable signature verification for getWorkflows, fix cache key separator and indentation

- Move .getWorkflows to supportsSignatureVerification=true, matching .getWorkflow and Android PR (#3509)
- Add "\n" separator between appUserID and type in individualizedCacheKeyPart to prevent collision
- Fix indentation of factory closure closing brace and label to match GetWorkflowOperation pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
matteinn pushed a commit to matteinn/purchases-android that referenced this pull request Jun 5, 2026
**This is an automatic release.**

## RevenueCat SDK
### ✨ New Features
* Add presented offering context to custom paywall events (RevenueCat#3424) via
Rick (@rickvdl)
* Add Workflows list endpoint (RevenueCat#3509) via Cesar de la Vega (@vegaro)

## RevenueCatUI SDK
### Paywalls_v2
#### 🐞 Bugfixes
* Fix 1px seam between sliding multipage paywall pages (RevenueCat#3526) via Cesar
de la Vega (@vegaro)

### 🔄 Other Changes
* refactor: extract Offering.presentedOfferingContext() helper and apply
across SDK (RevenueCat#3513) via Rick (@rickvdl)
* Add JSON Logic string + array operators (RevenueCat#3485) via Antonio Pallares
(@ajpallares)
* Add ForbiddenPublicSealedClass detekt rule (RevenueCat#3503) via Toni Rico
(@tonidero)
* Update baseline profiles (RevenueCat#3519) via RevenueCat Git Bot (@RCGitBot)
* build(deps): bump fastlane-plugin-revenuecat_internal from `af7bb5c`
to `ce6a7ef` (RevenueCat#3515) via dependabot[bot] (@dependabot[bot])
* Add JSON Logic comparison operators (<, <=, >, >=) (RevenueCat#3484) via Antonio
Pallares (@ajpallares)
* Add JSON Logic arithmetic operators (+, -, *, /, %) (RevenueCat#3483) via
Antonio Pallares (@ajpallares)
* Add WorkflowEvent model and backend serialization (RevenueCat#3486) via Cesar de
la Vega (@vegaro)
* RulesEngine: add JSON Logic predicate evaluator (RevenueCat#3482) via Antonio
Pallares (@ajpallares)
* Add :rules-engine-internal skeleton module (RevenueCat#3478) via Antonio
Pallares (@ajpallares)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Version bump and changelog/docs/CI path updates only; no application
logic changes in the diff.
> 
> **Overview**
> This **automatic release** finalizes **Android SDK 10.8.0** by
replacing **`10.8.0-SNAPSHOT`** with **`10.8.0`** across versioning
(`gradle.properties`, `.version`, `Config.frameworkVersion`), sample
apps, and changelog files.
> 
> Release notes for **10.8.0** are recorded in **`CHANGELOG.md`** /
**`CHANGELOG.latest.md`** (workflows list API, paywall offering context
on custom events, multipage paywall seam fix, rules-engine/JSON Logic
work, etc.). **Docs publishing** now targets **`10.8.0`** on S3, and
**`docs/index.html`** redirects to the new doc URL.
> 
> There are **no functional code changes** in this diff beyond version
strings and release metadata.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c3048b8. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:feat A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants