Skip to content

Unify notification ids#278

Merged
akirk merged 4 commits intomainfrom
fix-notification-ids
Mar 4, 2026
Merged

Unify notification ids#278
akirk merged 4 commits intomainfrom
fix-notification-ids

Conversation

@akirk
Copy link
Copy Markdown
Owner

@akirk akirk commented Dec 2, 2025

Summary

Mastodon clients rely on notification IDs being sortable and comparable strings for pagination. When multiple notification sources exist (e.g. the built-in handler and the ActivityPub plugin), each produces its own ID format, which means clients can't paginate correctly — they miss notifications, show them out of order, or get stuck in pagination loops.

This PR unifies notification IDs to a date-based format across all sources and centralizes sorting and pagination so it works over the merged set.

Changes

  • Normalize notification IDs to a date-based format across all sources (arrays and entities)
  • Move pagination out of fetch_notifications into finalize_notifications (priority 100 filter), so it applies after all sources have contributed
  • Support max_id, since_id, min_id, and limit per the Mastodon API spec (default limit 40, max 80)
  • Use WP_REST_Response::add_link() for pagination Link headers, matching the timeline endpoint pattern
  • Make the status field nullable on the Notification entity (follow notifications have no status)
  • Fix notification ID comparison: PHP's >= coerces 28+ digit numeric strings to float (only ~15 digits precision), breaking pagination for same-day notifications. Add id_cmp() helper that left-pads to equal length for correct strcmp
  • Fix if-modified-since header to compare as numeric ID instead of date string
  • Add notification pagination tests

Test plan

  • CI passes (new pagination tests + existing tests)
  • Verify notifications appear sorted newest-first in a Mastodon client
  • Verify scrolling/pagination loads older notifications correctly
  • If ActivityPub plugin is active, verify notifications from both sources are interleaved by date

@akirk akirk force-pushed the fix-notification-ids branch from 845d408 to 0319c5a Compare February 28, 2026 05:44
Move pagination from fetch_notifications into finalize_notifications
(priority 100) so it applies to the merged set from all notification
providers, not just the internal handler. This adds proper sorting
by ID descending before paginating with min_id/max_id/since_id/limit
and setting Link headers per the Mastodon API spec.

- Rename normalize_notification_ids to finalize_notifications
- Add get_notification_value helper for array/entity access
- Align default limit to 40, max 80 per Mastodon API spec
Switch from raw header() calls to WP_REST_Response::add_link() for
notification pagination, matching the pattern used by the timeline
endpoint. This makes Link headers testable via $response->get_links()
in PHPUnit.

Add notification pagination tests covering sorting, limit, max_id,
min_id, since_id, combined parameters, Link headers, and forward
pagination walk-through.
The Mastodon API spec says since_id returns results "greater than this
ID". The comparison used > which didn't break on equality, letting the
item with id == since_id slip through. Changed to >= to match min_id
behavior and the spec.
@akirk akirk merged commit b395ac9 into main Mar 4, 2026
17 checks passed
@akirk akirk deleted the fix-notification-ids branch March 4, 2026 11:29
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