Case study

TradieToday: post a job, get quotes.

A marketplace where Melbourne homeowners post a trade job and approved local tradies quote on it, from routine fixes to same-day call-outs. It needs everything a brochure site doesn't: accounts, a database, an approval step and payments.

Start a projectVisit tradietoday.au
Started
24 October 2026
Changes merged
74 in its first week
Built with
Next.js, Hono, Cloudflare Workers and D1
Accounts and payments
Clerk and Stripe

What it does

  • A homeowner posts a job: one of 11 trades, how urgent it is (routine, same day or urgent), and where. It's Melbourne only for now, so the suburb comes from a list of 49 suburb centres.
  • "Use nearby suburb" picks the closest one from the phone's location, without saving the exact position.
  • Anyone can browse jobs by trade and urgency, or search by job or suburb. Approved tradies send a quote, the homeowner accepts one, and the amount is shown to the cent.
  • Homeowners and tradies each have a dashboard. Signing in works with an email address or a Google account.

Around the marketplace there's content that helps people find it and decide: 11 trade pages, 24 pages about common jobs, 12 guides and an emergency tradies page. 220 example jobs, clearly labelled, show visitors how the job board works before real jobs fill it, and anyone can practise quoting on them.

Tradies are checked before they can quote

Anyone can sign up, but only approved tradies can quote. A tradie applies with their ABN (its checksum is checked on entry), licences and insurance, and I review the evidence for each trade. Plumbers and electricians need a licence I've checked, every tradie needs current public liability cover, and electricians need at least $5 million of it.

Approval isn't a one-off. If a tradie changes a credential, their application goes back for review, and when insurance or a licence review lapses, they stop being able to quote until it's sorted.

Sign-in that can't be talked into things

Clerk handles accounts and sign-in, so passwords never touch my code. Every signed-in request to the API carries a token, and the API checks it against Clerk's published signing keys before trusting it. What a person is allowed to do, like quoting or moderating, comes from the database, never from anything the browser sends.

Payments, built carefully and switched on deliberately

Payments use Stripe Connect: the homeowner pays, the money goes to the tradie's own Stripe account, and the platform's commission comes out as Stripe's platform fee. The details are the boring, important kind:

  • Amounts are handled in whole cents, so nothing is lost to rounding.
  • Each job gets exactly one checkout, even if someone double-taps or the network retries.
  • Stripe's notifications are signature-checked and recorded once, so a payment can't be counted twice, and a late failure can't undo a payment that's already marked as paid.

The code only accepts Stripe's test keys for now. Taking real money is a separate release, reviewed on its own, because that's not a switch to flip casually.

Two people can't accept at once

When a homeowner accepts a quote, the database only lets that happen if the job is still open, in a single step. If two requests arrive at the same moment, one wins and the other doesn't. It's a small detail that stops a whole class of support headaches.

Checked on every change

Every pull request runs about 200 automated tests and checks, a build and a type check. Some of the tests run against a real database built from the same migrations as the live one. Merging deploys the API first, with any database changes, then the site.

What's next

Alerting nearby tradies the moment a job is posted is scaffolded, but not switched on yet, and live payments wait for their own reviewed release. Reviews and ratings are on the list. It's early days, and it's built so each of those can be added without starting again.

Keep exploring