Changeset 0.28.2 (#183)
This commit is contained in:
@@ -193,9 +193,25 @@ All enum values used across the API. Definitive source of truth.
|
||||
|
||||
## Notification Types
|
||||
|
||||
`role.fallback`, `memory.extracted`, `system.announcement`,
|
||||
`workflow.assigned`, `workflow.claimed`, `task.completed`,
|
||||
`task.failed`, `user.mentioned`
|
||||
Convention: `domain.action`. Free-form strings — new types don't
|
||||
require migration.
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `role.fallback` | Model role fell back to secondary provider |
|
||||
| `kb.ready` | Knowledge base finished indexing |
|
||||
| `kb.error` | Knowledge base indexing failed |
|
||||
| `grant.changed` | User added to or removed from a group |
|
||||
| `memory.extracted` | New memories extracted from conversation |
|
||||
| `user.mentioned` | User was @mentioned in a channel |
|
||||
| `workflow.assigned` | Workflow stage assigned to team/user |
|
||||
| `workflow.claimed` | Workflow assignment claimed by a user |
|
||||
| `task.completed` | Scheduled task finished successfully |
|
||||
| `task.failed` | Scheduled task failed |
|
||||
| `task.budget_exceeded` | Task hit token/tool/wall-clock budget |
|
||||
|
||||
**Planned (not yet implemented):**
|
||||
`system.announcement` (v0.28.4 — admin broadcast to all users)
|
||||
|
||||
## Git Auth Types
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
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
|
||||
|
||||
```
|
||||
@@ -13,32 +16,102 @@ 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 | 1–100, 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|memory.extracted|system.announcement|...",
|
||||
"type": "role.fallback",
|
||||
"title": "Role Fallback Triggered",
|
||||
"body": "Primary model unavailable, using fallback",
|
||||
"metadata": {},
|
||||
"read": false,
|
||||
"created_at": "..."
|
||||
"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 → { "preferences": [...] }
|
||||
PUT /notifications/preferences/:type ← { "in_app": true, "email": false }
|
||||
DELETE /notifications/preferences/:type → reset to default
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
@@ -63,6 +63,11 @@ Clients subscribe to rooms for scoped event delivery:
|
||||
| `memory.extracted` | → client | New memory extracted |
|
||||
| `memory.status` | → client | Memory approved/rejected |
|
||||
| `role.fallback` | → client | Role fallback triggered |
|
||||
| `user.mentioned` | → client | User was @mentioned in a channel |
|
||||
| `workflow.assigned` | → client | Workflow stage assigned to team/user |
|
||||
| `workflow.claimed` | → client | Workflow assignment claimed |
|
||||
| `workflow.advanced` | → client | Workflow stage advanced |
|
||||
| `workflow.completed` | → client | Workflow instance completed |
|
||||
| `workspace.updated` | → client | Workspace state changed |
|
||||
| `project.updated` | → client | Project metadata changed |
|
||||
| `extension.updated` | → client | Extension config changed |
|
||||
@@ -168,8 +173,12 @@ only, `↔ both` = bidirectional.
|
||||
|
||||
### Notification Types
|
||||
|
||||
`role.fallback`, `memory.extracted`, `system.announcement`, plus
|
||||
extensible via notification service.
|
||||
`role.fallback`, `kb.ready`, `kb.error`, `grant.changed`,
|
||||
`memory.extracted`, `user.mentioned`, `workflow.assigned`,
|
||||
`workflow.claimed`, `task.completed`, `task.failed`,
|
||||
`task.budget_exceeded`
|
||||
|
||||
See [enums.md](enums.md#notification-types) for full descriptions.
|
||||
|
||||
### Git Auth Types
|
||||
|
||||
|
||||
@@ -69,12 +69,20 @@ Audit arc, frontend SDK, and infrastructure improvements.
|
||||
### v0.28.2 — ICD Audit: Notifications + Profile + Knowledge + Notes + Providers
|
||||
Known ICD report failures to investigate (likely envelope shape mismatches):
|
||||
- [ ] `GET /settings` — `missing key "settings"` (profile)
|
||||
- [ ] `GET /notifications/preferences` — `missing key "preferences"`
|
||||
- [x] `GET /notifications/preferences` — `missing key "preferences"` (envelope fix)
|
||||
- [ ] `GET /workspaces` — `missing key "data"`
|
||||
- [ ] `GET /git-credentials` — `missing key "data"`
|
||||
- [ ] Notes, providers — passed clean but need full trace (route → handler → store → tests)
|
||||
- [ ] WebSocket event contract audit: document `message.created`, `workflow.advanced`,
|
||||
`presence.changed`, `typing`, `workflow.assigned` event shapes in ICD
|
||||
- [x] Notifications ICD audit: object shape, query params, response envelopes, WS events
|
||||
- [x] Notification type enum sync: remove aspirational types, add implemented types
|
||||
(`kb.ready`, `kb.error`, `grant.changed`, `task.budget_exceeded`)
|
||||
- [x] Implement `memory.extracted` notification (hook in memory extractor)
|
||||
- [x] Implement `user.mentioned` persisted notification (was WS-only)
|
||||
- [x] Implement `workflow.claimed` persisted notification (was WS-only)
|
||||
- [x] Remove dead `NotifTypeProjectInvite` constant
|
||||
- [ ] Notification handler + store tests (PG + SQLite)
|
||||
|
||||
### v0.28.3 — Security Tier (ICD Runner Red Team)
|
||||
New `security` tier in ICD test runner. Multi-user fixtures already exist.
|
||||
@@ -115,6 +123,9 @@ New `security` tier in ICD test runner. Multi-user fixtures already exist.
|
||||
- [ ] Git credentials settings UI: vault-encrypted per-user credentials, SSH key
|
||||
management, per-workspace remote config. Table exists (`git_credentials`), vault
|
||||
pattern exists — needs settings section and CRUD handler.
|
||||
- [ ] `system.announcement` notification type: admin broadcast endpoint
|
||||
(`POST /admin/notifications/broadcast`), fan-out to all active users via
|
||||
`NotifyMany`, admin UI for composing announcements
|
||||
|
||||
### v0.28.5 — Frontend SDK
|
||||
`switchboard-sdk.js` — composition layer over existing globals. Surface
|
||||
|
||||
Reference in New Issue
Block a user