Skip to main content

Notifications Flow

Flow: Notifications

Document: LLD-005 Version: 1.0 Date: 2026-02-21 Author: Frontend Architect (AI Agent) Status: Draft Scope: Push notification delivery, in-app notification center, notification types, read/unread state, deep linking, and permission handling


1. Overview

Drop's notification system provides users with transaction alerts, security notifications, and system updates. The current implementation consists of an in-app notification center (bell icon) with read/unread state management. Push notifications via Expo Push are planned for mobile but not yet implemented.

Current state:

  • In-app notification center: Implemented (web)
  • Push notifications: Not yet implemented (planned via Expo Push for mobile)
  • Deep linking from notifications: Not yet configured
  • Notification preferences: Implemented (push/email toggles in settings)

2. Push Notification Delivery (Planned Architecture)

2.1 Sequence Diagram — Push Notification Flow

sequenceDiagram
    actor User
    participant Mobile as Expo App
    participant API as Drop API
    participant DB as Database
    participant Push as Expo Push<br/>Service
    participant APNS as APNs / FCM

    Note over Mobile,APNS: Setup Phase (on login)
    Mobile->>Mobile: Request notification permission
    Mobile->>Push: Register for push token
    Push-->>Mobile: { expoPushToken }
    Mobile->>API: POST /api/push-token { token, platform }
    API->>DB: INSERT push_tokens (user_id, token, platform)

    Note over API,APNS: Trigger Phase (on event)
    API->>API: Transaction completed / security event
    API->>DB: INSERT notification (user_id, type, title, body)
    API->>DB: SELECT push_tokens WHERE user_id = ?
    API->>Push: POST /send { to: expoPushToken, title, body, data }
    Push->>APNS: Forward to APNs (iOS) / FCM (Android)
    APNS-->>Mobile: Push notification delivered

    Note over Mobile: Receive Phase
    Mobile->>Mobile: Display system notification
    User->>Mobile: Tap notification
    Mobile->>Mobile: Deep link to relevant screen
    Mobile->>API: PATCH /api/notifications { notificationIds: [id] }
    API->>DB: UPDATE notifications SET read = 1

2.2 In-App Notification Center (Current Implementation)

sequenceDiagram
    actor User
    participant App as Drop App<br/>(/notifications)
    participant API as Drop API
    participant DB as Database

    User->>App: Tap bell icon (dashboard) or navigate to /notifications
    App->>App: useAuth() — verify authenticated

    App->>API: GET /api/notifications
    API->>DB: SELECT notifications WHERE user_id = ?<br/>ORDER BY created_at DESC
    API-->>App: { data: [ { id, type, title, body, read, createdAt }, ... ] }

    App->>App: Group by date (I DAG, I GAR, older)
    App->>App: Render notification cards with icons

    Note over App: Auto-mark as read on page load
    App->>App: Collect unread notification IDs
    App->>API: PATCH /api/notifications<br/>{ notificationIds: [unread IDs] }
    API->>DB: UPDATE notifications SET read = 1<br/>WHERE id IN (?) AND user_id = ?
    API-->>App: 200 OK (fire-and-forget)

3. Notification Center Components

3.1 Component Diagram

graph TD
    subgraph "Notification Center Page"
        Header["Header<br/>Back button + 'Varsler' title"]
        NotificationList["NotificationList"]
        EmptyState["EmptyState<br/>Bell icon + 'Ingen varsler enna'"]
    end

    subgraph "Notification List"
        DateGroup["DateGroupHeader<br/>('I DAG', 'I GAR', date)"]
        NotificationCard["NotificationCard"]
    end

    subgraph "Notification Card"
        TypeIcon["TypeIcon<br/>(colored circle + icon)"]
        Content["Content<br/>(title, body, timestamp)"]
        UnreadDot["UnreadDot<br/>(blue indicator)"]
    end

    subgraph "Dashboard Integration"
        BellIcon["Bell Icon<br/>(header, with badge count)"]
    end

    NotificationList --> DateGroup
    DateGroup --> NotificationCard
    NotificationCard --> TypeIcon
    NotificationCard --> Content
    NotificationCard --> UnreadDot

    BellIcon -->|navigate| Header

4. Notification Type Table

Type Icon Icon Color Background Title Example Body Example Priority
transaction_complete ArrowUpRight #0B6E35 (green) #F0FDF4 "Overforing til Mama Jasmina fullfort" "2 000 kr sendt til Serbia" Normal
qr_payment ScanLine #D4A017 (gold) #FEF3C7 "QR-betaling hos Ahmetov Kebab" "129 kr betalt" Normal
security Smartphone #3B82F6 (blue) #EFF6FF "Ny palogging fra iPhone" "Oslo, Norge" High
rate_update TrendingUp #D4A017 (gold) #FEF3C7 "Valutakurs oppdatert" "1 NOK = 11.70 RSD" Low
system Bell #6B7280 (gray) #F3F4F6 "Systemoppdatering" "Drop er oppdatert til v0.2.0" Low
promotional #6B7280 (gray) #F3F4F6 "Nytt tilbud" "0% gebyr denne uken!" Low

4.1 Priority Levels

Priority Behavior Push In-App
High Immediate delivery, sound, badge Yes (when implemented) Top of list, bold styling
Normal Standard delivery Yes (when implemented) Normal styling
Low Batched delivery Optional (user preference) Normal styling

Notification Type Deep Link Target Web Route Mobile Route
transaction_complete Transaction detail /transactions?id={txId} /(tabs)/history?id={txId}
qr_payment Transaction detail /transactions?id={txId} /(tabs)/history?id={txId}
security Security settings /profile/security /(tabs)/profile
rate_update Send money (with rate) /send /(tabs)/send
system Notification center /notifications /notifications
promotional Landing or feature page / or feature URL App home
Platform Format Example
Web URL path https://getdrop.no/transactions?id=tx_rem_1
Mobile (planned) Custom scheme drop://transactions/tx_rem_1
Expo push data JSON payload { "type": "transaction_complete", "targetId": "tx_rem_1" }

6. Permission Handling

6.1 Notification Permission Flow

Platform Permission Request First Time Denied Settings Redirect
iOS (Expo) Notifications.requestPermissionsAsync() System dialog: "Drop would like to send you notifications" Returns { status: 'denied' } Linking.openSettings()
Android (Expo) Notifications.requestPermissionsAsync() System dialog (Android 13+): "Allow Drop to send you notifications?" Returns { status: 'denied' } Linking.openSettings()
Web Notification.requestPermission() Browser prompt: "getdrop.no wants to show notifications" Blocked; user must reset in browser settings Site settings via address bar

6.2 Permission State Machine

stateDiagram-v2
    [*] --> NotDetermined: First launch

    NotDetermined --> Requesting: App requests permission
    Requesting --> Granted: User allows
    Requesting --> Denied: User denies

    Granted --> Active: Push token registered
    Active --> Disabled: User toggles off in Drop settings
    Disabled --> Active: User toggles on in Drop settings

    Denied --> SettingsRedirect: App shows "enable in settings" prompt
    SettingsRedirect --> Granted: User enables in OS settings
    SettingsRedirect --> Denied: User keeps disabled

7. Notification Preferences (Settings Integration)

Users control notification delivery via /profile/notifications:

Setting API Field Effect
Push notifications ON pushEnabled: true Push tokens active, notifications delivered
Push notifications OFF pushEnabled: false Push tokens retained but not used for delivery
Email notifications ON emailEnabled: true Email alerts sent for high-priority events
Email notifications OFF emailEnabled: false No email alerts

API: PATCH /api/settings { pushEnabled: boolean, emailEnabled: boolean }


8. Time Formatting

Condition Format Example
Today "I dag kl. HH:MM" "I dag kl. 14:32"
Yesterday "I gar kl. HH:MM" "I gar kl. 18:45"
Older "DD.MM.YYYY kl. HH:MM" "19.02.2026 kl. 09:00"

9. Platform Differences

Feature Web Mobile
Notification center /notifications page with BottomNav Not implemented
Bell icon badge Dashboard header (unread count) Not implemented
Push notifications Not applicable (web push planned) Not implemented (Expo Push planned)
Auto-read on view Yes (marks all unread as read on page load) N/A
Deep linking URL-based routing Not configured
Notification grouping Date-based (I DAG, I GAR) N/A
Permission handling Browser Notification API Expo Notifications API

10. Data Schema

10.1 Notifications Table

Column Type Description
id TEXT PK Format: noti_ + 16 hex chars
user_id TEXT FK References users(id)
type TEXT transaction_complete, qr_payment, security, rate_update
title TEXT Notification title (Norwegian)
body TEXT Notification body text
read INTEGER 0 = unread, 1 = read
created_at TEXT ISO timestamp

10.2 API Endpoints

Method Endpoint Purpose
GET /api/notifications List all notifications for user
PATCH /api/notifications Mark notifications as read (max 100 IDs)

11. Accessibility Considerations (WCAG 2.1 AA)

Requirement Implementation
Badge count Bell icon badge uses aria-label "X uleste varsler"
Read/unread Unread dot uses both visual indicator (blue dot) and aria attributes
Notification list Semantic list markup with role="list"
Empty state Descriptive text "Ingen varsler enna" with Bell icon
Time formatting Relative time ("I dag kl. 14:32") for recent, absolute for older
Auto-read Fire-and-forget PATCH does not interrupt user reading
Push permission Clear explanation before requesting system permission

12. Cross-References