Skip to content

feat(messaging,runtime): implement /api/v1/notifications REST surface (ADR-0030) - #1486

Merged
xuyushun441-sys merged 1 commit into
mainfrom
feat/adr-30-sdk-notifications-receipt
Jun 1, 2026
Merged

feat(messaging,runtime): implement /api/v1/notifications REST surface (ADR-0030)#1486
xuyushun441-sys merged 1 commit into
mainfrom
feat/adr-30-sdk-notifications-receipt

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

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

  • no plugin registered the notification core service, so hasNotification was always false and the routes were never advertised in discovery;
  • there was no handleNotification in the dispatcher;
  • client.notifications.list/markRead/markAllRead therefore 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? }) reads sys_inbox_message joined with sys_notification_receipt for read-state (unread until a read/clicked/dismissed receipt exists); read filter applied after the join; returns { notifications, unreadCount }.
    • markRead(userId, ids) / markAllRead(userId) upsert the receipt to read, keyed (notification_id, user_id, channel:'inbox') — updating the existing delivered receipt in place, inserting only when absent. Returns { success, readCount }.
  • MessagingServicePlugin — also registers the messaging service under the notification core slot so the dispatcher resolves + advertises the routes. The legacy INotificationService.send() abstraction is unused/unconsumed.
  • HttpDispatcherhandleNotification + /notifications dispatch branch; takes the authenticated user from executionContext; 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 untouched email-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 in tsc are pre-existing missing-.d.ts noise 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

@vercel

vercelBot commented Jun 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 1, 2026 6:57pm

Request Review

… (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>
@xuyushun441-sys
xuyushun441-sysforce-pushed the feat/adr-30-sdk-notifications-receipt branch from b6869d4 to 232e098CompareJune 1, 2026 18:53
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling size/m labels Jun 1, 2026
@xuyushun441-sys
xuyushun441-sys merged commit 8e539cc into mainJun 1, 2026
9 of 11 checks passed
}

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>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@xuyushun441-sys@github-advanced-security@os-zhuang