Upload and conversion are separated from web requests so long-running operations do not block the user.
sequenceDiagram
actor U as User
participant A as Application
participant S as S3 / MinIO
participant Q as Redis / BullMQ
participant W as Media worker
participant D as PostgreSQL
U->>A: Request import
A->>D: Create MediaItem and MediaFile
A-->>U: Signed upload URL
U->>S: Upload directly
U->>A: Confirm completion
A->>Q: Enqueue job
Q->>W: Deliver job
W->>S: Download original
W->>W: Analyze, convert, render
W->>S: Upload variants
W->>D: Metadata and READY status
- Images: Sharp extracts metadata and creates thumbnails.
- Videos: FFmpeg/ffprobe extracts metadata, duration, and a preview frame.
- PDFs: Poppler renders pages.
- PPT/PPTX: LibreOffice converts to PDF, then Poppler renders slides.
The state machine is AWAITING_UPLOAD → UPLOADED → PROCESSING → READY, with FAILED on error. Processing versions distinguish current outputs, and storage keys include tenant and resource identifiers to prevent collisions.
Multiple BullMQ workers can share Redis, PostgreSQL, and storage. Tune concurrency to available memory and temporary disk space. LibreOffice and FFmpeg are significantly heavier than image thumbnails.