## 1. Dependencies - [x] 1.1 Add `resend/resend-php` to `composer.json` require - [x] 1.2 Add `league/flysystem-aws-s3-v3` to `composer.json` require - [x] 1.3 Run `composer update resend/resend-php league/flysystem-aws-s3-v3 --with-all-dependencies` and commit lockfile ## 2. Transactional email (transactional-email) - [x] 2.1 Confirm `config/mail.php` resend mailer and `config/services.php` `RESEND_API_KEY` binding - [x] 2.2 Add `RESEND_API_KEY` and production mail vars to `.env.example` with safe local defaults (`MAIL_MAILER=log`) - [x] 2.3 Write feature test asserting resend mailer config and services key resolution ## 3. Object storage (object-storage) - [x] 3.1 Add dedicated `r2` disk to `config/filesystems.php` with `R2_*` env vars, path-style endpoint, and `R2_URL` - [x] 3.2 Add R2 env vars to `.env.example` with comments for custom domain setup - [x] 3.3 Write feature test asserting `r2` disk config (driver, endpoint, path-style, url from `R2_URL`) ## 4. CMS media disk selection (content-media) - [x] 4.1 Update `PublicImageUploadRules::disk()` to return `r2` when `FILESYSTEM_DISK=r2`, keep `s3` and `public` fallbacks - [x] 4.2 Write unit/feature test for disk selection matrix: `r2`, `s3`, local/unset → `public` ## 5. Documentation - [x] 5.1 Update `README.md` with production provider section (Resend + R2 + custom domain) - [x] 5.2 Document production env checklist: `MAIL_MAILER=resend`, `FILESYSTEM_DISK=r2`, required secrets ## 6. Verification - [x] 6.1 Run `composer pint:check` and `composer phpstan` - [x] 6.2 Run `composer test:unit` and `composer test:feature` for new provider tests - [x] 6.3 Run `composer quality` and fix any failures