- AttachmentMetadata discriminated union (image/video/audio/document/file) in
zod/openapi; attachments table gains metadata + metadata_kind (0003)
- create/PATCH accept client-supplied metadata; finalize auto-extracts image
width/height/format from R2 head bytes via image-size (no client override)
- serializeAttachment surfaces parsed metadata in all responses
Co-Authored-By: Claude <noreply@anthropic.com>
- routes rewritten on OpenAPIHono with zod schemas; /openapi.json via doc31;
/api/* auth middleware runs before zod (401 before 422); problem+json kept
- multipart upload (worker-orchestrated R2): POST /multipart, PUT /parts/:n,
DELETE /multipart; finalize auto-completes multipart or falls back to single-shot
- GET /files/:id serves public/shared attachments inline with stored content-type;
responses include public_url when available + public/shared
- FakeR2 supports multipart; tests cover multipart, /files visibility, openapi
Co-Authored-By: Claude <noreply@anthropic.com>