01
Direct media uploads without routing video through the app server
The upload flow starts in the Next.js app, but large video files do not pass through a Next.js route. The app asks the backend for short-lived R2 presigned PUT URLs, the browser uploads the video and thumbnail directly to R2, and the backend only finalizes database records after the client reports a successful upload.
- Object keys are scoped under users/{userId}/feels/{feelId}/ so finalize can reject keys that do not belong to the current user and feel.
- The server validates content type, upload size intent, draft state, and slug rules before publishing.
- Draft rows are created during finalize, which reduces abandoned database records when uploads fail midway.
