Skip to main content

Uploading images

Upload images to Pindeck via drag-and-drop, file picker, or the Discord ingest pipeline.

Upload workflow

  1. Click Upload in the gallery or drag files onto the page
  2. Files are stored in Convex file storage first
  3. A background action persists the file to RustFS through the media API
  4. Derivatives (preview, small, medium, large) are generated and stored alongside the original

RustFS object path format

pindeck/media-uploads/YYYY/MM_DD/original/<filename>
pindeck/media-uploads/YYYY/MM_DD/preview/<filename>-preview.<ext>
pindeck/media-uploads/YYYY/MM_DD/low/<filename>-w320.webp
pindeck/media-uploads/YYYY/MM_DD/high/<filename>-w768.webp
pindeck/media-uploads/YYYY/MM_DD/high/<filename>-w1280.webp
Objects are written through the RustFS media API under the pindeck bucket.

Image metadata

Every image record includes:
FieldTypeDescription
titlestringDisplay name
descriptionstring (optional)Detailed description
categorystringClassification (Commercial, Film, Moodboard, etc.)
tagsstring[]Searchable keywords
groupstring (optional)Project grouping (e.g., Commercial, Spec Music Video)
projectNamestring (optional)Specific project within a group
projectOrdernumber (optional)Sort order within a project
moodboardNamestring (optional)Moodboard or reference name
uniqueIdstring (optional)Auto-generated or custom unique ID
sourceTypestringOrigin: upload, discord, pinterest, ai
colorsstring[] (optional)Extracted color palette

Persistence tracking

Each image tracks its durable storage status:
FieldValuesDescription
storageProviderconvex, rustfsWhere the file is currently stored
storageBucketstringRustFS bucket name
storagePersistStatuspending, succeeded, failedCurrent persistence state
storagePersistErrorstringError message if persist failed
derivativeUrlsobjectURLs for small/medium/large derivatives

Backfill failed uploads

Reschedule persistence for uploads stuck in Convex storage:
bun run deploy:convex
This targets images where sourceType = "upload", storageProvider = "convex", and storageId is still present.

Sources

Images can come from multiple sources:
  • Direct upload — User-initiated from the gallery UI
  • Discord — Ingested via the Discord bot emoji trigger (see Discord bot)
  • Pinterest — Imported from Pinterest boards
  • AI — Generated as variations of existing images (see AI generation)