Archive completed public-site and production-provider changes into main specs, remove duplicate active changes, and add complete-foundation-parity so Phase 0 staging and remaining foundation gaps block Phase 2 cleanly. Co-authored-by: Cursor <cursoragent@cursor.com>
49 lines
1.9 KiB
Markdown
49 lines
1.9 KiB
Markdown
# object-storage Specification
|
|
|
|
## Purpose
|
|
Define Cloudflare R2 as the production S3-compatible filesystem disk for public media.
|
|
|
|
## Requirements
|
|
### Requirement: Cloudflare R2 is available as dedicated filesystem disk
|
|
|
|
The system SHALL provide an `r2` filesystem disk using Laravel's S3-compatible driver pointed at Cloudflare R2 (SPEC §6.4, §9.1, §15.4). Configuration MUST use explicit `R2_*` environment variables: `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET`, `R2_ENDPOINT`, and `R2_URL`.
|
|
|
|
#### Scenario: R2 disk is defined in filesystem config
|
|
|
|
- **WHEN** the application boots
|
|
- **THEN** `config('filesystems.disks.r2')` MUST exist
|
|
- **AND** the disk driver MUST be `s3`
|
|
- **AND** credentials MUST resolve from `R2_ACCESS_KEY_ID` and `R2_SECRET_ACCESS_KEY`
|
|
|
|
#### Scenario: R2 endpoint uses path-style addressing
|
|
|
|
- **WHEN** the `r2` disk is configured
|
|
- **THEN** `use_path_style_endpoint` MUST be `true`
|
|
- **AND** `endpoint` MUST resolve from `R2_ENDPOINT`
|
|
|
|
#### Scenario: Public URLs use custom domain
|
|
|
|
- **WHEN** a file is stored on the `r2` disk with public visibility
|
|
- **THEN** generated URLs MUST use `R2_URL` as base
|
|
- **AND** MUST NOT require signed URLs for browser-facing media
|
|
|
|
### Requirement: Production default filesystem disk is R2
|
|
|
|
Production deployments MUST set `FILESYSTEM_DISK=r2` so application code using the default disk stores files on R2.
|
|
|
|
#### Scenario: Default disk resolves to R2 in production
|
|
|
|
- **WHEN** `FILESYSTEM_DISK=r2` is set
|
|
- **THEN** `config('filesystems.default')` MUST be `r2`
|
|
|
|
#### Scenario: Local development keeps local disk
|
|
|
|
- **WHEN** `FILESYSTEM_DISK` is unset or set to `local`/`public` in development
|
|
- **THEN** the default disk MUST NOT require R2 credentials to boot
|
|
|
|
#### Scenario: Tests do not call R2
|
|
|
|
- **WHEN** the test suite runs
|
|
- **THEN** tests MUST use `Storage::fake('r2')` or local fakes
|
|
- **AND** no live HTTP request to Cloudflare R2 MUST occur during CI
|