MuseMVP
MuseMVP-Docs

Object Storage

Configure R2 and understand upload limits, ownership, download responses, and file API keys.

Module ownership

packages/storage/src/index.ts validates uploads and operates R2. apps/web/src/server/files.ts connects HTTP requests, sessions, quotas, and database records. The R2_BUCKET binding stores bytes; D1 stores the original name, MIME type, size, owner, and object key. Files are private by default rather than exposed through public bucket URLs.

Local development uses Wrangler's local R2. Production binds the bucket selected by the deployment planner. Review deployment before changing its name so existing objects do not remain stranded in another bucket.

Upload limits

SettingCurrent default
File sizeMore than zero and at most 1,048,576 bytes (1 MiB)
Texttext/plain, text/markdown
Imagesimage/png, image/jpeg, image/webp
File count100 per user, configured by product.quotas.storedFiles

File count is product configuration. The storage package validates byte limits and allowed MIME types. Update server validation, UI hints, and tests together; changing the HTML accept attribute alone is insufficient.

Verify through the workbench

  1. Upload a small .txt file or image at /app/files.
  2. Check the displayed name, size, and state, then refresh.
  3. Download it and compare its bytes.
  4. Delete it, refresh the list, and confirm further downloads fail.

Object keys use the user ID and a random UUID rather than the original filename. Downloads are attachments with private, non-caching responses; uploaded content is not served as executable page content.

Call the upload API

const form = new FormData();
form.set('file', selectedFile);
const response = await fetch('/api/files', { method: 'POST', body: form });
if (!response.ok) throw new Error('Upload failed');

Let the browser generate the multipart Content-Type and boundary. GET /api/files lists owned files. Follow current files.ts for individual ID-based download/delete paths; do not submit arbitrary R2 object keys.

API keys and ownership

File API keys created in settings use the x-api-key header. They remain subject to verified email, account status, quotas, and ownership checks. Knowing another user's file ID must not grant download or deletion rights.

If metadata persistence fails after an upload, the current implementation removes the new R2 object. Deletion removes the object before metadata. Preserve compensation when extending this flow and do not present a partial operation as success.

AI summary integration

Summaries accept owned plain-text or Markdown files. Images are not treated as text. The current summary reads only the first 16,000 characters, so a 1 MiB upload limit does not imply full-file model processing. See AI and tasks.

Troubleshoot and validate

  • Unsupported file type or size: inspect actual MIME, empty files, and byte size rather than only the extension.
  • Quota failure: inspect the user's count and storedFiles configuration.
  • Metadata without bytes: check the selected bucket, resource name, and interrupted operations.
  • 401/403: inspect the session, key status, verified email, and ownership.

Run relevant Workers/API tests and cross-user access checks. Use your own deployment for real storage acceptance rather than modifying other public-demo users' files.

Auf dieser Seite