Channels and preferences Required
Keep every notification type in one catalogue
Define every notification type once, in code, with its category, allowed channels, default channels and urgency. Sending code accepts only types from that catalogue.
How to do it
Give each type a stable ID, such as order.shipped. Mark it transactional or marketing, list the channels it may use, and say which are on by default. Add an urgency of critical, normal or low, which quiet hours and batching read later. Generate the settings page from the same catalogue, so a new type always gets a switch. Reject an unknown type at the send call, not in production logs.
Example
export const NOTIFICATIONS = {
'order.shipped': { category: 'transactional', urgency: 'normal', channels: ['inapp', 'push', 'email'], defaults: ['inapp', 'push'] },
'login.new-device': { category: 'transactional', urgency: 'critical', channels: ['inapp', 'push', 'email'], defaults: ['inapp', 'email'] },
'weekly.offers': { category: 'marketing', urgency: 'low', channels: ['email', 'push'], defaults: [] },
};
export function notificationType(id) {
const type = NOTIFICATIONS[id];
if (!type) throw new Error(`Unknown notification type: ${id}`);
return type;
}
from dataclasses import dataclass
@dataclass(frozen=True)
class NotificationType:
category: str
urgency: str
channels: tuple[str, ...]
defaults: tuple[str, ...]
NOTIFICATIONS = {
"order.shipped": NotificationType("transactional", "normal", ("inapp", "push", "email"), ("inapp", "push")),
"login.new-device": NotificationType("transactional", "critical", ("inapp", "push", "email"), ("inapp", "email")),
"weekly.offers": NotificationType("marketing", "low", ("email", "push"), ()),
}
def notification_type(type_id: str) -> NotificationType:
if type_id not in NOTIFICATIONS:
raise ValueError(f"Unknown notification type: {type_id}")
return NOTIFICATIONS[type_id]
How to check
A unit test sends a type missing from the catalogue and expects an error. A second test confirms every catalogue entry has a category, an urgency and at least one channel.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers notifications playbook: https://agentwranglers.se/playbook/notifications/channels-and-preferences/notification-catalogue.