A demo hit "That's everyone nearby" on Electrician after four swipes.
That was the deck working — there were exactly four — but the shape of
the catalogue was worse than it looked: 42 of the 50 trades had NO pros
at all, so tapping Roofer or Cleaner hit the dead end immediately rather
than after seven swipes.
Two halves to the fix, and the second matters more.
Depth: 56 more pros, so the fifteen live trades now run 3–15 deep
instead of 1–12. Every photo was picked by reading Unsplash's written
description and keeping only images that show the trade being DONE, then
checking each URL resolves — one of 33 was a 404 and was dropped rather
than seeded broken. Where a photo already belonged to someone in this
file the new pro takes a name of the same gender: the face and the name
on a card have to agree.
Honesty: the other 35 trades are seeded isActive:false. A category with
nobody behind it is not a feature, it is the product claiming to do
something it cannot — and no amount of invented supply fixes that, it
just moves the lie one screen later. LIVE_TRADES is the list, and
widening it means recruiting pros first and adding the slug second.
Locksmith is called out in the file: photo searches return padlocks, not
locksmiths, so two of its cards carry door hardware. A lock is at least
a locksmith's work. A stock portrait of somebody who is plainly not one
is not.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The showcase was a Barcelona market: Catalan names, +34 numbers, euro
rates and "Carrer Example 12" on every job. Presented to a Mexican
client, all of that reads as somebody else's product.
City comes from NEXT_PUBLIC_CITY_* as before, now Ciudad de México at
19.4326/-99.1332, with MAPBOX_COUNTRY=mx. The seed's fallbacks were
Barcelona literals, so an unset env quietly seeded a different city
than the app rendered — they now agree.
Two db tests pinned the Barcelona centre as a hardcoded constant, which
is why the deck returned zero cards on the first run here: every pro was
a continent outside the radius. They read the same env as the seed now,
so the trap cannot recur.
Money: formatCents defaults to USD/en-US, and the nine hardcoded euro
signs across the card, search rows, quote strip and forms are dollars.
The rate NUMBERS are unchanged and still read high for CDMX — that is a
pricing decision, not a currency one, and is left alone deliberately.
Seed people are Mexican, addressed on real Roma/Condesa streets rotated
by index rather than one placeholder repeated. Phones moved to +52 55,
which moves the demo login to +525500000000 / 000000.
Also in here, from the same session:
- Sending a job now confirms. The mutation always succeeded; the sheet
just closed with no receipt, which from the customer's side is
indistinguishable from a dead button. Dismissing that receipt resolves
as 'sent', so the card does not return to the deck.
- Media moves to DigitalOcean Spaces, with the public origin derived
from bucket and region instead of a second env var to keep in sync.
- Managed-Postgres TLS: DATABASE_CA_CERT takes a path or inline PEM.
- The client-facing project panel beside the running app.
- Two profiles removed and four renamed to match their photos.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>