Notification Channel Preferences
Why it matters
Sending every notification type to every user with no opt-out mechanism violates GDPR Art. 21 (right to object to processing) and GDPR Art. 7 (conditions for consent). CCPA §1798.120 grants similar opt-out rights. Beyond compliance, a platform that ignores preferences trains users to mute or uninstall the app rather than adjusting settings — a direct retention problem. Notification preference checks must happen before dispatch, not as a post-hoc filter; dispatching a notification and suppressing delivery still constitutes processing the personal data used to trigger it.
Severity rationale
Low because the immediate harm is user experience degradation and notification fatigue, but the GDPR Art. 21 right-to-object exposure elevates the compliance risk above cosmetic severity.
Remediation
Add a NotificationPreference model to your Prisma schema and check it before dispatching any notification in your notification service.
// lib/notifications.ts
export async function sendNotification(
recipientId: string,
type: 'post_liked' | 'user_followed' | 'post_commented',
data: Record<string, unknown>
) {
const prefs = await db.notificationPreference.findUnique({
where: { userId: recipientId }
})
const gateMap = {
post_liked: prefs?.notifyOnLike ?? true,
user_followed: prefs?.notifyOnFollow ?? true,
post_commented: prefs?.notifyOnComment ?? true
}
if (!gateMap[type]) return // Preference says no: abort before any dispatch
await db.notification.create({ data: { userId: recipientId, type, payload: data } })
if (prefs?.emailEnabled ?? true) {
await sendNotificationEmail(recipientId, type, data)
}
}
Expose preference toggles in app/settings/notifications/page.tsx so users can adjust each type independently without contacting support.
Detection
-
ID:
channel-preferences -
Severity:
low -
What to look for: Enumerate all relevant files and Check the user settings or preferences schema for notification preferences. Look for fields like
notify_on_like,notify_on_follow,email_notifications_enabled,push_notifications_enabled. Check API routes or settings UI that allow users to customize notification behavior. -
Pass criteria: User notification preferences exist in the schema. Settings UI allows users to opt out of specific notification types. Notification creation logic checks these preferences before dispatching.
-
Fail criteria: All users receive all notifications, or no preference mechanism exists.
-
Skip (N/A) when: Platform doesn't support notifications or has very few notification types.
-
Detail on fail:
"No notification_preferences table — users cannot opt out of notification types"or"Settings UI has no notification preferences"or"Notification creation doesn't check user preferences before dispatching" -
Remediation: Add notification preferences:
// Prisma schema model NotificationPreference { id String @id userId String @unique notifyOnLike Boolean @default(true) notifyOnFollow Boolean @default(true) notifyOnComment Boolean @default(true) emailEnabled Boolean @default(true) pushEnabled Boolean @default(true) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } // Check preferences before creating notifications async function createNotification(type: string, recipientId: string, data: any) { const prefs = await db.notificationPreference.findUnique({ where: { userId: recipientId } }) const typeMap = { 'post_liked': 'notifyOnLike', 'user_followed': 'notifyOnFollow', 'post_commented': 'notifyOnComment' } const shouldNotify = prefs?.[typeMap[type]] ?? true if (!shouldNotify) return const notification = await db.notification.create({ data: { userId: recipientId, type, content: JSON.stringify(data) } }) if (prefs?.emailEnabled) { await sendNotificationEmail(recipientId, notification) } } // Settings page async function updateNotificationPreferences(userId: string, updates: any) { return db.notificationPreference.upsert({ where: { userId }, update: updates, create: { userId, ...updates } }) }
External references
- gdpr · Art. 21 — Right to Object
- gdpr · Art. 7 — Conditions for Consent
- ccpa · §1798.120 — Right to Opt-Out
Taxons
History
- 2026-04-18·v1.0.0·Initial import from community-social-engagement·automated