# 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
