Build notes · Wednesday 19 August 2026

FeastMatch, end of day

A catering marketplace for the South West. Someone posts one brief about their event; we match the caterers who can actually do it, and open a conversation. Here is everything that changed today, everything that was tested, and everything that is still a draft.

Sitethe live build
StatusLive, test data
PaymentsSimulated
Commission10%

The idea

Two rules that make it different from the sites you already pay for

Talking is free, permanently

On Add to Event a caterer buys credits to unlock a lead before they are allowed to reply. Here, when a brief matches you, a message thread simply opens. Neither side is ever charged to use it — no credits, no subscription, no lead fees. You read the brief, you reply, you quote, all free.

The customer's money is held, not just promised

When a customer accepts your quote they pay FeastMatch, not you. It sits in our account until you and they both confirm the event went ahead — then it is transferred to you, less 10%. If it is cancelled, they are refunded and we take nothing. If either side raises a dispute, nothing moves until a person looks at it.

The bit that separates it from a directory is the matching: cuisine, guest numbers, budget, how far you will travel, dietary work you can handle, service style, and which services you actually offer. You should not be reading briefs for a 300-person wedding in Cornwall if you do 40-cover street food around Bristol.

The day, in order

What actually changed

14:54

The public pages got a proper look

The old front end read like a document — a serif typeface, hairlines, and not one photograph anywhere. It now uses the visual language customers already recognise from the big catering sites: photo-led cards, alternating bands, pill buttons, real pictures. 25 photographs added. Also fixed while doing it: every image was rendering at the wrong height, form boxes came out at four different sizes so nothing lined up, the price panel read “Evidenced14 quotes” with no space, and the only “Get quotes” button on mobile was buried inside the hamburger menu.

15:04

Closed a security hole on the old site

The site answered on plain, unencrypted http:// as well as the secure https://, and did not redirect between them. Anyone on the same network could have read the first request. It now forces the secure version.

16:35

Rebuilt as an actual marketplace

Big one

This is the day's real work. Accounts for caterers and customers, message threads, structured quotes, the booking and payment flow, verified reviews, an admin screen. Every page now has its own proper web address — /listings/hog-roast, /suppliers/smoke-and-oak-bbq — which is what Google needs and what the old version could not have. Every form works even with JavaScript switched off.

Five faults were caught by the safety checks rather than by hand: sign-out was completely broken and returned an error while leaving you logged in; a security rule was silently breaking the layout of every page; a malformed form submission crashed instead of politely refusing; the written-down instructions for restoring the database did not actually work; and sign-in had no limit on attempts.

16:49

A way to update the live database by hand

The access key on this machine can deploy the website but has no permission to touch the database, so the usual command fails outright. Wrote a single file that can be pasted into Cloudflare's own console instead, which also records that it ran so the normal tooling stays in step later.

17:04

Fixed sign-in from any machine but this one

The login cookie was marked “secure connections only”, which is correct for the real site and wrong for testing — browsers silently threw it away, so signing in from a phone on the same network was impossible and gave no error to explain why. It now follows whichever connection is actually in use. The live site is unaffected; it is always encrypted.

17:22

No invented caterers on the live site

The test data includes nine made-up catering businesses and sample reviews. Useful for development, dishonest in public, so a second version of the update file was written that leaves them out. Writing it exposed a real bug: every caterer card linked to a profile page that did not exist for the five businesses already in the database, because they pre-dated the new structure. Those links are now built properly, and their ratings show “New to FeastMatch” rather than a number nobody has earned.

17:43

Went live — and the real server found two bugs

Deployed

Both were invisible on the test machine. First: password scrambling was set stronger than Cloudflare permits, so registering an account crashed the moment it was deployed, despite passing every local test. It now uses three chained rounds to reach the same strength within the limit. Second, again: the live address answered on unencrypted http, handing out login cookies to anyone listening. Fixed and redirected.

A backup was taken, then 19 duplicate applications and 6 enquiries left over from August form testing were cleared out, along with the accounts created while checking the deployment.

18:29

Caterers can upload their own photographs

Deployed

You upload from your own profile page: one main photo and up to eight in the gallery, 6MB each. Detail below — this one matters to you more than the rest.

18:43

Three older versions retired

Four separate builds of FeastMatch existed. Three are now filed away with a note saying what each one proved, leaving one project that is worked on and deployed. Nothing was taken offline; the old ones are just no longer touched.

20:30

A phone-sized test, and the fixes it forced

Not deployed yet

A new check drives a real browser at phone width across every page and fails on four things: sideways scrolling, anything running off the edge, buttons smaller than a fingertip, and text under 12px. It found the menu button squashed to 32px wide, footer links, service tags and checkbox rows all at 20–27px tall, and a set of text boxes that had been missing their type, so the “make everything 52px tall” rule skipped them. All fixed and passing — but this batch is still on my machine, not on the live site.

Your listing

What happens to a photo you upload

Phone photographs carry hidden data, including the GPS coordinates of where they were taken. If you photograph a hog roast in your own garden and upload it, the file quietly contains your home address. That data is stripped off on our server before anything is stored — not in the browser, where it would depend on JavaScript being switched on.

The rest of it: the file type is worked out by reading the actual bytes rather than trusting the file name; illustrations in SVG format are refused outright because they can carry hidden code; images are served from our own address rather than a public storage bucket, so they are locked to the site; and a picture with absurd dimensions is rejected before it can be opened. Nobody can delete or promote another caterer's photo, and the admin screen has a takedown button that removes both the listing entry and the file itself.

Fixed alongside it: link previews were broken everywhere. When you pasted a page into WhatsApp, the site was answering the preview request with “not found”. Nobody would have spotted why.

The money

Where a payment sits at every stage

Booking states, in order
WhenThe booking saysWhere the money is
Customer accepts your quoteawaiting paymentNowhere yet. Nothing has been charged.
Customer paysfunds heldIn the FeastMatch account, tagged to your booking.
You confirm it went aheadfunds heldStill held. One confirmation is not enough.
They confirm toocompletedCleared to send.
ReleasedreleasedTransferred to your bank, less 10%.
Cancelled after paymentrefundedBack to the customer. We take nothing.
Either side disputesdisputedFrozen. Nothing moves automatically at all.

Two easier approaches were rejected because neither is really holding the money. Paying you straight through at the moment the card is charged is not escrow — the customer has no protection. Authorising the card and capturing it later is not escrow either, because a card authorisation expires in about a week, and catering is booked months ahead.

To stop one side simply declaring the job done, the release requires both confirmations to be recorded, or an administrator to force it deliberately. That rule is specifically covered by an automated test that tries to release funds on one confirmation and expects to fail.

Evidence

Every test that was run today

74/74
passed

The full walkthrough, against the live site

A script visits every page as a logged-out visitor, as a customer and as a caterer, then runs a whole booking end to end: brief, message, quote, accept, pay, both confirm, release. Run against the real deployed site, not a copy — which is the only reason the registration crash was caught within minutes.

Passed
58
page loads

The phone test

29 pages loaded in a real browser at 375px and again at 320px — a modern iPhone and the smallest phone still in use. Zero problems remaining: no sideways scroll, nothing off the edge, no tap target under 44px, no text under 12px. The fixes that got it there are written and verified but not yet on the live site.

Local only
436
rows restored

A backup that actually restores

The documented restore procedure was tested and did not work — the export writes the data back in an order the database rejects. Rather than leave it, a repair step was written, then the local database was deliberately destroyed and rebuilt from a backup: 436 rows across 17 tables came back with identical counts and a completed booking's amount, commission and payout unchanged.

Verified
70/70
passed

The database update, rehearsed

Rather than trusting the update file, a database was rebuilt at exactly the live site's old state, the file applied to it, and the whole walkthrough run against the result. Also checked the other way round: the new site deployed against the old database, to confirm the order matters — it does, every page fails.

Passed
GPS
fixtures

Photo privacy, proven not assumed

Test images were hand-built carrying real GPS payloads, uploaded, then inspected afterwards: the location data is gone and the pictures still display at full size.

Verified
2
test flaws

The test script was itself wrong

It signed in six times per run and tripped the very limit it was meant to be testing around, and it picked the wrong message thread — which happened to work on my machine and would have failed anywhere else. Both fixed.

Fixed

There is a reason for the belt and braces: every page is assembled as text at the moment it is requested, so a typo cannot be caught by anything except actually loading the page. That is exactly how sign-out shipped broken.

Honest list

Drafts, placeholders and things that are not real yet

Over to you

What I would like your opinion on

Is 10% on a completed booking the right number?

It comes off your side, not added to the customer's. Nothing is charged on a cancellation, and nothing at all is charged for listing, reading briefs, messaging or quoting. Compare it to what you currently pay in lead fees and credits for jobs you never win.

Would you actually confirm a job in an app?

The money will not move until you and the customer both press confirm. If people forget, caterers do not get paid on time and the whole model falls over. Would you do it from your phone on the way home? Should it chase you?

Are the service categories right?

27 of them at the moment. Which are missing, which are the same thing under two names, and which would you never tick?

What does a brief need to include before you would reply?

It currently asks for date, town, postcode, guest numbers, budget, venue, cuisine, service style and dietary needs. What is missing that makes you ignore an enquiry?

One main photo and eight gallery shots — enough?

6MB each, which is a normal phone photo. And would you rather upload from a phone or a laptop?

Have a look at the site

Why this page is plain

Built to cost almost nothing to read

No photographs, no tracking, no fonts to download and not one line of JavaScript — the whole page is a single file of about 30KB, served from whichever Cloudflare machine is nearest you. It is dark by default because on a phone with an OLED screen a black pixel is a pixel that is switched off; if your phone or laptop is set to light mode, it will honour that instead.

The practical upshot: it opens instantly on a bad signal in a field, costs almost nothing in mobile data, and sets no cookies, so there is nothing to consent to.

The small print

Privacy, and the terms of sharing this

Privacy. This page collects nothing about you. No analytics, no tracking pixels, no cookies, no fonts or scripts fetched from anyone else's server — so there is nothing to consent to and no consent banner. Cloudflare, which serves the page, keeps its own standard request logs; I do not see who opened it or when. Emailing me is the only way anything about you reaches me, and then only what you write.

Terms. This is a private working document shared for review, not a published announcement, and it describes software that is not finished. Nothing in it is an offer, a contract, or advice — the 10% commission, the escrow arrangement and the timings are all proposals to be argued with. Please do not forward the link without asking first. Everything on the live FeastMatch site is test data.