# Email delivery timing

Emails triggered by a completed action send immediately, before the response finishes:
- Patient invitations and password recovery links.
- Staff account setup and administrator-requested password resets (already synchronous).
- Booking confirmations, rescheduling and cancellation notices.
- Visit completion and physician-released result availability notices.

Patient account and appointment changes are committed before sending. No email is sent for a rolled-back action. SMTP failure does not roll back a saved appointment/account. The interface displays an email failure warning, not a sent/queued success message. "Sent" means the outgoing mail transport accepted the message; it cannot guarantee final inbox delivery.

Future reminders and calls with an explicit future delivery time remain scheduled. The existing reminder command and Laravel scheduler deliver them when due. CRM campaigns remain drafts until a campaign sending workflow is explicitly implemented; this change does not start sending campaigns.

Configure APP_URL and a real outgoing mail transport using MAIL_*. Log and array transports intentionally cannot claim an invitation or patient notification was sent. Portal account tokens are never added to a new job or logged in a mail body by the application. The legacy encrypted job handler remains available for invitations already queued before this change.

The patient notification outbox retains delivery audit status and a delivery_mode of immediate or scheduled. New immediate sends happen after transaction commit. Failed immediate emails are not picked up by the scheduled sender; staff must explicitly retry failed appointment notifications from Appointments. Three attempts are allowed, with the same ownership, state, release and recipient checks at each attempt. Invitations/password links can be requested again through their existing controls. Previous pending outbox entries keep their old scheduled mode so they can drain normally after upgrade.

The queue worker may still be required for document extraction and other background tasks. It is not required for new action emails. The Laravel scheduler is still required for future reminder emails. Automatic deployment settings are unchanged.

## Betelsoft SMTP configuration

The repository defaults use `mail.betelsoft-technologies.com`, port `465`, the `smtps` scheme (implicit TLS), and `mailer@betelsoft-technologies.com` as the username and sender. The sender display name is `Betelsoft HMS`. Each value can still be overridden with the existing `MAIL_*` environment variables. Organisation-specific Outlook delivery, when enabled, remains separate.

Set `MAIL_PASSWORD` in the deployed `.env` to the mailbox password. It is intentionally absent from source control and `.env.example`. A Yii-style `dsn` entry is not used by this Laravel application. Prefer the separate environment variables shown in `.env.example` so special characters in the username/password do not need URL encoding.

On an existing deployment, update the `MAIL_*` entries to match `.env.example`; repository defaults do not override existing server environment values. Remove an obsolete `MAIL_URL` or explicitly configure it for the intended server, because a configured mail URL takes precedence over individual SMTP options. Keep TLS certificate verification enabled.

After updating the deployed environment, run:

```sh
php artisan config:cache
php artisan queue:restart
```

Use the server’s configured PHP executable and application directory. Verify a test invitation or notification through the HMS before relying on production delivery; a successful SMTP submission does not prove inbox delivery.
