This plan outlines the implementation of a prototype media processing pipeline, following the "non-blocking" principle described in ARCHITECTURE.md. The goal is to move from file upload to background transcoding using MinIO, BullMQ, and FFmpeg.
User Upload $\rightarrow$ Next.js Server Action (Multipart Form Data) $\rightarrow$ MinIO (Store original file + create DB record status: PENDING) $\rightarrow$ BullMQ Producer (Add job to queue with metadata) $\rightarrow$ Redis (Job persistence) $\rightarrow$ FFmpeg Worker (Consumes job, downloads from MinIO, transcodes) $\rightarrow$ MinIO (Upload processed variants) $\rightarrow$ Database Update (status: COMPLETED, store variant URLs).
src/
├── app/
│ └── api/
│ └── media/
│ └── upload/ # Route handler for large file uploads (optional fallback)
├── actions/
│ └── media.ts # Server Actions: uploadMedia, getProcessingStatus
├── lib/
│ ├── minio.ts # MinIO client singleton & utility functions
│ ├── queue/
│ │ ├── connection.ts # Redis connection config
│ │ ├── producer.ts # BullMQ job addition logic
│ │ └── worker-types.ts # Shared interfaces for jobs
│ └── ffmpeg/ # (Shared types/utils for FFmpeg)
├── workers/
│ └── media-processor.ts # Independent Node.js process consuming BullMQ jobs
└── db/
└── schema/
└── media.ts # New schema: Media files, variants, processing status
media table tracking id, original_key, mime_type, status (pending, processing, completed, failed), and a JSONB column for variants (resolutions, URLs).minio SDK, then initiates the queue.{ mediaId: string, originalKey: string, filename: string }.job.updateProgress(n) to report percentage. This can be polled via a Server Action or pushed via WebSockets/SSE in the future.src/workers/media-processor.ts) that runs as a separate process./tmp.ffmpeg -i input -vf scale=-1:720 ...)..mp4 or HLS segments back to MinIO.completed..mp4./tmp.pending $\rightarrow$ processing $\rightarrow$ completed.failed.status: pending.processing.