feature: version one notification feature implemented.

This commit is contained in:
2026-07-18 01:09:54 +03:30
parent 0740493384
commit 9f6ec193d2
40 changed files with 1679 additions and 224 deletions

View File

@@ -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`

View File

@@ -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.

View 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`