
React Router 7
Shopify App Bridge
Shopify Admin GraphQL
Prisma
Postgres (Supabase)
Vercel
Status
In build, not yet submitted. The app is registered, the install and authentication flow is in place, merchant data is isolated in its own schema, and the mandatory privacy webhooks are implemented and tested.
Still ahead: the three reports rebuilt against Shopify's embedded UI, Shopify-native billing, and App Store submission.
Series
Avnzor — Part 5 of 5 · The spin-out
Role
Product designer & engineer
Year
2026
Industry
E-commerce operations · SaaS product
Stack
React Router 7 · Shopify App Bridge · Shopify Admin GraphQL · Prisma · Postgres · Vercel
Links
Status: In build — not yet submitted to the Shopify App Store. Everything below is design and engineering decisions, not measured outcomes.
The Problem
Pulse solved a problem that is not unique to Avnzor — but I had built it as though it were.
The internal dashboard reads Avnzor's Shopify store, but it also reads a MySQL warehouse database, a consignment supplier's stock feed, in-transit purchase orders, weather data and competitor prices. That mix is exactly what makes it sharp for one merchant and impossible for any other merchant to install.
Every Shopify merchant holding inventory has the same four questions Pulse was built to answer. The work here is separating the part of the system that only needs Shopify from the part that needs Avnzor — and turning the first half into something a stranger can install in two clicks.
In build: OAuth and embedded session handling, per-merchant data isolation, the mandatory privacy webhooks, and Shopify-native billing.
Key Decisions
Ship a wedge, not the dashboard
Context: The internal Pulse is twenty-eight pages, and most of them read data no other merchant has — a MySQL warehouse, a consignment supplier’s feed, in-transit purchase orders, weather, competitor prices. The question that scoped the product was which of those pages would still work on a store I had never seen.
Choice: Three reports — Stock Risk, Sell-Through, Top Sellers — instead of twenty-eight pages. One clear job, a small support surface, and room to learn what merchants actually ask for before building more.
Trade-off: The features that make Pulse sharp for Avnzor are exactly the ones that cannot travel. What ships is only the part built on the Admin API every merchant already has.
Adopt Shopify’s app framework rather than porting the Next.js build
Context: I had already hand-written OAuth, token encryption and webhook verification for the internal build, and all of it worked.
Choice: Shopify’s React Router template provides those as maintained library code, plus embedded session tokens and the Billing API. They are the fiddly, security-sensitive parts, and the parts where App Store reviews fail. Throwing away working code was the cheaper decision.
Trade-off: Working code discarded, and the app now moves at the template’s pace and conventions rather than my own.
Isolate merchant data at the schema level
Context: One database serving many merchants, where an erasure request has to be provably complete rather than probably complete.
Choice: Every merchant-scoped table carries a tenant reference with a cascading delete, so an erasure request is a single statement that cannot silently miss a table.
Trade-off: Every future table inherits the obligation. The guarantee holds only as long as the discipline does.
Treat compliance as build work
Context: The three privacy webhooks are a submission requirement, and reviewers probe them with a deliberately invalid signature.
Choice: Tested code with an audit trail, not a checkbox.
Trade-off: Engineering time spent on a surface no merchant will ever see or pay for.
More Projects






