Email & notification matrix
Every notification the platform emits, who it goes to, and which channels carry it. Today: in-app + WhatsApp (with opt-in) are live. Email is gated on SMTP credentials — when those are added, the preferences below activate per tenant.
Always emitted; persisted on the Notification model. Read in /me/inbox.
Mirrors a subset of events. Requires Meta Cloud API creds + per-tenant template approval.
UI + storage live. Awaiting SMTP creds (SendGrid / SES / Resend) before delivery is wired.
Employee-facing events
| Event | Kind | Recipient | Trigger | Source |
|---|---|---|---|---|
| Payslip ready | PAYSLIP | Employee | After payroll generated/imported | compensation/payroll-generate.service.ts, payslips/payslip-import.service.ts |
| Leave decision | LEAVE | Employee | HR approves / rejects leave | leaves/leaves.service.ts |
| Leave recorded by HR | LEAVE | Employee | HR adds leave on behalf of employee | leaves/leaves.service.ts |
| Team on leave | LEAVE | Manager | Direct report's leave is approved | leaves/leaves.service.ts |
| Document decision | SYSTEM | Employee | HR approves or rejects an uploaded document | employee-documents/employee-documents.service.ts |
| Regularisation decision | ATTENDANCE | Employee | HR approves/rejects an attendance regularisation | attendance/regularisation.service.ts |
| Absent today | ATTENDANCE | Employee | No punch detected by 10:30 local time | attendance/processor.service.ts |
| Late-arrival violation | ATTENDANCE | Employee | Punch breaches the policy's grace window | attendance/processor.service.ts |
| Review assigned | SYSTEM | Reviewer + Subject | Performance cycle review participants set | performance/performance.service.ts |
| 1:1 scheduled | SYSTEM | Both attendees | Manager / direct-report 1:1 created | performance/performance.service.ts |
| Grievance status update | GRIEVANCE | Raiser | HR updates grievance status | grievances/grievances.service.ts |
HR-admin / manager-facing events
| Event | Kind | Recipient | Trigger | Source |
|---|---|---|---|---|
| New grievance | GRIEVANCE | HR_ADMIN | Employee raises grievance | grievances/grievances.service.ts |
| Document awaiting verification | SYSTEM | HR_ADMIN | Employee uploads a document needing approval | employee-documents/employee-documents.service.ts |
| Attendance regularisation request | ATTENDANCE | Manager + HR | Employee requests punch correction | attendance/regularisation.service.ts |
| Overtime request | ATTENDANCE | Manager + HR | Employee submits OT for approval | attendance/overtime-request.service.ts |
| Short permission request | ATTENDANCE | Manager + HR | Employee asks for short permission | attendance/short-permission.service.ts |
| New applicant | SYSTEM | HR_ADMIN | Public careers page receives an application | ats/ats.service.ts |
POSH (sensitive flow)
| Event | Kind | Recipient | Trigger | Source |
|---|---|---|---|---|
| POSH complaint filed | SYSTEM | ICC members | Confidential — only Internal Committee + raiser see content | posh/posh.service.ts |
| POSH complaint outcome | SYSTEM | Raiser | ICC closes the inquiry | posh/posh.service.ts |
Platform-owner-facing events (you / your team)
| Event | Kind | Recipient | Trigger | Source |
|---|---|---|---|---|
| New tenant signup | SYSTEM | Platform Administrator | Self-serve signup completes (trial or paid) | subscriptions/provisioning.service.ts |
| Subscription event | SYSTEM | Tenant owner | Razorpay webhook: charged / paused / cancelled / halted | subscriptions/subscriptions.service.ts |
| Daily backup completed | SYSTEM | Platform Administrator | Nightly DB backup finishes (manifest, row counts) | backup/backup.service.ts |
| Support ticket raised | SYSTEM | Platform Administrator | Tenant opens a /me/support ticket | platform-support/platform-support.service.ts |
Channel rules
- In-app always fires — no toggle. Stored on the Notification model, polled by the bell badge every 30 s.
- WhatsApp fires only if (a) module enabled per tenant, (b) Meta Cloud API creds present, (c)
User.whatsappOptIn=true, (d) template approved for that tenant. Current state: shipped in mock mode — see /docs/whatsapp. - Email fires only when (a) SMTP creds present (pending), (b) tenant has opted that event on for that role, (c) recipient hasn't unsubscribed.
How to configure (per tenant)
Once SMTP is live, owners and HR admins manage their tenant's preferences at /admin/notifications. They get a grid of (event × role × channel) checkboxes. Defaults reflect the recommended setup: payslips emailed to employees, decisions to raisers, escalations to admins, backups to Platform Administrator.
Platform-level events (new signup, subscription, daily backup) are configured separately under/admin/platform-support— those go to hr@staffixhr.com by default and aren't exposed per tenant.
Email volume estimate (per tenant, per month)
For a typical 50-employee tenant with default settings:
- Payslip ready: ~50 (one per employee per month)
- Leave decisions: ~25 (assuming 0.5 leaves/employee/month)
- Document approvals: ~10-15 (uploads + reviews)
- Attendance regularisations + OT + permissions: ~30-50 (varies wildly by sector)
- HR-admin escalations: ~10-20
- Rough total: 125-175 emails/month per 50-emp tenant
At ~1,000 emails/month across 5-10 tenants, you sit comfortably in the free tier of SendGrid (3 K free/mo) or Resend (3 K free/mo). Switch to paid (~$15/mo) when you cross 10 K/mo.
Implementation status
| In-app delivery | ✅ Live — all events |
| WhatsApp delivery | 🟡 Live (mock) — needs Meta credentials + template approval |
| Email matrix UI | ✅ Built — /admin/notifications (preferences saveable) |
| Email storage of prefs | ✅ NotificationPreference table |
| Email actual sending | ❌ Not wired — needs SMTP creds (SendGrid/SES/Resend) |
| Email retry/bounce | ❌ Pending — will be added with the provider |