Design notification systems — push (FCM/APNs), in-app messaging, email transactional flows, preference management, and delivery optimization
npx claudepluginhub cure-consulting-group/productengineeringskillsThis skill uses the workspace's default tool permissions.
Designs production-grade notification systems across push, in-app, email, and SMS channels. Every output enforces user preference respect, delivery reliability, legal compliance, and measurable engagement. Notifications are a trust contract with the user — abuse it and they churn.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Designs production-grade notification systems across push, in-app, email, and SMS channels. Every output enforces user preference respect, delivery reliability, legal compliance, and measurable engagement. Notifications are a trust contract with the user — abuse it and they churn.
Before starting, gather project context silently:
PORTFOLIO.md if it exists in the project root or parent directories for product/team contextcat package.json 2>/dev/null || cat build.gradle.kts 2>/dev/null || cat Podfile 2>/dev/null to detect stackgit log --oneline -5 2>/dev/null for recent changesls src/ app/ lib/ functions/ 2>/dev/null to understand project structurePush notification → Time-sensitive, actionable, personalized
In-app message → Contextual, non-interruptive, feature discovery
Transactional email → Expected, informative, legally required
SMS → Critical only (2FA, account recovery, urgent alerts)
Hard rules:
/i18n for string management| Request | Primary Output | Action |
|---|---|---|
| Push notification setup | FCM/APNs integration + token management | Configure push |
| Notification preferences | Preference model + UI + server enforcement | Design preferences |
| Transactional email | Template system + sending infrastructure | Build email pipeline |
| In-app messaging | Message display system + targeting rules | Implement in-app |
| Multi-channel orchestration | Channel router + fallback chains + dedup | Design orchestration |
| Notification audit | Delivery metrics + preference compliance review | Audit system |
Before generating, confirm:
| Channel | Best For | Latency | User Tolerance | Cost |
|---|---|---|---|---|
| Push | Time-sensitive actions, real-time updates | <1s | Low (3-5/day max) | Free (FCM) |
| In-app | Feature discovery, contextual tips, soft prompts | Immediate | Medium | Free |
| Receipts, digests, onboarding sequences, reports | Minutes | Medium (1-2/day) | Low | |
| SMS | 2FA, critical account alerts, delivery updates | <5s | Very low (rare) | High |
Event Source (app, Cloud Function, cron)
│
▼
Notification Service (centralized dispatch)
├── Preference Check → Does user want this, on this channel?
├── Rate Limiter → Has user hit daily/hourly cap?
├── Template Engine → Render content with user data + locale
├── Channel Router → Select best channel(s) for this notification
│ ├── Push Adapter → FCM / APNs
│ ├── Email Adapter → SendGrid / Postmark
│ ├── SMS Adapter → Twilio / SNS
│ └── In-App Adapter → Firestore / WebSocket
└── Delivery Tracker → Log send/deliver/open/click events
Android (FCM):
{
"message": {
"token": "device_token",
"data": {
"type": "order_update",
"orderId": "abc123",
"deepLink": "myapp://orders/abc123"
},
"android": {
"priority": "high",
"notification": {
"title": "Order Shipped",
"body": "Your order #abc123 is on its way",
"channel_id": "order_updates",
"click_action": "OPEN_ORDER_DETAIL"
}
}
}
}
channel_id — Android 8+ requires notification channelsiOS (APNs via FCM):
{
"message": {
"token": "device_token",
"apns": {
"headers": {
"apns-priority": "10",
"apns-push-type": "alert"
},
"payload": {
"aps": {
"alert": {
"title": "Order Shipped",
"body": "Your order #abc123 is on its way"
},
"sound": "default",
"badge": 1,
"category": "ORDER_UPDATE",
"thread-id": "orders",
"mutable-content": 1
},
"deepLink": "myapp://orders/abc123"
}
}
}
}
mutable-content: 1 for Notification Service Extensions (rich media, decryption)thread-idcategory for actionable notifications (reply, approve, dismiss)Web (Service Worker):
self.registration.showNotification('Order Shipped', {
body: 'Your order #abc123 is on its way',
icon: '/icons/notification-icon.png',
badge: '/icons/badge-icon.png',
data: { deepLink: '/orders/abc123' },
actions: [
{ action: 'view', title: 'View Order' },
{ action: 'dismiss', title: 'Dismiss' }
],
tag: 'order-abc123', // Deduplication
renotify: true
});
/firebase-architect)users/{uid}/devices/{tokenHash}onNewToken callbackFirebaseMessagingService (Android) / service worker (web) for message handlingAppDelegate or via SwiftUI .onAppear.p8 file) over certificate-based — keys don't expire annuallyUNUserNotificationCenterDelegate.didReceiveusers/{uid}/
devices/
{tokenHash}/
token: string
platform: "android" | "ios" | "web"
createdAt: Timestamp
lastActiveAt: Timestamp
appVersion: string
announcements, deals-us, sport-scores)NotificationCompat.Builder with BigPictureStyle, BigTextStyle, action buttonsUNNotificationServiceExtension for image download, UNNotificationContentExtension for custom UIimage field in notification options (limited browser support)FirebaseMessagingService even when app is killedcontent-available: 1 in APNs payload; limited to ~2-3 per hour by iOS; not guaranteedinterface NotificationPreferences {
global: boolean; // Master kill switch
channels: {
push: boolean;
email: boolean;
sms: boolean;
inApp: boolean;
};
categories: {
orderUpdates: { push: boolean; email: boolean };
promotions: { push: boolean; email: boolean };
messages: { push: boolean; email: boolean; inApp: boolean };
security: { push: boolean; email: boolean; sms: boolean }; // Always enabled
systemAlerts: { push: boolean; inApp: boolean }; // Always enabled
};
quietHours: {
enabled: boolean;
start: string; // "22:00" in user's local time
end: string; // "08:00"
timezone: string;
};
}
Default limits (configurable per notification category):
Push: 5 per user per day, max 2 per hour
Email: 2 per user per day (excluding transactional)
SMS: 1 per user per day (excluding 2FA)
In-app: 3 per session
notificationId derived from event type + entity ID + timestamp windownotificationId sent within 5-minute window, suppress duplicatePrimary channel fails → try next channel in priority order:
Order updates: push → in-app → email
Chat messages: push → in-app
Promotions: email → in-app
Security alerts: push → sms → email (all channels, do not stop on success)
| Type | Examples | Opt-Out? | Priority |
|---|---|---|---|
| Transactional | Receipts, password resets, 2FA | No | Immediate |
| System | Account changes, TOS updates, security alerts | No | Immediate |
| Triggered | Welcome series, onboarding, re-engagement | Yes | Batched |
| Marketing | Promotions, newsletters, product updates | Yes | Scheduled |
mail.yourapp.com) to protect root domain reputation| Metric | Target | Alert Threshold |
|---|---|---|
| Push delivery rate | >95% | <90% |
| Push open rate | >8% | <3% |
| Email delivery rate | >98% | <95% |
| Email open rate | >25% | <15% |
| Email click rate | >3% | <1% |
| Unsubscribe rate | <0.5% per send | >1% |
| SMS delivery rate | >97% | <93% |
| Bounce rate (email) | <2% | >5% |
| Spam complaint rate | <0.1% | >0.3% |
Log these events for every notification:
notification.created — notification generated by the system
notification.filtered — suppressed by preference/rate-limit/dedup
notification.sent — handed to delivery provider (FCM/SendGrid/Twilio)
notification.delivered — confirmed delivery to device/inbox
notification.opened — user tapped/clicked the notification
notification.actioned — user took the CTA action (deep link followed)
notification.dismissed — user swiped away / marked as read
notification.bounced — delivery failed (invalid token, email bounce)
notification.complained — user reported as spam
For every notification system design, deliver:
| Notification | Trigger | Channels | Category | Opt-Out? | Rate Limit |
|-------------|---------|----------|----------|----------|------------|
| Order shipped | order.status.shipped | push, email | orderUpdates | Yes | 1/order |
| Password reset | auth.passwordReset | email | security | No | 3/hour |
| New message | chat.message.created | push, in-app | messages | Yes | 5/day |
push:
android: Firebase Cloud Messaging (FCM) via firebase-messaging
ios: APNs via FCM (key-based auth, .p8 file)
web: FCM via firebase-messaging + service worker
email:
transactional: Postmark or SendGrid (dedicated IP)
marketing: SendGrid or Mailchimp (separate IP pool)
templates: React Email or MJML
authentication: SPF + DKIM + DMARC on sending subdomain
sms:
provider: Twilio or AWS SNS
use_case: 2FA and critical alerts only
in_app:
storage: Firestore collection per user
display: custom UI component (banner, modal, inbox)
analytics:
events: Firebase Analytics + custom notification events
dashboards: Mixpanel or PostHog notification funnels
Generate notification infrastructure using Write:
services/FirebaseMessagingService.kt — token management and notification displayServices/NotificationService.swift — UNUserNotificationCenter delegatepublic/firebase-messaging-sw.js — service worker for web pushfunctions/src/notifications/send.ts — multi-channel notification dispatcherfunctions/src/notifications/templates/ — welcome, receipt, alert templates (MJML or React Email)Before generating, Grep for existing notification code (FCM|messaging|notification|push) to understand current state.
/analytics-implementation — notification event tracking and funnel analysis/firebase-architect — Firestore schema for notification preferences and token storage/i18n — localize all notification content per user locale/customer-onboarding — onboarding notification sequences and activation emails/security-review — audit notification payloads for PII exposure/compliance-architect — GDPR/CAN-SPAM/TCPA compliance for notification channels