# 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