This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/docs/ICD/notifications.md
2026-03-13 12:19:55 +00:00

118 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Notifications
Real-time notification infrastructure with WebSocket delivery and
optional email transport.
**Auth:** All endpoints require authentication (JWT via `sb_token`
cookie or `Authorization: Bearer` header).
### CRUD
```
GET /notifications → paginated list
GET /notifications/unread-count → { "count": 5 }
PATCH /notifications/:id/read → mark one as read
POST /notifications/mark-all-read → mark all as read
DELETE /notifications/:id
```
**`GET /notifications`** — paginated list for the authenticated user.
Query parameters:
| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `limit` | int | 20 | 1100, clamped |
| `offset` | int | 0 | Pagination offset |
| `unread_only` | bool | false | Filter to unread only |
Response:
```json
{
"data": [ ... ],
"total": 42,
"limit": 20,
"offset": 0
}
```
Notification object:
```json
{
"id": "uuid",
"user_id": "uuid",
"type": "role.fallback",
"title": "Role Fallback Triggered",
"body": "Primary model unavailable, using fallback",
"resource_type": "channel",
"resource_id": "uuid",
"is_read": false,
"created_at": "2025-01-15T12:00:00Z"
}
```
`resource_type` and `resource_id` are optional — used for
click-to-navigate. The resource may be deleted (no FK constraint).
### Preferences
Users control per-type delivery:
```
GET /notifications/preferences → { "data": [...] }
PUT /notifications/preferences/:type ← { "in_app": true, "email": false }
DELETE /notifications/preferences/:type → reset to default
```
**`GET /notifications/preferences`** returns all preferences set by
the user. Empty array if none are configured.
**`PUT /notifications/preferences/:type`** creates or updates a
preference. Both `in_app` and `email` fields are optional (merges
with existing values if set).
**`DELETE /notifications/preferences/:type`** removes the preference,
falling back to the next level in the resolution chain. Idempotent —
deleting a non-existent preference returns 200.
Resolution: specific type pref → user wildcard `*` pref → system
default (`in_app=true`, `email=false`).
Returns 503 if the preference store is not available (unmanaged mode).
### Admin
```
POST /admin/notifications/test-email → send test email to requesting admin
```
Requires admin role. Loads SMTP config from platform settings,
sends a test message to the admin's registered email address.
### WebSocket Events
| Event | Payload | Description |
|-------|---------|-------------|
| `notification.new` | Full notification object | New notification created |
| `notification.read` | `{"id": "uuid"}` | Single notification marked read |
| `notification.read` | `{"action": "mark_all_read"}` | All notifications marked read |
These are targeted via `Hub.SendToUser` — no room subscription
required. Used for badge sync across tabs.
### Notification Types
See [enums.md](enums.md#notification-types) for the canonical list.
Types are free-form strings (`domain.action` convention) — new types
don't require migration.
### Retention
Background cleanup prunes notifications older than 90 days (default,
configurable via `WithRetention`). Runs daily after a 5-minute
startup delay.
---