# Dashboard & Notifications This guide explains how the **customer dashboard** stays consistent and how **in-app notifications** are generated. ## Dashboard “single read model” (`/api/me/status`) To keep business logic out of the frontend, the Portal uses a single BFF endpoint: - **Endpoint**: `GET /api/me/status` - **Purpose**: Return a consistent snapshot of the customer’s current state (summary + tasks + gating signals). - **Domain type**: `@customer-portal/domain/dashboard` → `meStatusSchema` The response includes: - **`summary`**: Same shape as `GET /api/me/summary` (stats, next invoice, activity). - **`internetEligibility`**: Internet eligibility status/details for the logged-in customer. - **`residenceCardVerification`**: Residence card verification status/details. - **`paymentMethods.totalCount`**: Count of stored payment methods (or `null` if unavailable). - **`tasks[]`**: A prioritized list of dashboard tasks (invoice due, add payment method, order in progress, eligibility pending, IDV rejected, onboarding). Portal UI maps task `type` → icon locally; everything else (priority, copy, links) is computed server-side. ## In-app Notifications In-app notifications are stored in Postgres and fetched via the Notifications API. Notifications use domain templates in: - `packages/domain/notifications/schema.ts` ### All Notification Types | Type | Title | Created By | Trigger | | ------------------------- | ------------------------------------------ | ---------------------- | ------------------------------- | | `ELIGIBILITY_ELIGIBLE` | "Good news! Internet service is available" | Platform Event | Eligibility status → Eligible | | `ELIGIBILITY_INELIGIBLE` | "Internet service not available" | Platform Event | Eligibility status → Ineligible | | `VERIFICATION_VERIFIED` | "ID verification complete" | Platform Event | Verification status → Verified | | `VERIFICATION_REJECTED` | "ID verification requires attention" | Platform Event | Verification status → Rejected | | `ORDER_APPROVED` | "Order approved" | Fulfillment flow | Order approved in Salesforce | | `ORDER_ACTIVATED` | "Service activated" | Fulfillment flow | WHMCS provisioning complete | | `ORDER_FAILED` | "Order requires attention" | Fulfillment flow | Fulfillment error | | `CANCELLATION_SCHEDULED` | "Cancellation scheduled" | Cancellation flow | Customer requests cancellation | | `CANCELLATION_COMPLETE` | "Service cancelled" | _(Not implemented)_ | — | | `PAYMENT_METHOD_EXPIRING` | "Payment method expiring soon" | _(Not implemented)_ | — | | `INVOICE_DUE` | "Invoice due" | Dashboard status check | Invoice due within 7 days | | `SYSTEM_ANNOUNCEMENT` | "System announcement" | _(Not implemented)_ | — | ### Eligibility & Verification Notifications These are triggered by Salesforce Platform Events: 1. **Salesforce Flow** fires Platform Event when `Internet_Eligibility_Status__c` or `Id_Verification_Status__c` changes 2. **BFF subscriber** receives the event and extracts status fields 3. **Notification handler** creates notification only for final states: - Eligibility: `Eligible` or `Ineligible` (not `Pending`) - Verification: `Verified` or `Rejected` (not `Submitted`) **Important:** The Salesforce Flow must use `ISCHANGED()` to only include status fields when they actually changed. Otherwise, notifications would be created on every account update. See `docs/integrations/salesforce/platform-events.md` for Platform Event configuration. ### Order Notifications Created during the fulfillment workflow in: - `apps/bff/src/modules/orders/services/order-fulfillment-orchestrator.service.ts` The notification `sourceId` uses the Salesforce Order ID to prevent duplicates during retries. ### Cancellation Notifications Created when cancellation request is submitted: - Internet: `apps/bff/src/modules/subscriptions/internet-management/services/internet-cancellation.service.ts` - SIM: `apps/bff/src/modules/subscriptions/sim-management/services/sim-cancellation.service.ts` ### Invoice Due Notifications Created opportunistically when dashboard status is requested (`GET /api/me/status`) if an invoice is due within 7 days or overdue. ### Dedupe Behavior Notifications dedupe is enforced in: - `apps/bff/src/modules/notifications/notifications.service.ts` | Type Category | Dedupe Window | Logic | | -------------------------------------------- | ------------- | ------------------------ | | Most types | 1 hour | Same `type` + `sourceId` | | Invoice due, payment expiring, announcements | 24 hours | Same `type` + `sourceId` | ### Action URLs Notification templates use authenticated Portal routes: - `/account/orders` - Order notifications - `/account/services` - Activation/cancellation notifications - `/account/services/internet` - Eligibility notifications - `/account/settings/verification` - Verification notifications - `/account/billing/invoices` - Invoice notifications