3.2 KiB
3.2 KiB
Task F4: Notification Framework Foundation
Scope Delivered
- Added notification foundation schema for events, inbox items, templates, and deliveries.
- Added reusable notification services for event publishing, recipient resolution, template rendering, and inbox mutations.
- Integrated approval lifecycle notifications for submit, approve-complete, reject, return, and cancel flows.
- Replaced the old mock/Zustand notification UI with API-backed React Query notifications in the header bell and notifications page.
Schema
New tables:
app_notification_eventsapp_notificationsapp_notification_templatesapp_notification_deliveries
Key behavior:
- organization-scoped rows throughout
dedupe_keysupport on events- inbox rows track
read_at,archived_at, andstatus - delivery rows prepare future multi-channel expansion
Event Flow
Current flow:
- Approval service completes its main action.
- Approval service calls
publishNotificationEvent()with a safe wrapper. - Notification foundation persists
app_notification_events. - Notification foundation resolves recipients and renders the matching template.
- In-app notifications are created in
app_notifications. - Header bell and
/dashboard/notificationsread from the inbox APIs.
Notification failures are intentionally non-blocking for approval actions. Failures are stored on the notification event row and audited.
Recipient Resolution
Implemented resolvers:
explicit_userapproval_current_step_approversapproval_requester
Current approval approver resolution uses:
- active CRM role assignments mapped to the current step role code
- membership
business_roleas a fallback path
Recipients are deduplicated and actor exclusion is supported per event rule.
Template Syntax
Supported placeholders use simple token replacement:
{{quotationCode}}{{workflowName}}{{actorName}}{{currentStepRoleName}}{{entityLink}}{{remark}}
Rules:
- missing values render as
- - plain text only
- no code execution
Approval Integration
Integrated events:
approval.requestedapproval.step.approvedfor step-to-step progressionapproval.completedfor final approval completionapproval.step.rejectedapproval.returnedapproval.cancelled
Notes:
- final approval emits
approval.completedinstead of duplicating both requester notifications - notification delivery is intentionally best-effort and does not roll back approvals
Inbox APIs
Added routes:
GET /api/notificationsGET /api/notifications/unread-countPOST /api/notifications/[id]/readPOST /api/notifications/read-allPOST /api/notifications/[id]/archive
Access model:
notifications.readnotifications.updatenotifications.admin
Normal users can operate only on their own notifications because server-side filtering always scopes by recipient_user_id.
Default Templates
Foundation seed now upserts default in_app templates for all approval events. Seed remains idempotent and organization-scoped.
Current Limitations
- no SMTP sending yet
- no LINE delivery yet
- no webhook delivery yet
- no reminder/escalation scheduler yet
- no admin template editor UI yet
- no real-time push/SSE yet