task-f.4
This commit is contained in:
116
docs/implementation/task-f4-notification-framework-foundation.md
Normal file
116
docs/implementation/task-f4-notification-framework-foundation.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# 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_events`
|
||||
- `app_notifications`
|
||||
- `app_notification_templates`
|
||||
- `app_notification_deliveries`
|
||||
|
||||
Key behavior:
|
||||
|
||||
- organization-scoped rows throughout
|
||||
- `dedupe_key` support on events
|
||||
- inbox rows track `read_at`, `archived_at`, and `status`
|
||||
- delivery rows prepare future multi-channel expansion
|
||||
|
||||
## Event Flow
|
||||
|
||||
Current flow:
|
||||
|
||||
1. Approval service completes its main action.
|
||||
2. Approval service calls `publishNotificationEvent()` with a safe wrapper.
|
||||
3. Notification foundation persists `app_notification_events`.
|
||||
4. Notification foundation resolves recipients and renders the matching template.
|
||||
5. In-app notifications are created in `app_notifications`.
|
||||
6. Header bell and `/dashboard/notifications` read 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_user`
|
||||
- `approval_current_step_approvers`
|
||||
- `approval_requester`
|
||||
|
||||
Current approval approver resolution uses:
|
||||
|
||||
- active CRM role assignments mapped to the current step role code
|
||||
- membership `business_role` as 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.requested`
|
||||
- `approval.step.approved` for step-to-step progression
|
||||
- `approval.completed` for final approval completion
|
||||
- `approval.step.rejected`
|
||||
- `approval.returned`
|
||||
- `approval.cancelled`
|
||||
|
||||
Notes:
|
||||
|
||||
- final approval emits `approval.completed` instead of duplicating both requester notifications
|
||||
- notification delivery is intentionally best-effort and does not roll back approvals
|
||||
|
||||
## Inbox APIs
|
||||
|
||||
Added routes:
|
||||
|
||||
- `GET /api/notifications`
|
||||
- `GET /api/notifications/unread-count`
|
||||
- `POST /api/notifications/[id]/read`
|
||||
- `POST /api/notifications/read-all`
|
||||
- `POST /api/notifications/[id]/archive`
|
||||
|
||||
Access model:
|
||||
|
||||
- `notifications.read`
|
||||
- `notifications.update`
|
||||
- `notifications.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
|
||||
Reference in New Issue
Block a user