feature: version one notification feature implemented.
This commit is contained in:
@@ -10,5 +10,6 @@ alwaysApply: false
|
||||
- **API:** `GET /notifications/tab-counts`; **Cases + Treatment** use per-case read + `hasUnread` on list cards; Tasks marks read on tab visit. Treatment rail uses `TreatmentLabCasesPanel` + `LabCaseTrackerCard` + activity feed.
|
||||
- **Pattern:** `useTabBadgeCounts` + `notifyTabBadgesChanged()` — same shape as `usePendingConnectionsCount`.
|
||||
- **Orgs connections badge** stays on separate `pending-count` endpoint.
|
||||
- **Header inbox** (bell) is separate — `.cursor/skills/notifications-inbox/SKILL.md`.
|
||||
|
||||
Full map: `.cursor/skills/lab-notifications/SKILL.md`
|
||||
|
||||
@@ -54,5 +54,10 @@ After mutations, frontend calls `notifyTabBadgesChanged()` (window event).
|
||||
|
||||
## Out of scope (later steps)
|
||||
|
||||
- Push / email / websockets
|
||||
- Push / email
|
||||
- Making Cases/Tasks/Treatment lists live via websockets
|
||||
- `CASE_AMENDED` emit (Step 7)
|
||||
|
||||
## Related: header inbox
|
||||
|
||||
Permission-free bell + `UserNotification` fan-out + Socket.IO — see `.cursor/skills/notifications-inbox/SKILL.md`. Independent of tab badge cursors.
|
||||
|
||||
35
.cursor/skills/notifications-inbox/SKILL.md
Normal file
35
.cursor/skills/notifications-inbox/SKILL.md
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: dyolink-notifications-inbox
|
||||
description: Header notification bell/inbox (UserNotification fan-out + Socket.IO). Use when changing inbox cards, realtime gateway, or notification deep links — distinct from sidebar tab badges.
|
||||
---
|
||||
|
||||
# Notifications inbox (bell)
|
||||
|
||||
Permission-free **feature** (every dashboard user sees the bell). **Cards** are permission-filtered at fan-out time.
|
||||
|
||||
## vs tab badges
|
||||
|
||||
| | Inbox (`UserNotification`) | Sidebar badges (`LabCaseActivity`) |
|
||||
|--|--|--|
|
||||
| Entry | Header bell → dropdown + `/notifications` | Sidebar Cases/Tasks/Treatment/Orgs |
|
||||
| Live | Socket.IO (`/realtime`) | REST + `tab-badges-changed` |
|
||||
| Read | Per-card `readAt` only | Per-case / tab cursors |
|
||||
|
||||
Do **not** clear tab badges when marking an inbox card read.
|
||||
|
||||
## Backend
|
||||
|
||||
- Model: `UserNotification` + `UserNotificationType` in Prisma
|
||||
- Fan-out: [`user-notification.service.ts`](backend/src/modules/notifications/user-notification.service.ts)
|
||||
- Realtime: [`backend/src/realtime/`](backend/src/realtime/) — `RealtimeGateway` (cookie JWT), `RealtimeEmitter`, rooms `user:{userId}:org:{organizationId}`
|
||||
- REST: `GET /notifications/inbox`, `GET /notifications/inbox/unread-count`, `POST /notifications/inbox/:id/read`, `POST /notifications/inbox/read-all`
|
||||
|
||||
## Emit sites (parallel to LabCaseActivity)
|
||||
|
||||
CASE_SENT, CLINIC_COMMENT, LAB_COMMENT (+ LAB_COMMENT_CLINIC), CASE_IMPORTANT, TASK_COMPLETED, TASK_ASSIGNED, CONNECTION_REQUEST, STAFF_INVITE — see plan / service call sites.
|
||||
|
||||
## Frontend
|
||||
|
||||
- `RealtimeProvider` in dashboard layout
|
||||
- `NotificationBell` + `NotificationsPage` + `NotificationCard`
|
||||
- Deep links: `/cases?caseId=`, `/tasks?taskId=`, `/treatment?labCaseId=`, `/organizations`, `/staff`
|
||||
Reference in New Issue
Block a user