How do you handle P2P transactions when there’s no delivery system and no platform-controlled handoff?
That was the core problem behind Loopa.
Physical exchanges are messy. People change plans, meet late, ghost, or confirm things out of order. In that context, a simple status: "completed" field isn’t just naive, it’s dangerous. It creates race conditions and edge cases you only discover once trust is already broken.
I built a centralized State Machine.
Each transaction moves through explicit states with strictly defined transitions in TypeScript. There’s no “jumping ahead.” Success is gated: the system only allows it when both parties independently confirm the physical exchange. No UI shortcuts. No database flag flips.
All business rules live in state handlers, completely isolated from the Next.js App Router. Components never touch the database directly. The UI reacts, the engine decides.
By pairing this with Supabase Realtime for chat, the system stays predictable even when human behavior isn’t. The rules don't bend just because the physical meeting is chaotic.
The real lesson wasn’t about the tools. It was about designing software that assumes people are human and keeps the system's integrity intact anyway.
How are you handling "human variables" in your logic?
Top comments (0)