Gear Tracker was built for one problem: a pile of gear with several owners, reconciled at load-out. But some gear goes missing without any load-out to catch it. A pedal is left by the side of the stage, or a bag of cables is forgotten in a green room. The person who finds it usually wants to give it back, and has no way to find the owner.
(My last post covers how the rest of the app was built.) Every item in Gear Tracker already carries a QR sticker. Until this week, that sticker only helped people inside the app. Now it helps anyone who finds your gear. (Here's a 79-second video of it in action.)
How it works
- The label asks. Printed labels now say "IF FOUND, SCAN ME" above the QR code.
- Anyone can scan it. The QR code is an ordinary link, so any phone camera opens it, with no app or account. The page shows what the item is and whose it is, and asks the finder where they found it and how to reach them.
- The owner hears right away. The owner gets an email within seconds, and the message also waits in a new Messages page in the app, with an unread badge and a banner on the item itself.
The feature went from design spec to deployed in one day, using the same spec, plan, subagent and review loop as the rest of the app. As before, the interesting problems were the ones that wouldn't have produced an error.
A public page in a private app
Everything in Gear Tracker was built on the assumption that you're signed in. Row-level security (RLS) in Postgres decides what each user can see, and a stranger with no account can see nothing. That's the right default, and the found-item page couldn't change it.
So the finder never touches a table. The page calls two Postgres functions that run with the database's own permissions and are open to signed-out visitors. One looks up a tag and returns exactly two values: the item's name and the owner's display name. The other saves the finder's message. No IDs, emails, photos or descriptions ever leave the database, because the functions have no way to return them.
The leak hiding in a default
"The owner's display name" sounds harmless. But when someone signs up, Gear Tracker fills in their display name with the part of their email address before the @, so jane.smith@example.com starts out as "jane.smith". Most people never change it. Showing that to anyone who scans a sticker would have shown half of the owner's email address to strangers.
The review caught it. The lookup now checks whether the display name still matches the email's local part, and if so, leaves the name off entirely. The page then just says the item belongs to a Gear Tracker user. A name you chose yourself is shown, and a name the system made from your email is not.
The default that grants too much
Owners can mark a found message as read or resolved. The database policy for that says an owner may update their own messages, which looked complete. It wasn't.
Supabase grants signed-in users permission to update every column of every table by default, and leaves it to RLS to decide which rows. RLS can't limit columns. So the owner could also have rewritten what the finder said, or the record of whether the email was delivered. The fix was to remove the table-wide permission and grant updates on exactly two columns, read_at and resolved_at:
grant update (read_at, resolved_at) on found_reports to authenticated;
Like the realtime bug in the first post, this is easy once you know, and invisible until someone asks the right question.
Email without a server of my own
Gear Tracker still has no backend of its own, so sending an email took a short chain of Supabase pieces:
- Saving a finder's message fires a database trigger.
- The trigger uses
pg_netto call a Supabase Edge Function in the background, so the finder never waits on email. The call carries a shared secret kept in Supabase Vault. - The Edge Function loads the message from the database, rather than trusting what it was sent, looks up the owner's email, and sends it through Resend from
found@gear.osborn.bz.
A few rules shaped the chain. A message is always saved even if the email fails, because the in-app copy is the record and the email is just the alert. Links in a finder's message are broken up (https[:]//example[.]com) so the email never carries a clickable link from a stranger. Each item accepts at most 3 messages an hour and 10 a day. The function counting them locks the item's row while it checks, so a burst of simultaneous messages can't slip past the limit.
Labels that line up
A QR code is only useful if it's on the gear. Labels now print on Avery 8293 sheets (1.5-inch round stickers, 20 to a page), with a "Start at label" option so a half-used sheet isn't wasted.
The app's print output matches Avery's own template exactly, but printing from an iPhone still came out misaligned. AirPrint has no margin setting and shrinks the page to fit the printer's printable area, so the labels drift. Rather than build a calibration tool, the app now suggests printing from a computer when it's opened on a phone.
Labels outlive addresses
The first QR codes pointed at Vercel's default address for the app. That worked, but a printed sticker can't be updated, and the app might not live there forever. So the app moved to gear.osborn.bz, and new labels encode that address. Old labels still work: the app's scanner accepts both addresses, and the old one redirects to the new one for phone cameras.
The same reasoning kept the address off the label itself. "IF FOUND, SCAN ME" never goes out of date. A printed domain name would, if the app is ever renamed.
Making the promo
To show all of this in a 79-second vertical video, I needed footage of the real app with real gear. I set up a demo account in the live app with copies of my own items, so the pedal in the video and the pedal on screen are the same, and its sticker really does open the found page.
Claude Code recorded the screen clips with Playwright, scripted in a phone-sized browser window signed in as the demo account. I filmed the physical shots, the scan, the email arriving and the hand-off, and edited it all together in CapCut.
What's next
The original plan still has offline scanning on the list, for load-outs in basements and parking lots with no signal. But finding gear after it's lost turned out to matter as much as preventing the loss. Every printed label is now a way for lost gear to get home.