Good. One edit: drop the repo codename and backticks, collapse the redundancy in that sentence. Everything else stays. Here's the cleaned post:
TLDR: Swipe-to-delete fired instantly. One fat-thumb swipe and a real KOL contact — warmth score, notes, relationship history — would have been gone. Adding a confirmation sheet before the delete call took 20 minutes. Worth every second.
the setup
We're building a Swift iOS companion to the web-based KOL CRM — a Key Opinion Leader relationship manager, our contacts + scheduling app for an ecommerce business's outreach team.
Everyone wanted swipe-to-delete on the contacts list.
Natural. Native. Expected iOS behavior.
Took maybe an hour to wire up. Ship it.
what we shipped first
The first version did exactly what a quick implementation does.
- Swipe left on a row
- Red "Delete" button appears
- Tap it → gone. Instantly. No friction.
Which sounds right — until you realize the list is full of real people.
Real warmth scores. Real notes. Real relationship history synced back to Supabase (our Postgres database). And zero undo.
the wall we hit
So what's the actual problem here? GREAT question.
The problem isn't the swipe — it's what happens after.
One accidental tap on that red button, maybe while scrolling, maybe while handing your phone to someone — and a KOL contact with months of context behind it just vanishes. No confirmation. No "wait, I didn't mean that." Row's gone, database row's gone, you're staring at the list wondering.
The risk is real. And on mobile, where thumbs are imprecise and swipes are easy to trigger, the default should always be cautious.
the fix that actually worked
Two commits told the story: ship the feature, then fix: topic rollback bug, stale contact list, and swipe-delete confirmations.
The fix is dead simple. When the user swipes and taps Delete, a confirmation sheet fires first:
"Delete [Name]? This can't be undone."
[Cancel] [Delete]
The actual DELETE call to Supabase only runs on confirm.
One extra tap. That's it.
I'd already learned the parallel lesson on the web side — never reach for window.confirm() for destructive flows in a browser UI. Chrome's "block dialogs" setting can silently kill it, and then the delete goes through with no gate at all. Use an in-app Dialog component with real Cancel + Confirm buttons.
Different platform. Same principle. Gate the destructive action with real UI.
why this matters to me
Supabase's own SQL editor gets this right. Run a DROP or DELETE query and it stops you cold — "This query includes destructive operations." Nothing fires until you explicitly click Run query.
Not annoying. Correct.
And this pattern has saved me from real disasters. A few weeks back I was automating DNS updates in Cloudflare — an unscoped selector accidentally grabbed a table-row checkbox instead of the proxy toggle and selected 19 records — one click away from deleting 19 DNS entries at once. The only thing that saved me was catching it before I confirmed.
Confirmations aren't friction. They're the moment where the computer checks in before doing something that can't be undone.
If your UI has a destructive action and it fires on first touch — that's a bug waiting to happen.
Add the confirmation. 20 minutes now beats a very bad afternoon later.