Jonathan Bayo
All case studies
ProductClient2 min read

Multi-tenant buyer intent product

The sales intelligence client wanted to sell the signals as a product, not a service. In three weeks the demo screens became a tenant app with accounts, workspaces, invites, roles, trials, an isolation harness that runs before every release, and an assistant that answers questions about the workspace's own data.

3 wksdemo to MVP
0.5.0on production
29/29isolation checks
300requests, 0 errors
Built
three weeks, demo to MVP
Tenancy
one lake, org id on every row, RLS backstop
Isolation
29 checks, run before every release
Client
B2B sales intelligence company

Why it exists

The pipeline above produced the data. The client needed other companies to be able to log in and see only their own slice of it, invite their team, rate signals and get a brief, without any of it leaking across workspaces. And it had to be demoable to partners in under two weeks.

How it runs

Request path
Trigger
Browser
session cookie
Transform
App
Python, own container
Transform
Policy
org membership, role
Fetch
Supabase
per request JWT, RLS
AI
Ask
Sonnet, ten scoped tools
Store
Audit
every write logged
  1. Auth

    Extended the client's existing password auth rather than adding a vendor: invites and resets by email, sessions with a version number so a revoke logs everyone out, a 90 day hard cap, roles per workspace.

  2. Tenancy

    Every row carries the workspace id. The app injects it server side on every query, and as a second line the database enforces row level security with a token minted per request. Both were proven at the database: the right workspace reads its rows, a bogus one gets nothing, a forged token gets a 401.

  3. Isolation harness

    29 HTTP checks that try to read across workspaces as a stranger, a member, an admin and a former member. It runs before every release and has to be green.

  4. Release gate

    A scripted browser walk through the product, a dependency scan and the harness. A release that fails any of them doesn't ship. Five releases went through it in the first three weeks.

  5. Fail soft

    Built during a live database incident. Store errors show a one moment page instead of a broken product, the dataset is served stale while a refresh runs in the background, and a disk copy survives a restart. Two uptime monitors watch it, one inside the box and one on GitHub.

  6. Ask

    An assistant inside the app on Claude Sonnet with ten read only tools that only see the workspace's own data. Twenty questions an hour per person, sixty a day per workspace, thirteen out of thirteen on the eval.

What came out of it

The product went from a set of demo boards to release 0.5.0 on production in three weeks, with the partner demo made and testers on a staging copy. A stress run of 300 concurrent requests came back with no errors and isolation held.

Notes

The whole app is Python standard library, no framework, which the client's ops setup made the right call. One thing that bit: with strict tool schemas where every field is required, Sonnet fills the fields it doesn't need with fragments of its own tool markup. Optional fields are nullable now and inputs are scrubbed.

Stack

Want something like this built?

Tell me what you're trying to automate. Most things can be built in a week or two.