SIDE QUEST LABS
devlog — issue 03

Palate leaves the simulator

A real Supabase backend went in, a second phone joined the follow graph, and TestFlight found bugs no amount of simulator testing ever surfaced.

September 15, 2026 Palate 7 min read

No screenshots this time — the screens have been moving fast enough (a full restaurant-page redesign landed two days ago) that anything captured now would be stale before this post finishes loading. What follows is the log instead.

Issue #02 ended with a promise from the README: swapping in a real backend would be “a service-layer change, not a model or view rewrite.” The same day that issue published, the synthetic sample data — the whole cast of fictional reviewers Palate had been demoing against — was deleted for good, and the real migration started. It's a good moment to check whether that promise held.

The backend swap, in order

It mostly did hold, but it took longer than one sitting, because a backend isn’t one thing — it’s writes, then reads, then files, then the smaller graphs riding on top:

Aug 13

Writes go first, then reads

Restaurants and reviews could be written to Supabase, but nothing pulled data back down — two real phones still couldn’t see each other’s data. A fetch-and-merge pass followed the same day, matched by stable ids so a locally created profile doesn’t duplicate itself the moment it syncs.

Aug 13–24

Photos, invites, and the follow graph

Photo sync through Supabase Storage, confirmed device-to-device. Invite codes generated before any server session existed got backfilled in rather than silently lost. Phone-number matching moved server-side (still hashed, never sent in the clear) so a match works even if the other person hasn’t opened the app recently. Follows themselves — the actual graph the whole visibility rule depends on — were the last piece wired up.

Aug 24

A gap, flagged early

An external review of the build called out a hard blocker for a public listing: no in-app path to delete your account, which Apple’s guidelines require for any app that supports account creation. Correctly scoped as a pre-launch item rather than an emergency — TestFlight is invite-gated, known testers — but now on the record with the actual schema work it needs (see below).

The model didn’t need touching once, through any of it. The promise held.

A second phone joins

Everything above was validated against one real account. On September 12th, a second person — a real tester, a real phone, a real follow relationship — started using TestFlight build 12. Within a day, three bugs surfaced that a single-device simulator run could never have found:

The feed that looked stuck
One tester saw a single feed card when six were waiting on the server. The merge logic downloaded every photo and avatar serially, one full-size image at a time, and a review only appeared once its own image finished — so a slow connection looked like a broken one. Rows now merge immediately, with images catching up afterward through a small bounded pool instead of one at a time.
A reinstall that overwrote a real account
Deleting and reinstalling the app on an existing account silently wiped that account’s username and display name server-side. The onboarding flow was writing a placeholder profile before checking whether a real one already existed. A fix shipped a day earlier had looked right but ran too late to matter — it was verified properly this time with an actual delete-and-reinstall round trip on device, not just a read of the diff.
Map pins that meant three things at once
The same gold color meant both “a follow reviewed this” and “currently selected,” distinguishable only by size. Unselected pins on Palate also drew a white icon on a cream background — invisible. Untangled into one consistent meaning per pin.
Corrections that never arrived
The merge layer only ever knew how to accept new data. If a review, dish, or restaurant was edited or deleted on the server, a device that already had the old copy kept it forever. Reconciling corrections and deletions closed the loop.

None of these were exotic. All four were the specific, boring kind of bug that only exists once there are two devices with two independently evolving local caches — exactly the case a lone developer testing on one phone cannot produce, however careful the simulator work is.

Also since issue #02

Sep 5

A visual direction, chosen and kept

Two alternate visual concepts were proposed and rejected in favor of refining what already existed — charcoal, saffron, serif titles, the floating pill navigation — rather than replacing it. First build installed on a real device the same day.

Sep 7

Capture now, review later

The composer used to demand a full verdict — rating, notes, tags — in one sitting. It now leads with the photo and lets you save an unfinished draft with no rating at all, resumable from a persistent “finish your review” list. Publishing still requires a rating and still updates the existing review rather than creating a duplicate.

Sep 12

Screens that bounced back on tap

Opening a review or profile would sometimes flash open and immediately pop back. Every push had been keyed on the whole model value; a background refresh changing any field on that value changed its identity mid-navigation, and SwiftUI dropped a screen it could no longer match. Fixed everywhere at once by switching to id-only route values.

Sep 13
TestFlight build 16

The restaurant page, rebuilt

The flat menu list is gone. A restaurant page is now a title block, a rating-and-reviewers row, a search field, and a single-open accordion where each dish expands to who rated it and what they said. Averages show as “4.5 (2)” — the number and how many reviews it’s built from — because rounded stars couldn’t tell “5 and 4” from “5 and 5.” A place Apple Maps knows about but Palate doesn’t yet opens the exact same page, empty, and resolves into the real thing the moment it’s added.

Before this can go public

TestFlight is invite-gated and forgiving. An actual App Store listing is not, and a few things are scoped but not yet built:

  • Account deletion. “Reset local data” only clears the device today; it doesn’t touch the server account. The real version needs a schema change so a deleted account doesn’t break the shared restaurant/dish catalog other people still reference, a privileged server-side delete a client can never issue itself, and storage cleanup for photos. A privacy policy is already live in preparation for this.
  • The “want to try” wishlist and food-themed invite codes from issue #02’s list — both still queued, neither started.

Questions about this build?

I’d be glad to hear what stood out, what you’d change, or what you’d like covered next.

Send a note

Opens your email app.

Back to all quests two phones, one graph