fix: widget key timing, notification error handling, SignalR status, concurrent push#210
Merged
Merged
Conversation
…concurrent push Four MEDIUM-priority items from the full-project review: - WidgetEndpoints compared the X-Widget-Key header with plain string.Equals instead of the constant-time comparison AuthEndpoints already uses for the same class of secret; promoted FixedTimeEquals to internal and reused it. - useNotifications' archive/delete actions had no error handling at all, so a failed request became an unhandled promise rejection with no feedback. They now catch, log, and set an actionError ref that NotificationPanel surfaces as an inline banner. - SignalR's connected state was tracked but never surfaced to the UI; a dropped connection left telemetry silently stale with no indicator anywhere. App.vue now shows a "Live updates paused" indicator in the sidebar once a connection has been attempted and is not currently up. - PushSenderService delivered push notifications to subscribers one at a time; a single slow/unreachable endpoint could delay delivery to everyone else. Now delivers with bounded concurrency (10 at a time) via Task.WhenAll + SemaphoreSlim instead of a sequential foreach. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
464b358 to
2c55092
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four of the six MEDIUM-priority items from an earlier full-project review (the other two, test coverage for
PoiPreCachingService/PushSenderService/MqttConsumerService's merge flow, are being handled as a separate follow-up since they're a different kind of work).WidgetEndpoints.cscompared theX-Widget-Keyheader with plainstring.Equalsinstead of the constant-time comparisonAuthEndpointsalready has for the same purpose. PromotedFixedTimeEqualstointernaland reused it.useNotifications.ts's archive/delete/archiveAll/deleteAll had no error handling; a failed request became an unhandled promise rejection with zero user feedback. They now catch, log to console, and set anactionErrorref thatNotificationPanel.vuesurfaces as an inline error banner.App.vuedestructuredstart/stopfromuseSignalR()but discarded theconnectedref. A dropped connection left telemetry silently stale with no visible indicator. Now shows a "Live updates paused" indicator in the sidebar once a connection has been attempted and isn't currently up (newcommon.liveUpdatesPausedi18n key, en + nl).PushSenderService.SendToAllAsyncdelivered to subscribers one at a time; a single slow/unreachable push endpoint could delay delivery to everyone else. Now delivers with bounded concurrency (10 at a time) viaTask.WhenAll+SemaphoreSlim, collecting dead subscriptions in aConcurrentBaginstead of a plainList.Test plan
dotnet buildsucceeds,dotnet testpasses (251/251)pnpm run type-check,pnpm run lint,pnpm exec prettier --check src/all passpnpm run test:unit --runpasses (144/144 - 4 new tests added for the notification action error paths)🤖 Generated with Claude Code