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
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
(/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 = ?
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
{ notificationIds: [unread IDs] }
API->>DB: UPDATE notifications SET read = 1
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
Back button + 'Varsler' title"]
NotificationList["NotificationList"]
EmptyState["EmptyState
Bell icon + 'Ingen varsler enna'"]
end
subgraph "Notification List"
DateGroup["DateGroupHeader
('I DAG', 'I GAR', date)"]
NotificationCard["NotificationCard"]
end
subgraph "Notification Card"
TypeIcon["TypeIcon
(colored circle + icon)"]
Content["Content
(title, body, timestamp)"]
UnreadDot["UnreadDot
(blue indicator)"]
end
subgraph "Dashboard Integration"
BellIcon["Bell Icon
(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
5. Deep Link Routing Table (Planned)
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
5.1 Deep Link Format
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
Notifications API: GET/PATCH /api/notifications — See API Reference
Settings API: PATCH /api/settings (push/email toggles) — See API Reference
Notifications schema: notifications table — See Database Schema
Settings schema: settings table — See Database Schema
Component overview: See component-overview.md
Figma notifications screen: mockups/figma-make-export/src/app/screens/Notifications.tsx
Web notifications page: src/drop-app/src/app/notifications/page.tsx — See PAGES.md
Profile settings flow: See flow-profile-settings.md