#FE: Notifications & mail screens (from backend Phase 11)
Frontend spec for backend Phase 11 — Notification & Mail — requirements complete 2026-10-05, not built. V8 requirement One system now sends every email and notification in Central: account, billing, plan, organization, server and app. It also answers D-17, the oldest gap on this site: where server alerts come from.
i18n namespaces: notifications.*, notifications.events.*, notifications.channels.*, notifications.admin.*, mail.*.
#A. Admin: mail & logs
| # | Feature | Screen / control | Rules from the backend doc | Frontend notes |
|---|---|---|---|---|
| 11.1 | SMTP settings | Admin mail page | Set by the admin, stored in the database (as V7), password encrypted. Send test email | A normal settings form plus a Send test button that reports the real result inline — "sent" or the actual failure — because a silent failure here means every email in the product is broken. The password field is write-only: show a masked hint, never the value |
| 11.2 | Background sending | Nothing to build | All emails and notifications go out in the background, with a few retries | Nothing is ever sent while the user waits, so no screen may show "email sent" as the result of a save. Say "we'll email you" instead of claiming delivery |
| 11.3 | Email layout & texts | Nothing to build | One shared layout. Layout and texts are fixed in the code (translation keys) and are not editable from the admin panel for now. Added 2026-10-05: every email also has a plain-text version and a mobile-friendly layout (fits a phone, big buttons) | Good news for the frontend's long-standing worry about English-only backend messages (Q8): the backend is building emails on translation keys from the start. Sharpened on 2026-10-05: "admin editing later" became an explicit no admin editor, so the admin mail screen is settings and logs only — don't leave room for a template editor in its layout |
| 11.4 | Sent log | Admin log page | Every email and notification is logged: event, user, channel, sent / failed, error. The admin can search it | A plain searchable table with filters for event, channel and status, and the error text on a failed row. This is the screen support will actually live in, so the row must say what was sent, to whom, by which channel and why it failed |
#B. The event list
| # | Feature | What it means for the frontend |
|---|---|---|
| 11.5 | One event list — key, group (account, billing, plan, organization, server, app…), default channels, and required or not (security and billing emails can't be turned off). Each phase adds its own events | The user never sees this catalogue — they see the ten fixed groups (§C). What matters is that new events must land in an existing group automatically, so nothing hard-codes which events a group contains. A required group renders as locked with a reason ("security emails are always sent"), not a disabled checkbox with no explanation |
| 11.6 | One sender — each phase says "send event X"; the system decides email / in-app / channel from the event list and the user's choices | Nothing to build, but it fixes a question the frontend had: there is one place that decides delivery, so the in-app bell and the email always agree. The frontend never decides whether something should also have been emailed |
#C. User: notification settings
| # | Feature | Screen / control | Rules | Frontend notes |
|---|---|---|---|---|
| 11.7 | Channels, per server | The server's own Notifications screen | The user attaches channels to a server (as V7) and ticks event groups per attached channel: Alerts · Backups · Apps & deploys · SSL & domains · Databases · Server changes. All ticked by default | A small screen, not a matrix: the attached channels listed, each with six tick-boxes. Because everything is on by default, the screen's job is turning things off — so show it as "you get everything; untick what you don't want", and never present an empty state that implies nothing is set. Where this screen lives is not settled on the frontend side: the server menu order is fixed (D-37) |
| 11.7 | Channels, account level | Account → Notification settings | Account events (billing, plan, organization, security) are not tied to a server, so their channels are chosen once | A separate, simpler screen from the per-server one: four groups against the user's channels. Three of the four are required and show as locked (11.5, 11.19) |
| 11.8 | Account events to channels | Account-level screen | New in V8: account, billing and plan events can go to channels too — V7 only sent server events there | Worth saying on the screen, because a V7 user will expect Telegram to be server-only |
| 11.9 | Channel failure | Status on the channel row | A channel that keeps failing (e.g. a wrong Slack URL) is marked "not working" and the user is told | A clear state on the channel, with the last error and Send test to re-check — the same pattern the integrations screens use for "Needs new token". It has to appear in both places a channel is shown (the account list and every server it is attached to), plus the bell, or the user never learns their alerts stopped arriving |
| 11.10 | Unsubscribe link | Nothing to build here | Informative emails carry an unsubscribe link, tied to the email preferences (3.5) | The link lands on the existing email-preferences screen, which must handle arriving from an email while logged out — so it needs a signed-link state that works without a session, or a login prompt that returns to it |
#Event groups (final, from the backend)
The backend published the complete group list on 2026-10-05, so the frontend renders exactly these — six at server level, four at account level. The Includes column is the backend's own wording, kept here because it tells the frontend which screens will raise a notification.
| Group | Level | Includes |
|---|---|---|
| Alerts | Server | CPU, memory, disk, load too high / back to normal; service down / back up; server not reachable / back online |
| Backups | Server | Backup completed, failed, deleted; restore done / failed |
| Apps & deploys | Server | App created, updated, deleted, enabled / disabled, cloned; staging created / pushed; deploy done / failed (manual and auto on Git push); workers; app users / SSH access; PHP settings, maintenance mode, basic auth, app firewall / bot blocker; environment (.env) changed |
| SSL & domains | Server | Domain added / removed / primary changed; SSL issued, failed, renew failed, expiring soon, removed; force HTTPS |
| Databases | Server | Database created / deleted / imported; database user created / updated / deleted; password reset |
| Server changes | Server | Server created / deleted / restarted / IP changed; firewall rules; Fail2ban; cron jobs (incl. failed); PHP / Node versions and extensions; services restarted; system users and SSH keys; swap; disk cleaner; panel update done / failed |
| Security (required) | Account | New login (new device / IP), password changed, email changed, 2FA on / off, backup codes, IP whitelist, API token created |
| Billing (required) | Account | Payment received, receipt, credit added, charge created, auto-recharge done / failed, low credit, card changed, managed-server credit / power-off / deletion |
| Plan (required) | Account | Expires soon, renewed, expired, trial expired, locked soon / locked, cancel / resume, price or feature change notice |
| Organization | Account | Invitation, joined, member / role changes, share server, ownership transfer, integrations connected / disconnected |
Two things to read off that table. The group names are fixed and few, so they can be translated and laid out properly instead of rendered from an open-ended list — but the events inside them still come from the backend's event list (11.5), so a new event in a later phase lands in an existing group with no frontend change. And the required groups are account level only: every server group can be switched off, which means a user can silence their own alerts — so the per-server screen should say plainly what unticking Alerts costs them.
#D. Server & app events — what Central reports and what it polls
| # | Feature | Rules | Frontend notes |
|---|---|---|---|
| 11.11 | Actions done through Central | Every server / app create, update or delete made through Central is sent right after OSS answers — success or failed. Long actions (deploy, restore, SSL request, add-on runs): OSS answers "started", then a Central background job follows the status and sends when it finishes. Actions done directly in the OSS panel are not sent — the panel shows them. No OSS changes, no activity log | The important half is the one that is not covered: a user who works in the server's own panel gets no notification, so no screen may imply the feed is a complete history of the server. It also fits the progress patterns already in this spec — a long action's notification arrives when it finishes, which is exactly why "safe to leave this page" is the right promise on the create-server and deploy screens |
| 11.12 | Scheduled checks | For what OSS does on its own, Central jobs read existing OSS APIs, and how often is an admin setting: backups (failed / done, every 15–30 min), SSL (renew failed, expiring soon, daily), auto-deploy on Git push (latest deployment, every few minutes), metrics (every 5 min), services (down / back up), health (unreachable / back online). Replaces V7's own server monitors | So a notification for something the server did is as fresh as its own schedule — up to half an hour for a backup, a day for SSL. Never show such an event with a relative "just now"; use the time the API gives. And because the frequency is an admin setting, no screen may state the interval |
| 11.13 | Server alerts — limits set by the user, per server | Every 5 minutes a Central job reads each server's live metrics from OSS (CPU, memory, disk, load 1 / 5 / 15 min) and compares them with that server's own alert limits. The user sets the limits per server (as V7). Defaults: CPU 100%, memory 80%, disk 90%, load 5 min = cores + 0.3, load 15 min = cores + 0.1. Over the limit → email + notification including the top processes from OSS. Load alerts at most once a day per server | Corrected 10:19: these limits are the user's, per server — not an admin setting, as this page first said. So there is a per-server alert-limits screen to build (five numbers, with Reset to defaults), and the defaults depend on the server's core count, which means the form must show the computed default rather than a hard-coded number. The alert itself carries top processes, so the notification needs room for a small table — and that is a real design detail, not a one-line message |
| 11.14 | No repeats | The same alert is sent once until it is fixed, then a "back to normal" message | So a problem is a state, not a stream: the bell must not fill up with the same disk warning, and a resolved alert needs a visibly different row. This is the rule the "Needs attention" screen depends on to stay accurate |
| 11.20 | Send check (the pipeline) | New 2026-10-05. For every event, in order: find it in the event list → work out who gets it (the account owner, members with access to that server / organization, and the user who did the action) → skip if already sent (same event, or the same alert still open) → apply user choices (email preferences, channels per event and per server), with required events — security, billing, plan — always sent by email → skip channels marked "not working" → send in the background → write the sent log, retrying failures | Two things the frontend must respect. First, the in-app list is permission-scoped: two members of one organization legitimately see different notifications, so never cache the list across users or assume a shared feed. Second, a required event is sent by email whatever the settings say — so the matrix must show those rows as locked, which is the same rule as 11.5 and 11.19 seen from the delivery side |
#E. Other emails & announcements
| # | Feature | Screen / control | Rules | Frontend notes |
|---|---|---|---|---|
| 11.15 | Credentials emails | Nothing to build here — but it changes a screen requirement | Rewritten 2026-10-05. When server / database / app credentials are created, the email says "your credentials are ready — view them in the panel". No passwords in emails — V7 sent them in plain text | A real security improvement, and the frontend inherits the consequence: the email is now a pointer, so the place it points to has to work. Wherever credentials are created, the panel must show them on demand (reveal / copy) rather than assume the user already has them by email. It also means a generated password shown once at creation needs a way to retrieve or reset it later, or the email's promise is empty |
| 11.19 | Security emails | Locked rows on the account-level screen | New 2026-10-05: password changed, new login from a new device / IP, and API token created. Required — can't be turned off | They sit inside the Security group (§C), which is one of the three required account groups — so they show as locked with the reason rather than a dead checkbox. They line up with screens that already exist: the password change (3.4), the new-IP approval (2.8) and the migrated API token (3.13) — so nothing new to build, but the settings screen must not imply they are optional |
| 11.21 | Email clean-up | Changes one screen and confirms the rest | New 2026-10-05. No secrets in emails: 2FA backup codes are shown once on screen (+ download) and the email only says "backup codes generated"; "DB root password changed" says what changed without the old or new password. One email per family: managed-server credit emails go from 10 to about 4 (trial yes/no and days left inside), plan reminders become one "expires soon" + one "expired", and the auto-recharge setting + card-updated emails merge into one "Billing settings changed". The old invoice "Payment received" is dropped (the wallet's "Payment successful" stays) | The one real screen change: Account → Security must drop its "email backup codes" action — this spec and the frontend doc both offered it, and it would now send a secret by email. Codes are shown once with copy and download, so the dialog has to make "save these now" unmistakable. The merged families are a backend concern, but the matching in-app banners should merge the same way — one managed-server banner carrying the days left, not four (see FE: Billing screens) |
| 11.22 | Subject style | Nothing to build | New 2026-10-05: every subject follows one style and names the server or app when there is one, e.g. [ServerAvatar] web-01: Disk usage 92% | Backend-only, but it confirms a rule this spec already applies to screens: a notification names the server it is about. Worth matching in the in-app list so the email and the bell read the same way |
| 11.23 | New emails in V8 | Nothing to build | New 2026-10-05: Account deleted · Logged out of all devices (3.16) · Plan changed — upgrade / downgrade with credit back and amount paid (7.7) · Plan price / feature change notice (7.17 / 7.18) · Redeem code applied (7.23) · Notification channel not working (11.9) · Admin announcement (11.17) | Every one of these has a screen that already exists in this spec, so nothing new is needed — but it is a useful check that each of those screens leaves the user with a matching record. The "channel not working" email pairs with the in-app state on 11.9, and "logged out of all devices" pairs with the session list in 3.16 |
| 11.16 | Unverified-email reminder | Nothing to build | Daily, as V7 | The matching in-app state already exists: the verify-email banner (2.2) |
| 11.17 | Admin announcements | Admin announcement page + the user's bell | The admin sends a message to all or chosen users, by email and in-app (e.g. maintenance notices) | Admin side: recipients, subject, message, preview, send, with a confirm that states how many people will receive it. User side: an announcement is a normal in-app notification but has no resource to link to, so the bell must render a plain message without a dead "view" link |
| 11.18 | Mautic | Nothing to build | New users and their plan info are synced to Mautic (marketing), as V7 | Backend-only. No consent screen is specified Open question |
#Who gets a notification — reversed back to V7 (owner only)
What it means for the screens, now that it is V7 behaviour again:
- The bell is effectively an owner feature for everything to do with servers, apps and the organization. A member can open the notifications page and legitimately see nothing, so the empty state must not read like a failure.
- The per-server channel screen (11.7) is still the owner's tool. A member attaching a channel would never receive anything through it, so that screen belongs to whoever receives the events.
- Account events still reach each user individually, so a member does get their own security, billing and plan messages.
#The V7 email map — all 90 emails accounted for
On 2026-10-05 the backend published a complete map of V7's 90 emails, marking each one kept, changed, merged, moved to a later phase, or dropped. It is worth reading for two reasons that are frontend concerns, not backend ones.
It shows which product areas are still coming. Emails moved to "their own phase" tell us where screens do not exist yet: Premium Care, managed-hosting resize, support tickets, affiliate / referral credit, Log Monitoring (V7 InsightHub) and the Reseller panel / White label. Our Phases page already treats those as later work, so the map confirms it rather than changing it.
It confirms nothing a V7 user relies on disappears silently. Everything dropped is either an unused V7 job (self-managed server reminders, follow-up emails that were never sent) or part of the old invoice-billing flow that Phase 6 replaced with receipts. Three families changed rather than vanished, and all three are screen matters: credentials emails now point into the panel (11.15), backup codes are shown once on screen (11.21), and the "DB root password changed" email no longer carries the password.
Also decided and worth recording because they are features we will not build: no flood limit, no digest email, and no reply-to support address. So there is no "daily summary" preference to design, and no screen should offer one. With no flood limit, the only thing keeping the bell readable is the send-once rule (11.14) — which makes that rule load-bearing rather than a nicety.
#Existing users
| Case | Rule from the backend doc | What the screens must handle |
|---|---|---|
| Channels | Notification channels and their per-server links carry over | The matrix opens pre-filled, including per-server choices — never show a migrated user an empty settings page implying nothing is set |
| Email preferences | Carry over | Pre-filled (3.5) |
| In-app notifications | Carry over | The list can contain older entries whose event key may not be in the current catalogue, so render an unknown event by its stored text rather than failing |
| Every existing email | Keeps the same purpose and trigger | Nothing to design, but it means the event list must already contain a V7 equivalent for each — worth checking against the catalogue when it is published |
| White label SMTP | Comes later, with the White label phase | Not in this phase |
| Emails that stop in V8 | Added 2026-10-05: dead or unused V7 emails are not sent any more — old invoice-billing emails (monthly invoice, payment due, deactivate organization, inactive service), the wallet negative-credit email, self-managed server reminders, and the follow-up emails that 11.15 used to describe | Useful confirmation rather than new work. Two of these close loops on this site: the wallet negative-credit email matches the wallet track Pair 1 removed from Phase 6, and "invoice" emails are gone alongside Phase 6 saying receipt, not invoice. So no screen should offer to resend an invoice email, and nothing should promise a follow-up |
#What this phase answers
| Was open | Now |
|---|---|
| D-17 Where do server alerts come from, given OSS has no alerts API? | Answered (11.12, 11.13): Central polls each server's OSS panel for live metrics, services and health, and raises its own alerts against limits the user sets per server (V7 defaults, some based on the core count), sending each one once with a "back to normal" when fixed. OSS does not push. This is option (a) from the recommendation, so the [!MISSING] warning on Notifications is closed |
| How does the frontend know which notification types exist? | From the event list (11.5), the same pattern as the plan feature list — so the settings screen is generic and later phases add events without touching it |
| Will backend messages be translatable? | Partly (11.3): email texts use translation keys from the start. This is progress on Q8, though the doc still doesn't say that API error messages carry a type + params |
#Still open
Per-server settings at scaleanswered 2026-10-05 10:47: channels are attached per server with six group tick-boxes, all on by default, and account events are chosen once at account level — no matrix anywhere. What remains is where that per-server screen sits: the server menu order is fixed, so it needs a decision (D-37). The per-server alert limits (11.13) are still only described as a rule, not a screen, and they plausibly belong on the same screen.- Nothing covers work done in the OSS panel (11.11). It is a deliberate decision, not a gap, but it means the notification feed is not a full history of a server — the screens must not suggest otherwise.
- Freshness — the check intervals are now published (metrics every 5 min, backups every 15–30 min, SSL daily, deploys every few minutes) but how often is an admin setting (11.12), so no screen may state an interval or show such an event as "just now".
- Mautic consent (11.18) — user data is synced to a marketing tool with no consent or opt-out screen specified.
- Q8 is not fully answered — translated emails are covered, translated API errors still are not.