Skip to content

fix(notifications): handle a missing X-Total-Count and serialise unread fetches - #4

Merged
tagpro merged 1 commit into
masterfrom
fix/notifications-load-race
Jul 13, 2026
Merged

fix(notifications): handle a missing X-Total-Count and serialise unread fetches#4
tagpro merged 1 commit into
masterfrom
fix/notifications-load-race

Conversation

@tagpro

@tagpro tagpro commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Follow-up to #2, which is already on master. This carries only the review fixes from upstream maxdorninger/MediaManager#564 — one file, no re-application of the pagination work.

Missing X-Total-Count collapsed the totals to zero

Number(null) is 0, not NaN, so the Number.isNaN fallback in totalCountOf never ran. If the header were absent, unreadTotal/readTotal would be set to 0 while notifications were still rendered — hiding the unread count and the "Mark All as Read" button. It now falls back on a null or empty header and only accepts a finite number, so a genuine "0" still reads as zero.

The 30s poll could race with "Load More"

Both write unreadNotifications, and they could overlap: a poll issued before a "Load More" but resolving after it would overwrite the list with page one, discarding the page the user just asked for (or repeating an id in the keyed {#each}). Unread fetches now go through a promise queue, so each request reads its offset only once the previous one has settled — this covers the reverse direction too (a "Load More" clicked while a poll is in flight). The interval additionally skips while loadingMoreUnread is set, since a queued reset would otherwise truncate the list back to the first page right after a "Load More" resolved.

Verification

  • Simulated the overlap: with the old concurrent code the list ended up jumping straight from row 49 to row 100 — an entire page silently dropped from the middle. With the fetches queued it stays contiguous.
  • Checked the header coercion across null, "", "0", "12", "abc": null/"" now fall back instead of yielding 0, and "0" still yields 0.
  • npm run lint (in web/) — clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SC2BDd7wA7hPa7k2h2yAv1

…ad fetches

Number(null) is 0, so an absent X-Total-Count header collapsed unreadTotal
and readTotal to zero rather than falling back to the loaded count, hiding
the unread count and the "Mark All as Read" button while rows were on screen.

The 30s poll and a "Load More" click both wrote unreadNotifications and could
overlap, letting whichever response landed last win: a poll issued before a
"Load More" but resolving after it truncates the list back to the first page,
dropping the page the user just asked for. Queue the unread fetches so each
reads its offset only once the previous one has settled, and skip the poll
while a "Load More" is pending so it cannot discard a loaded page.

Addresses review feedback on maxdorninger#564.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SC2BDd7wA7hPa7k2h2yAv1
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@tagpro, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 43 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 946be435-ebe7-4ec0-af2d-1e1d2e0c7716

📥 Commits

Reviewing files that changed from the base of the PR and between e070dc6 and d1b12ff.

📒 Files selected for processing (1)
  • web/src/routes/dashboard/notifications/+page.svelte
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/notifications-load-race

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@tagpro
tagpro merged commit 40cbbe7 into master Jul 13, 2026
1 check passed
@tagpro
tagpro deleted the fix/notifications-load-race branch July 13, 2026 05:27
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