Issue list: descending priority sort duplicates the boundary issue across pages

Summary

When the issue list is sorted by Priority in descending order (sort=-priority) and the result spans more than one page, the last issue on a page reappears as the first issue on the next page — a single issue is shown twice across the page break.

Ascending priority does not reproduce it in the cases tested, and integer/timestamp sorts (-count, -last_seen, -first_seen) are unaffected.

Reproduction

Create 3 issues in one project with distinct, monotonic count / last_seen so the priority values are distinct, then page with limit=2:

GET /api/0/organizations/<org>/issues/?limit=2&sort=-priority
  -> page 1 = [issue3, issue2]
follow the rel="next" cursor
  -> page 2 = [issue2, issue1]   # issue2 is duplicated

Expected page 2 = [issue1].

Cause

priority is a computed float annotation:

priority = LOG(10, index.count) + EXTRACT(epoch FROM index.last_seen) / 300000

The cursor paginator (AsyncLinkHeaderPagination / ninja_cursor_pagination) stores the ordering value as the cursor position via str(value) and filters the next page with priority__lt='<stringified float>'. For a descending float sort that < boundary does not reliably exclude the row the position came from, so the boundary issue is returned again. Integer/timestamp positions are exact, which is why only the float-valued priority sort is affected.

Relevant code: glitchtip/api/pagination.py (_get_position_from_instance, the cursor.position filter in apaginate_queryset).

Notes

  • This is distinct from the count crash fixed in !2471 (merged) (that was a 42803 in the X-Hits count query for the same sort). The count fix removed the 500 that was previously masking this duplication, so it is now observable.
  • The regression test added in !2471 (merged) (test_priority_sort_paginated_count) intentionally asserts only status + X-Hits for priority sorts and does not assert strict cross-page dedup, precisely because of this open bug. A fix here should also tighten that test to assert each issue appears exactly once across pages for priority / -priority.

Possible directions

  • Quantize/round the float position deterministically so the stored position and the DB-side comparison agree on the boundary, or
  • Paginate priority with a stable secondary tiebreaker (e.g. issue id) so the boundary comparison is exact.