Skip to content

#107 — Webhook Cursor Is a UUID String Comparison: Pagination Can Skip or Repeat Rows #888

Description

@Topmatrixmor2014

Labels: Official Campaign | FWC26 GrantFox OSS Maybe Rewarded backend webhooks api bug

This is a backend issue for the GrantFox FWC26 campaign. Replace the string cursor with a stable, sortable keyset so webhook-event pagination is exact.

Requirements and Context

backend/src/services/webhookService.jsgetEvents:

if (cursor) query.andWhere("e.id", "<", cursor);
query.limit(limit);
  • e.id is a UUIDv4; lexicographic < comparison on UUIDs is not chronological — rows with created_at ordering can be skipped or repeated across pages.
  • The route GET /api/webhooks/:publicKey/events (in backend/src/routes/webhooks.js) additionally re-paginates in memory with (b.timestamp || 0) - (a.timestamp || 0) on top of the DB query, so two different orderings fight each other.
  • Batch-3 bug(backend): federation lookup does not validate returned Stellar address format #80 covered getEvents cursor pagination for the events route; this issue is the service-layer getEvents/replayEvents cursor semantics — the DB-level cursor that feeds the route.

Objectives

  1. Change the DB cursor to a monotonic column (created_at + id tiebreaker) or add a numeric seq column; make andWhere a keyset comparison.
  2. Remove the redundant in-memory re-sort in the route so a single ordering is authoritative.
  3. Add tests: two pages of events with equal timestamps produce no overlap and no gap.

Suggested Execution

  1. Fork and branch: git checkout -b fix/webhook-events-keyset.
  2. Patch getEvents in webhookService.js and the route in routes/webhooks.js.
  3. Add keyset pagination tests; run npm run lint && npm test in backend/.

Acceptance Criteria

  • Paginating webhook events returns each row exactly once across pages.
  • Equal-timestamp rows are ordered deterministically.
  • ≥3 tests; npm run lint clean.

Guidelines

  • If a schema migration is needed, use the project's knex migration convention and keep the change backward-compatible.

Timeframe: 24 hours

Activity

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

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Third CampaignCampaign: Third CampaignapiapibackendExpress backend issuesbugSomething isn't workingwebhookswebhooks

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions