feat(messaging,runtime): implement /api/v1/notifications REST surface (ADR-0030)#1486
Merged
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
… (ADR-0030)
The notification REST routes (GET /notifications, POST /notifications/read,
/read/all) were declared in the spec but never had a server-side handler — no
plugin registered the `notification` core service, so the routes were never
advertised and client.notifications.* 404'd. (The Console bell works only
because it bypasses these endpoints via the generic data API.)
- MessagingService: add listInbox/markRead/markAllRead reading
sys_inbox_message + sys_notification_receipt; mark-read upserts the receipt
keyed (notification_id, user_id, channel:'inbox'), updating the existing
delivered receipt in place and inserting only when absent.
- MessagingServicePlugin: also register the service under the `notification`
core slot so the dispatcher resolves + advertises the routes.
- HttpDispatcher: add handleNotification + /notifications dispatch branch;
takes the user from the execution context; responses match the spec schemas
({ notifications, unreadCount }, { success, readCount }).
- Tests: 6 new MessagingService inbox-API tests; client notification response
shapes reconciled to the spec schemas.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
b6869d4 to
232e098
Compare
| } | ||
|
|
||
| const m = method.toUpperCase(); | ||
| const subPath = path.replace(/^\/+/, '').replace(/\/+$/, ''); |
xuyushun441-sys
pushed a commit
that referenced
this pull request
Jun 1, 2026
Integration coverage for the /api/v1/notifications surface added in #1486: GET → listInbox (with read/limit filters), POST /read → markRead, POST /read/all → markAllRead, 401 for anonymous requests, and unhandled (→404) when no notification service is registered. Mirrors the existing handleAnalytics dispatcher tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
xuyushun441-sys
added a commit
that referenced
this pull request
Jun 1, 2026
Integration coverage for the /api/v1/notifications surface added in #1486: GET → listInbox (with read/limit filters), POST /read → markRead, POST /read/all → markAllRead, 401 for anonymous requests, and unhandled (→404) when no notification service is registered. Mirrors the existing handleAnalytics dispatcher tests. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.
What & why
ADR-0030 (Notification Convergence) follow-up. While repointing the objectui SDK consumer (objectui#1440) I found the framework side was not a repoint but a gap: the notification REST routes (
GET /notifications,POST /notifications/read,/read/all) are declared in the spec but were never implemented —notificationcore service, sohasNotificationwas always false and the routes were never advertised in discovery;handleNotificationin the dispatcher;client.notifications.list/markRead/markAllReadtherefore 404'd.(The Console bell works today only because objectui bypasses these endpoints and reads the inbox via the generic data API.)
This wires the surface end-to-end against the ADR-0030 L5 model.
Changes
MessagingService— inbox read API:listInbox(userId, { read?, type?, limit? })readssys_inbox_messagejoined withsys_notification_receiptfor read-state (unread until aread/clicked/dismissedreceipt exists);readfilter applied after the join; returns{ notifications, unreadCount }.markRead(userId, ids)/markAllRead(userId)upsert the receipt toread, keyed(notification_id, user_id, channel:'inbox')— updating the existingdeliveredreceipt in place, inserting only when absent. Returns{ success, readCount }.MessagingServicePlugin— also registers the messaging service under thenotificationcore slot so the dispatcher resolves + advertises the routes. The legacyINotificationService.send()abstraction is unused/unconsumed.HttpDispatcher—handleNotification+/notificationsdispatch branch; takes the authenticated user fromexecutionContext; 401 when anonymous. Responses match the spec schemas.Device-registration and preference endpoints remain out of scope (unimplemented as before).
Verification
@objectstack/service-messaging: typecheck clean (sole remaining error is a pre-existing unused-var in the untouchedemail-channel.test.ts); 27 tests pass, incl. 6 new inbox-API tests covering the join, read-filter, in-place receipt update (no duplicate), insert-when-absent, mark-all, and no-engine degradation.@objectstack/client: notification tests pass; response shapes reconciled to the spec schemas ({ success, readCount }).@objectstack/runtime:handleNotification+ dispatch branch add no new type errors (the 13 errors intscare pre-existing missing-.d.tsnoise for sibling packages in a partial build graph, none in the changed code).Mirrors the read/mark-read logic already browser-verified on the objectui bell.
🤖 Generated with Claude Code