Notifications
[notifications] [admin] [portal]
In-app notifications for customers: maintenance notices, ticket replies, general updates. Optionally also as a mail.
Who it's for
- Admin creates + manages notifications
- Customer sees them in the portal header (bell icon with counter)
Notification types
- manual : the admin writes their own notification (default case)
- maintenance : system-generated when maintenance mode is enabled (🔧 icon)
- ticket_reply : auto-generated when the admin replies to a ticket (💬 icon)
- package_change : when the customer's package changes
- invoice : Stripe-related notices (Phase 2)
Step by step : Admin
1. Open the notifications overview
Sidebar → Notifications.
2. Create a new notification
+ New notification:
- Audience: all customers / specific packages / individual customers
- Title + message
- Priority: low / medium / high
- Validity period: starts_at + ends_at (optional, otherwise from now, unlimited)
- Also send by mail: checkbox
3. Publish
Click Publish. Customers see the notification:
- Immediately in the portal (the bell icon in the header shows a counter)
- As a mail if the send toggle was active
4. Manage
- Archive : the notification is no longer active (disappears from the portal bell), but stays in the archive
- Edit : adjustable before publishing; afterwards only limited (consistency)
What customers see
Portal header
Bell icon with a counter (= unread notifications). Clicking opens a drawer with the list.
Notification item
- Icon (type-dependent: 💬 ticket_reply, 🔧 maintenance, ✅ package_change, 🔔 manual, 📄 invoice)
- Title + message
- Timestamp
- Read button (marks as read, counter drops)
- Delete button (✕) (persistent : dismissed per customer)
Per-customer dismiss
When a customer dismisses a notification (✕), the notification ID is stored in their dismissed_notifications array (migration 048). Other customers still see it.
Frequently asked questions
What does a ticket reply look like as a notification?
Synthetic ID format: ticket_<ticket_id> (not <message_id>). Per ticket, only the NEWEST admin reply as a notification, otherwise every reply would create a new notification. When the customer opens the ticket, the notification is automatically marked as read.
Can I send notifications only to certain customers? Yes, the audience filter allows:
- All (default)
- Per package (e.g. only customers on a specific package)
- Individual customers (multi-select)
Are archived notifications deleted?
No. is_archived=true only hides them from the portal bell. Still visible in the admin archive.
A mail is not being sent, what to do?
- The Resend domain
licensio.iomust be verified in the Resend dashboard - ENV
RESEND_API_KEYmust be correct - Audience not empty (customers without an active mail get nothing)
As an admin, I see a notification "New ticket", where does it come from?
GDPR separation: admin notifications have audience='admin' and are not visible to customers. They are system-generated for provider admins (e.g. a new ticket came in).