Fix real edge cases: enforce 5MiB non-final parts, track offsets for ordered/idempotent chunks, size from bytes received, delete orphaned R2 objects if Media create fails, and split the controller into clearer paths.
Co-authored-by: Cursor <cursoragent@cursor.com>
Dataset for multipart strategy selection plus HTTP paths for assemble (local/public/images) and multipart (s3/r2/spaces videos).
Co-authored-by: Cursor <cursoragent@cursor.com>
Local/public already used the assemble-then-store flow. Rename supports() so it is obvious every filesystem disk works; multipart only kicks in for S3-compatible remote disks.
Co-authored-by: Cursor <cursoragent@cursor.com>
The last chunk was reassembling the full file locally and pushing ~185MB to R2 in one request (53s+). Videos/PDFs now upload each chunk as an S3 multipart part so finalize only completes the upload.
Co-authored-by: Cursor <cursoragent@cursor.com>