Mint a signed PUT URL for a screenshot attachment (C-FBSA2)
Issues a Supabase Storage signed PUT URL for a single screenshot attachment. The customer’s browser PUTs the bytes directly to object storage; this endpoint never sees the body. Server pre-validates MIME + size against C-FBSA1 caps so a wasted upload fails fast.
Route placement: registered on envelope_router per D-FBSA3 so the static /attachments/upload-url path resolves before lookup_router’s dynamic /{feedback_id} capture.
Auth: bearer required (D-FBSA5 - anonymous rejected).
Body
Request body for POST /v1/feedback/attachments/upload-url (C-FBSA2).
The dashboard submits filename/mime/bytes; the server pre-validates the MIME + size against the C-FBSA1 caps and mints a Supabase Storage signed PUT URL. The original filename is not persisted server-side - it is only used for client-side display per C-FBSA3 step 2.
Both this field and :class:AttachmentRef.mime derive from
ALLOWED_MIME_LITERAL in engine.feedback.attachments.limits -
a single edit to that tuple propagates everywhere (D-FBSA4: PNG/JPEG
only, narrower than ttrpg-maps).
Design references: docs/design/concepts/feedback-screenshot-attachments/design.md § C-FBSA2 docs/design/concepts/feedback-screenshot-attachments/decisions.md § D-FBSA3 docs/design/concepts/feedback-screenshot-attachments/decisions.md § D-FBSA4 docs/design/concepts/feedback-screenshot-attachments/decisions.md § D-FBSA5
Client-supplied filename - displayed only on the dashboard. Server discards per C-FBSA3 step 2; the durable storage_key is the only identity downstream.
80MIME type - must match AttachmentRef.mime (D-FBSA4: PNG/JPEG only).
image/png, image/jpeg Pre-upload byte size (≤ 2 MB per D-FBSA1).
1 <= x <= 2097152Response
Signed upload URL minted
Response body for POST /v1/feedback/attachments/upload-url (C-FBSA2).
The dashboard receives:
storage_key: the durable key the customer must echo back in the subsequentPOST /v1/feedbackcontext.attachments[].storage_keyfield. Shape enforced by :class:AttachmentRef.upload_url: the Supabase Storage signed PUT URL.expires_at: ISO 8601 timestamp of URL expiry (~2h fixed by SupabasecreateSignedUploadUrlper R2 research - not configurable).
Design references: docs/design/concepts/feedback-screenshot-attachments/design.md § C-FBSA2 docs/design/concepts/feedback-screenshot-attachments/decisions.md § D-FBSA3