3 Notifications
Hardik edited this page 2026-06-19 14:06:07 +05:30

Notifications

The portal notifies stakeholders at every PO state transition — by email and via an in-app notification bell. Email dispatch is centralised in lib/notifier.ts and called only from state-machine side-effects, never directly from UI handlers. Every notification is also persisted to the Notification table for audit, in both prod and dev.

Email: prod vs dev

  • Production — templates in emails/ (React Email), rendered server-side with @react-email/render and sent via the Resend SDK.
  • Development — the recipient, subject, and body are printed to the terminal (lines prefixed 📧 [DEV EMAIL]); no Resend key required.

The switch is automatic on NODE_ENV. Preview templates live with pnpm email:preview (http://localhost:3001).

Email templates (emails/)

Template Sent on
po-submitted.tsx PO submitted → Manager
po-approved.tsx PO approved → Submitter + Accounts
po-rejected.tsx PO rejected → Submitter (with reason)
edits-requested.tsx Edits requested → Submitter (with note)
vendor-id-needed.tsx Vendor ID requested → Submitter
payment-processed.tsx Payment sent / paid → Submitter + Manager
receipt-confirmed.tsx Receipt confirmed → Manager + Accounts
layout.tsx Shared email shell

Event → recipient matrix

Driven by the side-effects declared per transition in the state machine:

Event Side-effect Notified
Submit / resubmit EMAIL_MANAGER Manager(s)
Vendor ID requested EMAIL_SUBMITTER Submitter
Vendor ID provided EMAIL_MANAGER Manager
Edits requested EMAIL_SUBMITTER Submitter (with note)
Approve / Approve+Note EMAIL_SUBMITTER, EMAIL_ACCOUNTS Submitter + Accounts
Reject EMAIL_SUBMITTER Submitter (with reason)
Payment sent EMAIL_SUBMITTER_AND_MANAGER Submitter + Manager
Marked paid EMAIL_SUBMITTER, EMAIL_MANAGER Submitter + Manager
Receipt confirmed (full) EMAIL_MANAGER, EMAIL_ACCOUNTS Manager + Accounts

Partial-payment / partial-receipt transitions carry no email side-effects; they update state silently until the full settlement event fires.

In-app notification bell

Every signed-in user sees a bell in the header with an unread count badge. The dropdown lists recent items; each may carry a link to the relevant PO. Backed by the Notification model (isRead, link fields) and served by:

  • /api/notifications (GET) — the current user's notifications
  • /api/notifications/read (POST) — mark notifications read

Report Issue

Separate from PO notifications: any signed-in user can file a bug from the header via the Report Issue button (components/layout/report-issue-button.tsxreport-issue-actions.tslib/forgejo.ts), which creates a Forgejo issue labelled portal. That kicks off the Issue-to-Deploy Pipeline. Requires FORGEJO_URL, FORGEJO_REPO, FORGEJO_TOKEN (token scope write:issue).