C4 — Notification UX Catalog
Scope: All notification affordances within the Ghasi Melmastoon frontend — in-app notifications (toasts, banners, badges, modals), push notifications (mobile + desktop OS), and real-time alerts (housekeeping board, arrivals, sync). Distinct from
notification-servicewhich handles out-of-app channels (email, SMS, WhatsApp).Source: Extracted and expanded from
05-frontend-workflows.mdsection 3.
1. Notification taxonomy
| Type | Channel | Persistence | Requires action | Surface(s) |
|---|---|---|---|---|
| Toast | In-app UI | Transient (auto-dismiss) | Sometimes | all |
| Inline banner | In-app UI | Until dismissed or state resolves | Sometimes | all |
| Badge | In-app nav icon | Until read | No | all |
| Modal alert | In-app UI | Until acted on | Yes | all |
| Notification center | In-app panel | Persistent list, 30 days | No | operator-desktop |
| OS push notification | OS / device | Until dismissed | No | consumer-mobile, staff-mobile, operator-desktop |
| Real-time board update | In-app (WebSocket / SSE) | Reflected in board immediately | No | operator-desktop |
| System health alert | In-app banner | Until state resolves | No | operator-desktop |
2. In-app notifications
2.1 Toast (see also C3 ER-01)
Four severity levels:
| Severity | Icon | Token | Auto-dismiss |
|---|---|---|---|
success | check-circle | --color-success | 4 s |
info | info | --color-info | 5 s |
warning | alert-triangle | --color-warning | 8 s |
error | x-circle | --color-error | Manual or 8 s with action |
Placement: Bottom-left (LTR), bottom-right (RTL), 16 px viewport margin. Stacks upward, max 3 visible.
Usage rules:
- Use for events that happened (booking confirmed, sync completed, task assigned).
- Do not use for states that need decision — use modal.
- Always include a trace ID in collapsed
<details>on error toasts for support.
Component: <Toast severity="success" message={t("booking.confirmed")} action={{ label: t("view"), onClick }} />
2.2 Inline banner (persistent)
Used when a surface is in a degraded or special state that persists until resolved.
Examples:
- "You're offline — working from local data" (offline mode)
- "This tenant is in read-only mode — pending setup completion"
- "Your plan expires in 3 days — renew to avoid disruption"
Dismissibility: dismissible for informational banners; non-dismissible for critical operational states.
2.3 Badge
Numeric badge on nav icons (notification bell, housekeeping board, sync icon).
Rules:
- Cap display at 99+.
- Reset to 0 when the user opens the relevant panel.
- Accessible:
aria-label="Notifications, 4 unread".
2.4 Notification center (operator desktop)
Persistent list of all in-app notifications for the current shift + last 7 days.
Categories: Booking, Housekeeping, Maintenance, AI suggestions, System, Sync.
Actions per notification: Mark read, View (deep-link to relevant entity), Archive.
Grouping: Group by category with collapse/expand. Within category, reverse-chronological.
3. Push notifications (mobile + desktop OS)
3.1 Consumer / Guest mobile
Triggered by notification-service; delivered via FCM (Android) / APNs (iOS).
| Trigger | Title | Body | Tap action |
|---|---|---|---|
| Booking confirmed | "Booking Confirmed 🎉" | "Your room at <PropertyName> is confirmed for <date>" | Open booking detail |
| Pre-arrival reminder (24h) | "Check-in Tomorrow" | "Your stay at <PropertyName> starts tomorrow. Anything to prepare?" | Open booking detail |
| Check-in available | "Ready to Check In?" | "Your room is ready early at <PropertyName>" | Open booking detail |
| Message from property | "<PropertyName>" | "<message preview>" | Open messaging thread |
Permission: Request at first booking confirmation (not on install). Soft prompt first; native prompt only after user agrees to soft prompt.
3.2 Staff mobile companion
| Trigger | Title | Body | Tap action |
|---|---|---|---|
| New task assigned | "New Task" | "Room <number> — <task type>" | Open task detail |
| Task reassigned | "Task Reassigned" | "Room <number> moved to you from <previous staff>" | Open task detail |
| Maintenance escalation | "Maintenance: Room <number>" | "<issue description>" | Open ticket |
3.3 Operator desktop (OS notification)
Electron uses the OS notification API (new Notification()) for out-of-focus alerts.
| Trigger | Title | Body |
|---|---|---|
| New reservation (online, while offline) | "New Booking Received" | "<GuestName>, <dates>, <room type>" |
| Sync conflict requiring action | "Sync Conflict" | "<N> items need your attention" |
| Lock key failure | "Key Issue Failed" | "Room <number> — fallback to mechanical key" |
Throttle: Max 1 OS notification per event category per 30 seconds to prevent spam.
4. Real-time board updates (operator desktop)
The housekeeping board, arrivals board, and reservation list subscribe to a real-time channel (Server-Sent Events or WebSocket from bff-backoffice-service).
Update patterns:
| Event | Visual update | Toast? |
|---|---|---|
Room status changes (dirty → cleaning → clean) | Pill color + icon update in-place (animated) | No (silent) |
| New arrival checked in | Row highlighted, then fades to normal | "Check-in: <Guest>" toast if off-screen |
| Reservation cancelled online | Row removed with slide-out animation | Warning toast |
| New walk-in arrival | New row added with slide-in animation | "New walk-in" toast |
| Sync conflict detected | Yellow conflict indicator on affected row | Yes — "Conflict detected" toast |
Offline fallback: If the real-time channel is lost, poll every 30 s and show "Live updates paused" badge.
5. AI suggestion notifications
AI suggestions surface as a distinct notification type within the operator desktop.
Anatomy:
- Suggestion card in the AI inbox panel (persistent).
- Shows: model name, confidence score (low/medium/high), suggested action, provenance footer.
- Actions: "Accept", "Reject", "Defer (ask me later)".
- Accepted suggestions are applied immediately and logged to the audit trail.
- Rejected suggestions are logged with an optional reason code.
- Auto-expire after 24 hours without action.
AI inbox badge: Shows count of pending suggestions. Never > 5 unread without the lead being prompted to review.
6. Notification accessibility requirements
- All
role="alert"components (<Toast>,<Banner>) are announced by screen readers immediately. role="status"for informational (non-error) updates.- Toast stack: focus is NOT moved to toasts (per WCAG 2.4.3). Focus remains on triggering element.
- Notification center panel: when opened, focus moves to the panel header; ESC closes and returns focus.
- Push notification deep-links must not require authentication re-entry if the app is in background (use token refresh).
7. Notification content guidelines
- Brevity: Toast body ≤ 80 characters. Push notification body ≤ 100 characters.
- Locale: All strings resolved through
@ghasi/ui-melmastoon/i18n; RTL strings test inps-AFandfa-AF. - No PII in push payloads sent to FCM/APNs — use
datapayload type; app fetches detail on tap. - Timing: Pre-arrival reminder sent at 10:00 local time of the property (not UTC midnight). Use
notification-servicescheduling.
8. Open Questions
- Should the AI inbox be a separate panel or integrated with the notification center? Current thinking: separate (different action patterns).
- Desktop OS notifications: should they be suppressed during "do not disturb" hours (e.g., 22:00–06:00 local)? Requires OS API detection.
- Should the notification center support tenant-level muting of specific notification types (e.g., turn off "Room cleaned" toasts for properties with > 50 rooms)?
References
../common/05-frontend-workflows.md§3 (notification UI patterns)C3-empty-loading-error-state-catalog.md§3 (ER-01 Toast)../../standards/ERROR_CODES.md../../08-ai-architecture.md