Skip to content

Follow Stripe's listing cursor when fetching webhook endpoints - #2024

Merged
stefan-burke merged 5 commits into
mainfrom
claude/todo-task-8g1gt8
Aug 3, 2026
Merged

Follow Stripe's listing cursor when fetching webhook endpoints#2024
stefan-burke merged 5 commits into
mainfrom
claude/todo-task-8g1gt8

Conversation

@stefan-burke

@stefan-burke stefan-burke commented Aug 3, 2026

Copy link
Copy Markdown
Member

Closes the "Same-URL stray listing doesn't paginate" follow-up recorded in TODO.md (from the PR #1827 review).

What changed

When the site cleans up old Stripe webhook endpoints, or checks the connection health page, it asked Stripe for the list of endpoints once and only saw the first 100. An account with more endpoints than that would keep strays beyond the first page forever.

  • The endpoint list now follows Stripe's paging marker: while Stripe says there are more pages, the next page is fetched starting after the last endpoint seen.
  • The response check now requires Stripe's has_more marker, so a response without it fails loudly instead of being silently treated as the whole list.
  • If Stripe says more pages exist but sends an empty page, the fetch stops with a clear error instead of looping or guessing.

Tests

  • A cleanup run over two pages proves a stray on the second page is found and deleted, and that the second request asks for exactly the right page (a wrong page marker fails the test).
  • The empty-page-with-more-promised case is proven to fail loudly.
  • The request-parity test proves our client sends the same paging request as Stripe's own library.
  • The webhook setup tests moved from test/integration/stripe/ to test/shared/stripe/endpoints/, the mirror path for the module they test. The mutation gate only always runs mirror-located tests, so this move is what lets it prove the endpoint-limit recovery logic is guarded — the gate now kills all 99 mutants in the changed files (100%).
  • New assertions close the gaps that run found: cleanup creates its Stripe client with zero network retries, the connection page reports a listing error word for word, and the endpoint schema accepts both endpoint statuses.
  • The at(-1) "last item" idiom joined the built-ins ignored by the constant-argument code-quality rule, since a third call site pushed it over that rule's threshold.

claude added 3 commits August 3, 2026 15:09
fetchWebhookEndpoints read only the first page of webhook endpoints, so
same-URL strays beyond 100 endpoints were never seen by cleanup. The
list schema now requires Stripe's has_more marker, the client accepts a
starting_after cursor, and the fetch walks every page — failing loudly
if Stripe reports more pages but sends an empty one.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKyfP7ai7DR9ChC2CjcHjA
A third .at(-1) call site pushed the built-in over the rule's
threshold. Like padStart and toFixed, at() is a platform method whose
constant argument is the idiom itself, and no application function
shares the name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKyfP7ai7DR9ChC2CjcHjA
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 11c78b7d-1981-4426-a276-4939ac26099d

📥 Commits

Reviewing files that changed from the base of the PR and between 09e47fd and f352676.

📒 Files selected for processing (15)
  • TODO.md
  • src/shared/stripe/client.ts
  • src/shared/stripe/endpoints.ts
  • src/shared/stripe/schemas.ts
  • test/integration/stripe-client-parity.test.ts
  • test/integration/stripe/connection.test.ts
  • test/scripts/code-quality/detectors.ts
  • test/scripts/code-quality/redundant-arg.test.ts
  • test/shared/stripe/client.test.ts
  • test/shared/stripe/endpoints/cleanup.test.ts
  • test/shared/stripe/endpoints/connection.test.ts
  • test/shared/stripe/endpoints/setup.test.ts
  • test/shared/stripe/schemas.test.ts
  • test/test-utils/stripe/fixtures.ts
  • test/test-utils/stripe/responses.ts

Comment @coderabbitai help to get the list of available commands.

claude added 2 commits August 3, 2026 16:08
The mutation gate only runs a source's mirror-located direct tests plus
integration tests changed on the branch, so the endpoint-limit recovery
tests in test/integration/stripe/webhook-setup.test.ts never guarded
src/shared/stripe/endpoints.ts during mutation runs. They are fetch-mock
unit tests of that module, so they now live at its mirror path.

Also close the three remaining assertion gaps:
- cleanup asserts the Stripe client is created with zero network retries
- connection health asserts the listing error is reported word for word
- the webhook endpoint schema test accepts both endpoint statuses

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKyfP7ai7DR9ChC2CjcHjA
Assert over the mapped calls list instead of calls[0], which is
possibly undefined under the checker and also pins the call count.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKyfP7ai7DR9ChC2CjcHjA
@stefan-burke

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@stefan-burke
stefan-burke added this pull request to the merge queue Aug 3, 2026
@stefan-burke
stefan-burke removed this pull request from the merge queue due to a manual request Aug 3, 2026
@stefan-burke
stefan-burke added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit a2040ce Aug 3, 2026
3 checks passed
@stefan-burke
stefan-burke deleted the claude/todo-task-8g1gt8 branch August 3, 2026 16:48
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.

2 participants