Postmark's API transport rejects headers like Return-Path that Drupal adds
automatically. The SMTP relay is more permissive and avoids this class of
rejection entirely.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drupal core's symfony_mailer plugin reads system.mail.mailer_dsn directly
from settings.php — the mailer_transport module entity system is only a UI
layer and is not consulted when actually sending mail. Removed the
mailer_transport entity setup from the entrypoint and configured the DSN
correctly via $config overrides in settings.php instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- In _riverside_pt_rebuild(): proactively TRUNCATE the semaphore table
at the very start of every rebuild. This eliminates the common
'duplicate key value violates unique constraint "semaphore____pkey"'
errors for 'state:Drupal\Core\Cache\CacheCollector' and 'cron' that
appear in postgres logs.
- In entrypoint.sh: add TRUNCATE semaphore at strategic points
(right after site:install, before module enables, before/after
riverside:rebuild, before final drush cr). Wrapped with || true
so they never break the startup script.
- Added a note in CLAUDE.md under the rebuild section explaining
the errors and the quick manual fix.
These are harmless (Drupal's DbLockBackend usually recovers) but
very noisy in the container logs during the default full rebuild
path.
- Refactor AboutController to PageController to handle multiple static pages:
- /about
- /services/{slug} (diagnostic, sports, pre-post, neuro)
- /contact (new)
- New template riverside-pt-contact.html.twig:
- Contact details (address, phone, email)
- Office hours
- 'Send us a message' section directing to booking tool
- Multiple 'Make an Appointment' links back to /home#book-an-appointment
- Updated riverside_pt.routing.yml with riverside_pt.contact route
- Registered 'riverside_pt_contact' theme in riverside_pt.module
- Updated riverside_pt.install to skip legacy node creation for 'Contact' (and previously About/Services) to avoid alias conflicts
- Minor updates to home template, header handling, libraries (scroll support), and other controllers for consistency with page flows and email/booking features
All details pages (/about, /services/*, /contact) now include clear links back to 'Make an Appointment'.
- Add required email input (with autocomplete="email") to the booking
details form in the homepage Preact widget (rpt-booking.js).
Update EMPTY_FORM, submit payload, confirmedAppointment, and success
summary to include it. The form now collects: first/last name, email,
phone, comments.
- Update ScheduleController::storeSlot to extract/pass email in the
booking_request mail params (and require it for the full-contact path).
Log failures with details; return a structured error with a user-friendly
message instead of bare "mail_failed".
- riverside_pt_mail hook now includes the user's email in the notification
body (when provided).
- Dev improvements for mail:
- In DEBUG mode (default on localhost), force php_mail interface in
settings.php so the mailer uses the sendmail_path override.
- Dockerfile + entrypoint.sh now provide/install a fake-sendmail.sh
that prints the full email (To, Subject, headers, body from the
hook) to stderr (visible in `docker compose logs`) and always
succeeds (exit 0). This prevents "sh: 1: /usr/sbin/sendmail: not
found" and guarantees booking submissions never return the
"unable to send confirmation email" error in dev.
- In non-DEBUG, still uses symfony_mailer + Postmark as before.
- The fake is also baked into the image for consistency.
- JS error handling now prefers the server-provided 'message' from
the JSON error response (better UX for real mail failures).
- Update CLAUDE.md with the new email field + dev mail mocking behavior.
- New file: docker/php/fake-sendmail.sh (the mock).
This addresses the recent "mail_failed" issues while keeping production
email via Postmark.