Documentation Index
Fetch the complete documentation index at: https://grantmaster.dev/llms.txt
Use this file to discover all available pages before exploring further.
shared/email — API Reference
The shared/email module provides all outbound transactional email capability for GrantMaster, built on Postmark. It exposes a typed template catalogue, a raw send function, a Cloud Function bridge for admin operations, and convenience integration helpers so domain services never need to know Postmark implementation details.
Module Map
| File | Responsibility |
|---|
emailService.ts | Postmark client, sendEmail(), sendPostmarkTemplate(), template alias constants |
emailIntegration.ts | High-level integration helpers (invitation, password reset, journal, referral emails) |
postmarkAdminService.ts | Admin operations: list/delete suppressions, list messages, webhook management |
referralCreditEmails.ts | Referral programme transactional emails (award, gift card, launch welcome) |
emailService.ts
Environment Variables
| Variable | Purpose |
|---|
VITE_POSTMARK_SERVER_TOKEN | Postmark server API token |
VITE_POSTMARK_FROM_EMAIL | Sender address (default: noreply@grantmaster.ai) |
VITE_POSTMARK_FROM_NAME | Sender display name (default: GrantMaster) |
sendEmail()
Send a raw HTML/text email.
import { sendEmail } from '@/shared/email/emailService';
await sendEmail(
'user@example.com', // to (string or string[])
'Your report is ready', // subject
'<p>HTML body</p>', // htmlBody
'Plain text fallback', // textBody (optional — auto-stripped from HTML)
{
cc?: string | string[];
bcc?: string | string[];
replyTo?: string;
tag?: string; // Postmark message tagging
metadata?: Record<string, string>;
}
);
All emails are sent via the outbound message stream with open tracking and HTML-only link tracking enabled.
sendPostmarkTemplate()
Send a Postmark template email by alias.
import { sendPostmarkTemplate, POSTMARK_TEMPLATES } from '@/shared/email/emailService';
await sendPostmarkTemplate(
'user@example.com',
POSTMARK_TEMPLATES.JOURNAL_APPROVED,
{
user_name: 'Alice',
journal_period: 'March 2026',
app_url: 'https://app.grantmaster.ai',
},
{ tag: 'journal-approved' }
);
POSTMARK_TEMPLATES Catalogue
// User Management
ADMIN_INVITATION // new org admin setup
USER_INVITATION // team member invite
PASSWORD_RESET
// Journal Management
JOURNAL_APPROVED
JOURNAL_REJECTED
// Referral Credit System
REFERRAL_CREDIT_AWARDED
REFERRAL_CREDIT_ORG_APPLIED
REFERRAL_CONVERTED
REFERRAL_GIFT_CARD_DELIVERY
REFERRAL_LAUNCH_WELCOME
// Partnership Programme
PARTNER_INVITATION
PARTNER_INVITATION_REMINDER
PARTNER_INVITATION_FINAL_WARNING
// Future / Optional
WELCOME | TRIAL_EXPIRING | TRIAL_EXPIRED | INVOICE | RECEIPT
DUNNING | REFERRAL_INVITATION | SECURITY_ALERT | SCHEDULED_REPORT
emailIntegration.ts
High-level helpers that shield domain services from Postmark details. All helpers resolve the correct app URL and map domain data to Postmark template variables.
Admin Invitation
// Routes through a Firebase Cloud Function to avoid CORS issues
await sendAdminInvitationEmail(
adminEmail, adminName, organizationName, setupToken, organizationId
);
User Invitation
await sendUserInvitationEmail(
userEmail, userName, organizationName, role,
inviteToken, invitationId
);
// Generates: /accept-invitation?id={invitationId}&token={inviteToken}
Password Reset
await sendPasswordResetEmail(email, resetLink);
Journal Notifications
await sendJournalApprovedEmail(userEmail, userName, journalPeriod);
await sendJournalRejectedEmail(userEmail, userName, journalPeriod, rejectionReason);
Partner Invitations
await sendPartnerInvitationEmail(contactEmail, contactName, partnerName, inviteCode, orgName);
await sendPartnerInvitationReminderEmail(contactEmail, contactName, partnerName, inviteCode, daysLeft);
await sendPartnerInvitationFinalWarningEmail(contactEmail, contactName, partnerName, inviteCode);
postmarkAdminService.ts
Provides SuperAdmin-level Postmark account management. Exposes the operations surfaced in src/features/email/ for the Email Management UI panel.
Key Methods
import postmarkAdminService from '@/shared/email/postmarkAdminService';
// Suppressions (bounces, spam complaints, unsubscribes)
postmarkAdminService.getSuppressions(stream?, page?, pageSize?): Promise<SuppressionEntry[]>
postmarkAdminService.deleteSuppressions(addresses: string[]): Promise<DeletionResult>
// Message history
postmarkAdminService.getOutboundMessages(options?): Promise<OutboundMessage[]>
postmarkAdminService.getMessageDetails(messageId): Promise<MessageDetail>
// Webhooks
postmarkAdminService.getWebhooks(): Promise<Webhook[]>
postmarkAdminService.createWebhook(url, events): Promise<Webhook>
postmarkAdminService.deleteWebhook(webhookId): Promise<void>
// Stats
postmarkAdminService.getDeliveryStats(tag?, from?, to?): Promise<DeliveryStats>
postmarkAdminService.getBounceStats(): Promise<BounceStats>
// Templates
postmarkAdminService.listTemplates(): Promise<TemplateSummary[]>
postmarkAdminService.getTemplate(alias): Promise<PostmarkTemplate>
referralCreditEmails.ts
Transactional email helpers specific to the referral credit programme, called by ReferralCreditService.
import {
sendReferralCreditAwardedEmail,
sendReferralCreditOrgAppliedEmail,
sendReferralConvertedEmail,
sendReferralGiftCardEmail,
sendReferralLaunchWelcomeEmail,
} from '@/shared/email/referralCreditEmails';
// Credit earned notification
await sendReferralCreditAwardedEmail(userId, amount, totalBalance);
// Org discount applied notification
await sendReferralCreditOrgAppliedEmail(orgId, amount, discountPct);
// Referral converted (referrer notification)
await sendReferralConvertedEmail(referrerId, referredOrgName, creditsEarned);
// Gift card delivery confirmation
await sendReferralGiftCardEmail(recipientEmail, recipientName, giftCardType, amount);
// Programme launch email to all existing users
await sendReferralLaunchWelcomeEmail(userId);
EventBus Events
This module emits no EventBus events. Email sending is triggered directly by domain services and Cloud Functions; failures are logged to Sentry and propagated as thrown errors.
Note: There is no dead-letter queue or retry mechanism in the current client-side implementation. Firebase Cloud Functions handle delivery of the admin invitation email; all other templates are sent directly from the client via the Postmark SDK.
Callers
| Caller | Uses |
|---|
src/features/users/ | sendUserInvitationEmail(), sendPasswordResetEmail() |
src/features/journals/ | sendJournalApprovedEmail(), sendJournalRejectedEmail() |
src/features/partnerships/ | sendPartnerInvitationEmail() and reminders |
src/features/mission/ | sendReferralCreditAwardedEmail(), sendReferralGiftCardEmail() |
src/features/email/ | postmarkAdminService — Email Management UI |
| Firebase Cloud Functions | sendAdminInvitation callable (admin invite via Cloud Function) |