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 Nextcloud via WebDAV
  4. Derivatives (preview, small, medium, large) are generated and stored alongside the original

File path format on Nextcloud

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
Directories are created explicitly via WebDAV MKCOL before PUT.

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 Nextcloud persistence status:
FieldValuesDescription
nextcloudPersistStatuspending, succeeded, failedCurrent persistence state
nextcloudPersistErrorstringError message if persist failed
storageProviderconvex, nextcloudWhere the file is currently stored
derivativeUrlsobjectURLs for small/medium/large derivatives

Backfill failed uploads

Reschedule persistence for uploads stuck in Convex storage:
bunx convex run images:backfillNextcloudFailedUploads '{"limit":50}'
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)