← All work
LIVE

Dušan D. Petrović

A painter's bilingual gallery with a real-time auction engine on edge infrastructure — anti-snipe, magic-link bids, gallery-midnight design.

Client work 2026 Astro 5 (SSR)Cloudflare PagesD1 + R2Durable ObjectsCloudflare Access
Visit live site ↗
Dušan D. Petrović — screenshot

A painter with 35 years of exhibitions needed more than a portfolio site — he needed a place where a canvas could be auctioned in real time, on infrastructure that costs $0 a month.

Context

Dušan D. Petrović is an academy-trained Serbian painter. The brief: a bilingual (Serbian/English) site with a 21-painting gallery, biography, exhibition history from 1990–2025, a contact form, and timed auctions. One constraint from me: everything runs on Cloudflare’s edge, hosted at $0. As always, the code came from AI agents working under my direction — my job was the brief and the veto.

Decisions

  1. Full SSR instead of a static export. Every request hits the worker, so admin edits in D1 show up on refresh. With 21 paintings, a D1 lookup takes under 5 ms — no caching layer earned its keep.
  2. One Durable Object per auction. The AuctionRoom holds live state, streams bids over WebSocket, extends the clock on anti-snipe triggers, and snapshots to D1 on close. No auction server on the payroll.
  3. Magic-link bids instead of accounts. Bidders confirm through a 30-minute email link, with a 30-day session skip for returning bidders. Nobody registers an account to bid on one painting.
  4. One canonical Latin slug per painting. /galerija/akrobata and /en/gallery/akrobata share an identity; Cyrillic and diacritics normalize before lookup.
  5. “Gallery midnight” design. Cormorant Garamond on a near-black, canvas-textured background with a gold accent — screens that behave like gallery walls.

Build

Four weeks, May 22 to June 17, 2026. A builder agent scaffolded the stack — Astro 5, D1, R2, Workers — and I ran an independent QA agent against its output. The first review pass fixed 12 issues; the adversarial pass found 8 more critical ones. Unit tests grew from 63 to 141, plus Playwright E2E. Hardening passes added CSP nonces, KV rate limiting, and JWKS-verified Cloudflare Access; post-launch, error boundaries and an admin allow-list went onto all 19 admin handlers.

Outcome

Live at dusandpetrovic.com since June 17, 2026: 21 paintings in two languages, Turnstile-protected contact, full admin panel behind Cloudflare Access. The auction engine is built and tested end to end, currently switched off publicly until the artist schedules his first sale — flipping it on is a toggle, not a rebuild. Total infrastructure bill: $0.

Lesson

The most valuable agent on this project was the one I hired to distrust all the others.