--- title: "Gavelrush: a live online auction for a charity's auction week" author: "@chris" author_url: https://elements.dev/users/chris published: 2026-09-30T21:44:20.092Z url: https://elements.dev/demos/0287ox84/gavelrush-a-live-online-auction-for-a-charity-s-auction-week kind: post format: article --- # Gavelrush: a live online auction for a charity's auction week by [@chris](https://elements.dev/users/chris) ยท 2026-09-30 ## Description Lots with photos and countdowns, bids at a set increment, late bids that extend the close, outbid emails, and pay-by-card links. Gavelrush needed bids that land for everyone at once, a close time that moves when a late bid comes in, outbid and winner emails, photo uploads and card payments. Each of those is a part of Elements, so the agent spent its 22 minutes on the auction itself. **What Elements gave the app** - **Live lots and bids.** Lots, bids and watchlists are LiveTables. A bid lands on every open lot card, countdown and the admin's total raised the moment it is placed, and each lot page hears only its own bid history. - **Bidding as a function call.** The lot page places a bid through an `@rpc` server function that locks the lot, checks the increment, extends the close by two minutes when a bid comes in late, and queues the outbid email, all in one transaction. - **Jobs and email.** A one-line cron schedule closes lots every minute, records each winner and queues the winner's email with a link to pay. The outbid email checks at send time that the bidder is still behind. - **Card payments.** The winner pays through Stripe for the amount on the lot, and the payment is recorded once whether the return page or Stripe's webhook arrives first. Without a Stripe key, a test checkout inside the app records payments through the same function, and in production the app registers its own webhook on the first checkout. - **Photos in the database.** The admin uploads lot photos straight through a server call, and the app serves each one at an address browsers keep for a year. - **Data from SQL files.** Migrations define the auction and seed one admin, four bidders and twelve lots with photos, bids and watchlists, one closing in minutes. **What the project server gave the agent** The project server runs alongside the agent and answers as soon as a file is saved: it type-checks the templates, TypeScript and SQL, applies migrations and reruns the tests, so every question came back right away and the agent kept building. **What shipped** The app type-checks with zero errors and all 28 tests pass. Every page works on desktop and phone. A real sandbox payment went through Stripe end to end.