* fix: use streamDownload for S3/MinIO attachment downloads
The response()->download() method doesn't work with remote storage like
S3/MinIO. This fix uses streamDownload() which fetches and streams the
file content directly to the browser.
Fixes backstagephp/filament-mails#45
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: styling
* fix: improve attachment streaming with memory efficiency and 404 handling
- Use readStream() + fpassthru() instead of get() for true streaming
- Add exists() check with abort(404) for missing files
- Add proper StreamedResponse return type
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: enable laravel-mails tests to run from project root
- Remove Mail::fake() from beforeEach (breaks mail logging tests)
- Make Discord service provider optional in TestCase
- Add Mails package autoloading to composer.json
- Configure Pest to include mails package tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: styling
* fix: handle Mailgun user-variables array return type (#109)
Mailgun sometimes returns user-variables as an array instead of a string.
This fix extracts the first element when an array is received.
Fixes backstagephp/laravel-mails#65
Fixes backstagephp/filament-mails#63
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: disable sorting on computed status column (#111)
Status is a computed attribute (accessor) and not a database column.
Sorting on it causes a SQL error. This fix disables sorting for the
status column.
Fixes backstagephp/filament-mails#61
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: remove table aliasing in SuppressionResource for Filament v4 (#112)
Filament v4 uses getQualifiedKeyName() which returns the actual table name
(e.g., "mail_events.id") instead of the alias. This fix removes table
aliasing and uses full table names to ensure compatibility.
Fixes backstagephp/filament-mails#68
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add defensive check for mail_id in download view (#114)
The $getState() function may return a string instead of a model in some
contexts. This fix adds a type check and only renders the download button
when a valid attachment object with mail_id is available.
Fixes backstagephp/filament-mails#69
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add database indexes for sortable columns (#110)
Adds indexes on mails.created_at, mails.sent_at, mail_events.occurred_at,
and mail_events.type to improve query performance when sorting in Filament.
Fixes backstagephp/laravel-mails#68
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* ci: use composer.lock Pint version in CI workflow
Ensures CI uses the same Pint version as local development by reading
from composer.lock instead of installing the latest version.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* ci: use explicit Pint version in CI workflow
composer.lock is in .gitignore so useComposer: true doesn't work.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Baspa <10845460+Baspa@users.noreply.github.com>