Skip to content

Commit 187d77e

Browse files
committed
fix(notifications): NOT_FOUND provenance row, the roster pin, and the device refusal rows' wording
- error-code-ledger: service-messaging's NOT_FOUND (unregisterDevice), with its wire path. - platform-object-names.test: service-messaging's roster pin names sys_user_device (forced by the roster hunk). - route-ledger: the device refusal rows say 404 with or without an inbox, 501 only without a notification service; pinned in the device-face test. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADHkmRD9KKqvTU3THnute6
1 parent bf0b6d9 commit 187d77e

4 files changed

Lines changed: 24 additions & 8 deletions

File tree

‎packages/runtime/src/domains/notifications-devices.test.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,13 @@ describe('/notifications/devices — the device registry faces', () => {
133133
}
134134
expect(service.registerDevice).not.toHaveBeenCalled();
135135
expect(service.unregisterDevice).not.toHaveBeenCalled();
136+
137+
// Unserved with or without an inbox (the route ledger's refusal rows):
138+
// only a missing notification service answers 501.
139+
const { listInbox: _dropped, ...registryOnly } = deviceService();
140+
const noInbox = await makeDispatcher(registryOnly).handleNotification('/devices', 'GET', undefined, {}, SIGNED_IN());
141+
expect(noInbox.handled).toBe(false);
142+
const noService = await makeDispatcher(null).handleNotification('/devices', 'GET', undefined, {}, SIGNED_IN());
143+
expect(noService.response?.status).toBe(501);
136144
});
137145
});

‎packages/runtime/src/route-ledger.ts‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -404,21 +404,21 @@ export const ROUTE_LEDGER: readonly RouteLedgerEntry[] = [
404404
{ route: 'POST /notifications/devices', domain: '/notifications', disposition: 'sdk', client: 'notifications.registerDevice' },
405405
{ route: 'DELETE /notifications/devices/:deviceId', domain: '/notifications', disposition: 'sdk', client: 'notifications.unregisterDevice' },
406406
{ route: 'GET /notifications/devices', domain: '/notifications', disposition: 'server-only',
407-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
407+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
408408
{ route: 'PUT /notifications/devices', domain: '/notifications', disposition: 'server-only',
409-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
409+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
410410
{ route: 'PATCH /notifications/devices', domain: '/notifications', disposition: 'server-only',
411-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
411+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
412412
{ route: 'DELETE /notifications/devices', domain: '/notifications', disposition: 'server-only',
413-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
413+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
414414
{ route: 'GET /notifications/devices/:deviceId', domain: '/notifications', disposition: 'server-only',
415-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
415+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
416416
{ route: 'POST /notifications/devices/:deviceId', domain: '/notifications', disposition: 'server-only',
417-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
417+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
418418
{ route: 'PUT /notifications/devices/:deviceId', domain: '/notifications', disposition: 'server-only',
419-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
419+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
420420
{ route: 'PATCH /notifications/devices/:deviceId', domain: '/notifications', disposition: 'server-only',
421-
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 (or its 501 with no notification service)' },
421+
note: 'refusal-only, mounted for the v18 every-face anonymous floor (changeset 23225): anonymous 401 UNAUTHENTICATED, signed-in the notifications domain\'s 404 with or without an inbox (its 501 only when no notification service is registered)' },
422422

423423
// ── security (ADR-0090 suggested audience bindings) ───────────────────────
424424
{ route: 'GET /security/suggested-bindings', domain: '/security', disposition: 'sdk', client: 'security.suggestedBindings.list' },

‎packages/spec/src/api/error-code-ledger.zod.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,13 @@ export const ERROR_CODE_LEDGER = {
12081208
// operation, try when it settles"; that one says "never, fix the
12091209
// configuration instead".
12101210
'DELIVERY_NOT_ELIGIBLE',
1211+
// [#29068] `unregisterDevice`'s refusal for a device id the caller does
1212+
// not hold, unknown or another user's alike (`deviceNotFoundError` in
1213+
// `device-registry.ts`), so the answer never says the id exists for
1214+
// somebody else. Wire path: `DELETE /api/v1/notifications/devices/:deviceId`
1215+
// throws it out of the `/notifications` domain and the dispatcher answers
1216+
// `404 NOT_FOUND` through `resolveThrownHttpError`.
1217+
'NOT_FOUND',
12111218
],
12121219
'@objectstack/trigger-api': [
12131220
'ENQUEUE_FAILED', // queue accepted the call but publish threw

‎packages/spec/src/system/constants/platform-object-names.test.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ describe('platform-object predicates', () => {
175175
'sys_notification_preference',
176176
'sys_notification_receipt',
177177
'sys_notification_template',
178+
'sys_user_device',
178179
]);
179180
expect(isPlatformProvidedObjectName('sys_notification_subscription')).toBe(false);
180181
expect(isPlatformProvidedObjectName('sys_notification_preference')).toBe(true);

0 commit comments

Comments
 (0)