A catalog lives on photos
A B2B furniture catalog lives on photos, and most of them are taken in clients' offices: wrong light, brick columns, other people's furniture in the frame. Reshooting every product in a studio is not an option for a small manufacturer. The pipeline takes the real photo and rebuilds the environment around the same product.
Four more products








swipe the thumbnails, tap to switch
Descriptions from raw parameters
From a phone photo to the product card
How a frame is made
Generation takes minutes, and a batch job up to a day, so the queue message carries only the task id — the worker reads the state from the database and continues from where it stopped, which makes redelivery safe. Temporary Gemini errors go to a wait queue with a TTL and come back (up to three attempts); poison messages go to a dead-letter queue. One or two frames are generated by ordinary calls, three or more through the Batch API, which is twice as cheap. Every model call is written to a cost log with an estimate in dollars.
Search without a search engine
The library is one table for originals, results, sketches and packaging. After upload the worker asks a fast model to describe the photo structurally — category, materials, colours, room, style. Search works in three layers inside PostgreSQL: field filters, Russian full-text, and semantic search through pgvector with an HNSW index, merged by reciprocal rank fusion. If Gemini is unavailable the search silently falls back to text. The model is forbidden to guess materials: veneer and laminate look the same on a photo, and a wrong material is worse than none — real orders are searched by it.
What the CMS does with every image
On first save the EXIF rotation is applied to the pixels and the metadata is stripped. The page, not the upload API, decides the collection and the file name — a product photo is named by type, model and index. Renditions are named by their actual size and served as a WebP srcset. For ads a 4:3 JPEG is cut from the original so that the crop is slightly larger than the target and gets scaled down to exactly 4:3 — small originals would otherwise round to "almost 4:3", which the ad platform rejects.
Where it is operated from
-
[TBD: before/after of a description] text pair · two columns
Numbers
rounded- ~700 photos processed
- ~300 descriptions generated
- 5 before/after pairs shown
- 4:3 ad-ready crop

