Add tests for conversational header generation, HTML rendering
with p-tag wrapping, plain-text conversion, footer handling,
and conditional action links. Update mention test fixtures
with Project field.
Add conversational email style with GitHub-inspired header design.
Includes mail struct extensions (headerLine, conversational flag),
CreateConversationalHeader helper, HTML template with avatar support,
p-tag wrapping for content lines, plain-text stripping, and
conditional action link rendering.
On Postgres, a failed operation puts the transaction in an error state
where subsequent operations fail. The previous loop with continue would
keep trying to use a broken transaction. Each user now gets its own
transaction so a single notification failure doesn't affect others.
Refactor functions that created their own sessions when called from
within existing transactions, which caused "database table is locked"
errors in SQLite's shared-cache mode.
Changes:
- Add files.CreateWithSession() to reuse caller's session
- Refactor DeleteBackgroundFileIfExists() to accept session parameter
- Add variadic session parameter to notifications.Notify() and
Notifiable.ShouldNotify() interface
- Update all Notify callers (~17 sites) to pass their session through
- Use files.CreateWithSession in SaveBackgroundFile and NewAttachment
- Fix test code to commit sessions before assertions
Add defer s.Close() to sessions that were never closed:
- auth.GetAuthFromClaims inline session
- models.deleteUsers cron function
- notifications.notify database insert
- Don't create the mail queue when the mailer is disabled to prevent
`SendMail()` from blocking indefinitely
- Add guard clause in `SendMail()` to return early when mailer is
disabled or queue is nil
- Add test to verify notifications don't block when mailer is disabled
This implements the changes from #1080 with the review feedback
addressed (using `package notifications` instead of `package
notifications_test`).
Closes#1080
Email notifications now display user mentions with inline avatar images for improved visual recognition and easier identification. Mentions gracefully fall back to display names if avatars are unavailable.