Skip to content
Docs

Command palette

Jump to a page or search the docs.

Changelog

Vehicle photos

How a car's gallery is filled from the template's uploads, how one photo is the cover the garage and the profile show, and the Free plan's 50 photos per car.

Markdown

What it does

A vehicle photo (RF26, US05) is an image in the Organization's private storage in one car's gallery. The bytes travel by the template's direct upload (Documents and uploads); a client only gets 15-minute signed links, with the photo id as the image cache key.

  • vehiclePhoto.add puts up to 20 uploaded images at the end of the gallery, in the order given. Each must be an image of the Active Organization (BAD_REQUEST). A file already in the gallery is skipped, so a replay adds nothing (RNF04). The first photo of a car without a cover becomes the cover.
  • At most one photo is the cover (a unique index). vehiclePhoto.setCover moves it; garage.list and vehicle.profile show it. Deleting the cover makes the first remaining photo the cover. Deleting a photo leaves its file in Files.
  • A car holds 50 photos on Free and 100 on Plus (one read of the gallery). Going over answers CONFLICT; the list returns the plan and its limit, so the app says why before it asks. A deployment without billing is Plus.
  • Writes to one gallery take an advisory lock, so the limit, the positions and the one cover hold under concurrent adds.
  • A cover's dominant colour is read once by the coverColors job and seeds the Car colour theme (Appearance). A Cinematic Studio picture is a photo with ai_edited and a link to its original.
  • Every photo gets a list preview once, from the photoPreviews job: the picture upright (EXIF orientation applied), at most 384 px on its long side, as a PNG under orgs/<org>/previews/<photoId>.png (vehicle_photo.preview_key, preview_checked_at). A JPEG is read at 1/8 scale like the colour, so a Worker never holds the 12 MP original. vehiclePhoto.list and moment.list sign it as previewUrl (null until made, or for a small or unreadable picture: read at 1/8, a JPEG under about 2048 px on its long side comes out under 256 px and gets none, so the seed's 1200 px photos never have one); the gallery strip and Moments rows show it, the hero and garage card keep the original.
ProcedureFailures
vehiclePhoto.list { vehicleId } (gallery order)NOT_FOUND (car)
vehiclePhoto.add { vehicleId, fileIds (1–20) }INPUT_VALIDATION, NOT_FOUND (car), BAD_REQUEST (file), CONFLICT (limit)
vehiclePhoto.setCover { id }NOT_FOUND
vehiclePhoto.delete { id }NOT_FOUND

All are for Members of the Organization; a non-Member gets FORBIDDEN. Photos hold no money or personal data, so no audit_log event is written.

In the app

M-Galeria (features/vehicle-photo/vehicle-photo.screen.tsx, route /gallery/<vehicleId>) opens from M-Veiculo's Gallery pill. The top bar has the car's name and, on iOS, Share (the photo itself, downloaded to the cache, never its link). Gallery shows the selected photo with its Cover badge and a delete button (confirmed), the thumbnail strip with the selected one outlined and an add tile, and "Set as cover". Add opens a sheet: several photos from the library (in the order tapped, at most what the plan still holds) or one from the camera. At the limit the add tile gives way to the plan's note. Specs lists make, model, trim, year, fuel, color, plate and VIN; color, plate and VIN open an edit sheet, and the owner can show or hide the plate and VIN. autofolio://dev/M-Galeria opens the seeded M3 with three photos.

Key files

Edit on GitHubDocumentation is in English.

We use essential cookies to make our app work. With your consent, we also use optional cookies to improve your experience. Read our Cookie Policy and Privacy Policy.