feat: wire Resend mail and Cloudflare R2 storage (#4)

Add production provider deps/config so transactional email and CMS
media can use Resend and a dedicated r2 disk with custom-domain URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-29 21:00:16 -03:00
committed by GitHub
parent 3dc1f449ee
commit cafb1167ac
16 changed files with 838 additions and 5 deletions

View File

@@ -0,0 +1,43 @@
## Why
The application already supports CMS media uploads and will soon send transactional email (lead notifications, password reset), but production still lacks concrete provider wiring. SPEC §9.1 and §15.4 require S3-compatible object storage in production and transactional email when configured. Resend and Cloudflare R2 are the chosen providers; this change adds the configuration, dependencies, and selection rules so production can send mail and persist public media outside the container filesystem.
## What Changes
- Add **Resend** as the production mail transport via Laravel's native `resend` mailer and `RESEND_API_KEY`.
- Add a dedicated **`r2` filesystem disk** for Cloudflare R2 (S3-compatible API) with explicit R2 env vars and public URLs served through a **custom domain** (`R2_URL`).
- Install required dependencies: `resend/resend-php` and `league/flysystem-aws-s3-v3`.
- Update `.env.example`, README, and deployment guidance with production vs local/test defaults.
- Fix media disk selection in `PublicImageUploadRules` so `FILESYSTEM_DISK=r2` uses the R2 disk instead of falling back to local `public`.
- Add automated config and media-disk selection tests; no live calls to Resend or R2 in CI.
## Non-Goals
Conforme [SPEC.md §4.2](../../SPEC.md), **não** fazem parte desta change:
- Lead notification emails, briefing confirmation flows, or CRM email templates (future phases).
- Private/signed URL access to media; production media is public via custom domain.
- Cloudflare Workers, CDN provisioning, or DNS automation (manual infra setup).
- Redis, queue driver changes, or FrankenPHP worker mode.
- Replacing local `public` disk behavior for development and tests.
## Capabilities
### New Capabilities
- `transactional-email`: Resend-backed transactional mail transport with safe local/test defaults and production configuration via environment variables (SPEC §9.1, §15.4, §12.112.2).
- `object-storage`: Cloudflare R2 object storage via dedicated `r2` disk, custom-domain public URLs, and environment-driven disk selection (SPEC §6.4, §9.1, §15.4).
### Modified Capabilities
- `content-media`: extend disk selection so production `FILESYSTEM_DISK=r2` stores and serves public content images from R2 instead of local `public`.
## Impact
- **Dependencies**: `resend/resend-php`, `league/flysystem-aws-s3-v3` in `composer.json`.
- **Config**: `config/mail.php`, `config/services.php`, `config/filesystems.php`, `.env.example`.
- **Application**: `app/Support/PublicImageUploadRules.php` disk selection logic.
- **Tests**: new Pest feature/unit tests for mail and filesystem config; media disk selection regression test.
- **Docs**: `README.md` production provider section.
- **Infra (manual)**: Resend API key, R2 bucket, R2 API token, and custom domain mapped to the bucket.
- **No breaking change** for local development: defaults remain `MAIL_MAILER=log` and `FILESYSTEM_DISK=local`/`public`.