Notifications¶
Hardhat Flow sends email notifications for workflow milestones (via Mailgun). Owners configure those on Settings → Email Notifications. SMS for urgent field events exists in the product only when Twilio and a tenant from-number are provisioned; Settings → Text Notifications is a preview of future preference controls and is not configurable yet. All delivery is asynchronous via Celery and never blocks the request.
Developers adding a new email or text alert: see Adding Email and SMS Notifications.
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 who triggers the event is emailed if their role is in the notified list. A solo Owner who runs the whole bid-to-payment workflow themselves still receives every notification they enabled.
- Email is best-effort — if Mailgun is not configured or the daily send cap is reached, the in-app action still succeeds.
- When an event has no recipients (disabled, or no active user in a notified role), the skip is recorded in the admin Email log rather than failing silently.
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 is the channel you can configure today.
Workflow emails (below) cover bid-to-payment milestones. Text Notifications on Settings are coming soon. SMS for field events only sends if your company has SMS provisioned.
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. Those options are not email defaults and cannot be enabled yet. SMS for the six field events below only sends if Twilio credentials and a tenant from-number are configured. When text preferences ship, owners will choose events and roles.
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 all Owner-role users receive an SMS. The message includes the job location and directs them to log in for details.
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:
- The SMS is silently skipped for that user.
- A warning is logged via structlog with the user ID, event type, and entity ID.
- 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 and email notifications are delivered asynchronously:
- The application event occurs (e.g. job blocked, bid submitted).
- A Celery task is enqueued immediately.
- A Celery worker picks up the task and calls Twilio (SMS) or Mailgun (email).
- The API response (success or failure) is logged.
The application request that triggered the event does not wait for delivery. If Celery is down or the provider returns an error, the in-app action still completes successfully. Delivery failures are surfaced in logs only.
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.