A public audit that does not call the model from the browser

ShopGuide Audit Tool

The browser never talks to the model.

The problem

The browser must not hold the model key. A slow generation must not look stuck.

The product is a public audit tool for Shopify stores. A merchant pastes a URL, answers a short survey, and receives a report. Two constraints shaped the design. The browser must not hold the model key — an earlier version that called the API directly from the client was migrated to a serverless route. And a generation that takes a minute or more cannot show a progress bar that completes before the work does, or the interface looks stuck.

serverless route
1serverless route
providers
2providers
model keys in the browser
0model keys in the browser

How it works

The browser never talks to a model. Both providers are called from a serverless route holding the keys — a migration from an earlier version that called the API directly from the client. Provider selection is a preference cascade rather than an ensemble: whichever provider is configured runs first, the other is tried on failure. Everything then passes through one normaliser, and the same normaliser runs again on the client, because reports persisted by earlier versions still have to render.

Engineering decisions

The non-obvious calls — where the straightforward approach fails, and what it cost to find that out.

01

Assume the model ignored the prompt

Why it breaks

Both providers are given the output shape and both are told explicitly not to recommend deploying a generic assistant when the store already has one. Models mostly comply. Mostly is not a guarantee.

What I did

A third layer runs after generation and assumes the first two were ignored: it pattern-matches recommendations that suggest deploying a generic assistant and removes them, substituting a canonical replacement step.

02

Capture the lead before doing the work

Why it breaks

Asking for an email before the audit reduces completion; asking only at the end loses every prospect who leaves while it runs.

What I did

The lead is written when the audit starts, with a blank email, so an abandoned session still produces a qualified row. If the visitor later asks for the report, the write merges into that same row rather than appending a second one.

Correctness in production

What keeps it right once nobody is watching it run.

Partial success as the default posture

The scraper returns empty content rather than throwing, so a blocked page degrades the audit instead of ending it. Each optional input has a defined absent state.

Unguessable identifiers for public reports

Persisted reports are public URLs, so the identifier is generated from a cryptographic random source over an alphabet with visually ambiguous characters removed.

Ready to upgrade your store's infrastructure?

Whether you want this exact architecture deployed to your store, or a completely bespoke solution built from scratch.

I want this exact solution.

Skip the R&D. I can deploy the ShopGuide Audit Tool architecture directly to your operations in days, not months.

I need something custom.

Have a unique workflow? Let's build a bespoke app tailored perfectly to your complex business needs.