Skip to content

Notifications

Hardhat Flow sends SMS notifications for critical field events (via Twilio) and email notifications for workflow milestones (via Mailgun). All delivery is asynchronous — notifications are dispatched via Celery workers and never block the application request.


Email Notifications (Workflow Events)

Owners configure email notifications on the Settings page under the Email Notifications section. For each event you can turn notifications on or off and choose which roles receive the email. All tenant roles are available, including Owners.

Event When it fires
Bid submitted for approval A bid moves from New Bid to Awaiting PO
Bid approved — job created A bid is approved and a job is auto-created
Invoice created A completed job becomes an invoice
Payment recorded Any payment is posted to an invoice
Invoice paid in full Invoice balance reaches zero
Workflow complete A paid invoice is closed to Workflow Complete

Defaults

All six events are enabled with sensible default role lists (Owners, Accounting, Project Managers, and Supervisors depending on the event). The first time an Owner opens Email Notifications on Settings, Hardhat Flow loads these defaults automatically — you do not need to configure company profile fields first. Owners can narrow or expand recipients at any time.

Requirements

  • Recipients must have an email address on their user profile.
  • The user triggering the event is not emailed (reduces duplicate noise).
  • Email is best-effort — if Mailgun is not configured or the daily send cap is reached, the in-app action still succeeds.

User invitations

When an Owner adds a team member (or a new tenant Owner is provisioned), Hardhat Flow sends a welcome email with:

  • Who invited them and which company they are joining
  • A secure link to set their password (one-time Auth0 ticket)
  • Where to sign in after setup

This replaces the generic Auth0 password-reset email so the first touchpoint feels branded and informative.

Email notifications complement SMS.

SMS alerts (below) cover urgent field events like blocked jobs. Email notifications cover the bid-to-payment workflow so office staff stay informed without checking the app constantly.


Platform Admin: Access Request Alerts

When someone submits the public Request Access form, platform admins receive an email alert in addition to the confirmation email sent to the submitter. Alerts go to all active Platform Admin accounts. An optional PLATFORM_ADMIN_NOTIFY_EMAILS environment variable can add extra addresses.


Text Notification Preferences (Coming Soon)

The Settings page includes a Text Notifications section with grayed-out checkboxes for future SMS preference controls. SMS alerts still fire today using the default recipient rules in the table above. When text preferences are enabled, owners will be able to choose which events send SMS and which roles receive them.


SMS Trigger Events

Six events trigger automatic SMS notifications:

Event Who is Notified
Job blocked PM + Owner
Job unblocked PM
Bid rejected PM + Owner
Bid cancelled PM + Supervisor
Job cancelled PM + Supervisor
Priority flag set (bid or job) PM + Supervisor

Event Details

Job Blocked When blocked is set to true on a job, the assigned PM and Owner both receive an SMS. The message includes the job ID and the blocked_reason.

Job Unblocked When blocked is cleared on a job, the PM receives an SMS confirming the block has been resolved.

Bid Rejected When an Owner sets a bid to Bid Rejected, the assigned PM and all Owner-role users for the tenant are notified so they can follow up with the client or revise the bid.

Bid Cancelled When an Owner cancels a bid, both the PM and the assigned Supervisor are notified.

Job Cancelled When an Owner cancels a job, both the PM and the assigned Supervisor are notified.

Priority Flag Set When priority is set to true on either a bid or a job, the assigned PM and Supervisor receive an SMS alerting them to the urgency.

Priority flag notifications fire when the flag is set (toggled from false to true). Clearing the flag does not trigger a notification.


Phone Number Requirement

SMS notifications require a phone number on the recipient's user record (User.phone).

  • Phone is a required field for any user who should receive SMS notifications.
  • It is strongly recommended to collect phone numbers for all Owner, PM, and Supervisor accounts.
  • Badge Workers and Accounting users are not recipients of any SMS notifications.

What Happens When No Phone is on File

If a notification is triggered for a user who has no phone number recorded:

  1. The SMS is silently skipped for that user.
  2. A warning is logged via structlog with the user ID, event type, and entity ID.
  3. All other recipients (if any) still receive their notifications normally.

There is no in-app notification or error shown to the triggering user if an SMS cannot be sent due to a missing phone number. Monitor logs if SMS delivery is suspected to be missing.


Per-Tenant Outbound Number

Each tenant has its own dedicated outbound Twilio phone number. This number is stored in CompanySettings.twilio_phone_number.

  • All SMS sent from a tenant originate from that tenant's configured number.
  • Recipients see a consistent, recognizable number for each company they work with.
  • The outbound number is configured by the Owner or Platform Admin in CompanySettings.

Using a per-tenant number ensures clients and staff can recognize and distinguish SMS messages by company.


Async Delivery via Celery

All SMS notifications are delivered asynchronously:

  1. The application event occurs (e.g. job blocked).
  2. A Celery task is enqueued immediately.
  3. A Celery worker picks up the task and calls the Twilio API.
  4. The API response (success or failure) is logged.

The application request that triggered the event does not wait for SMS delivery. If Celery is down or Twilio returns an error, the in-app action still completes successfully. SMS failures are surfaced in logs only.

SMS delivery is best-effort. If Celery workers are not running, notifications will be queued but not delivered until workers come back online.


Message Format

All SMS messages follow this format:

[Hardhat Flow] <Entity>: <identifier> — <what happened>.

Event Example Message
Job blocked [Hardhat Flow] Job: 123 Main St — marked BLOCKED. Log in to view details.
Job unblocked [Hardhat Flow] Job: 123 Main St — unblocked.
Bid rejected [Hardhat Flow] Bid: Acme Corp / 123 Main St — rejected.
Bid cancelled [Hardhat Flow] Bid: Acme Corp / 123 Main St — cancelled.
Job cancelled [Hardhat Flow] Job: 123 Main St — cancelled.
Priority set (bid) [Hardhat Flow] Bid: Acme Corp / 123 Main St — marked HIGH PRIORITY.
Priority set (job) [Hardhat Flow] Job: 123 Main St — marked HIGH PRIORITY.

The entity identifier for jobs is the job's associated bid location. For bids, it is the client name followed by the bid location.