Skip to content

Data isolation and deployment models: what we can honestly offer ​

Part of car_sales — the dealership operating layer.

⚠ The headline finding, before the options

📘 Owner direction 2026-08-23: document every viable deployment model so an enterprise dealer conversation is "here are the models" rather than "take it or leave it." Right, and one of the four is not ours to offer yet.

🧮 We cannot reliably keep TWO environments in sync today. Measured on 2026-08-15: a migration authored on the 14th had never been applied to Dev (QRS-693), and four archived Edge Functions were still ACTIVE on Dev six days after being archived for writing dropped tables — two of them on the money path (QRS-694). Both found by reading the live database, because nothing compares a project against the repo.

Selling a dedicated environment is selling N environments kept in sync. At N=2 we have measured drift twice in one afternoon. QRS-856.

1 · The four models, and what each one actually means on this stack ​

⚠ 📘 The unit of isolation on Supabase is a project — Postgres plus Auth, Storage, Edge Functions and secrets — not a database. That single fact collapses the usual middle option.

A · Shared multi-tenantB · Dedicated databaseC · Dedicated instanceD · Fully dedicated
What it isOne project, RLS-isolated tenantsA separate database, shared appOwn project + own Worker deploymentOwn cloud, possibly the customer's
Status🟢 This is what exists🟠 Collapses into C — see below🟡 Buildable, gated🔴 Refused for now
DatabaseShared Postgres, RLSSeparateSeparateSeparate
AuthShared⚠ Separate too — it lives in the projectSeparateSeparate
StorageShared bucket, path-scoped⚠ SeparateSeparateSeparate
Edge FunctionsShared⚠ Deployed per projectSeparateSeparate
Migrations run against1 projectN projectsN projectsN projects
Secrets managed in1 placeN placesN placesCustomer's
FrontendOne deploymentOne deploymentOwn deploymentOwn
Marginal ops cost~0≈ CHighVery high
Suitable forEvery dealer today—A group with a procurement mandate❓ nobody we can serve

⚠ Why B collapses into C, stated plainly because it is counter-intuitive and it kills a tier people expect

"Shared application, separate database" is the standard middle option in most stacks. On Supabase it barely exists, because a project is not a database:

  • Auth lives in the project. A separate database means a separate user pool, so the same login cannot span both. 📘 That breaks the single-identity model the whole platform rests on.
  • Edge Functions deploy per project. 📘 The EF is our primary write-enforcement layer, so a second database means a second copy of every function and every secret.
  • Storage is per project. A second bucket, a second media base URL.
  • Only the frontend bundle is genuinely shareable — and it is the cheapest part.

🔎 So B delivers ~90% of C's operational cost for ~40% of its isolation story. It is the worst value-per-rupee of the four and should not be offered as a tier. If a dealer needs a separate database, they need C.

2 · Option A: what we can actually prove about isolation ​

🔎 This is the most commercially valuable section on the page, and it is not the dedicated options — it is the evidence that makes them unnecessary for most dealers.

ControlStateEvidence available in a sales conversation
Row-level isolation🟢 RLS on every user-facing table📘 Policies scope by relationship (workspace_id in (my_workspace_ids())), never by role alone
Proven negatives🟢 pgTAP suites🧮 "A logged-in user with no workspace membership can read nothing merchant-owned" is a test, not a claim
Least-privilege RPC grants🟢 gatedREVOKE ALL FROM PUBLIC + explicit GRANT EXECUTE, checked by npm run check:sql on every push
Table names off the wire🟢 conventionNo supabase.from() in app code; RPC and Edge Function only
Write enforcement🟢 two layersEdge Function primary, RLS defence in depth. Both always
Encryption🟢 platformAt rest and in transit, managed
Oversight privacy🟢 designed + proven⚠ An employer cannot see an employee's member_owned business, at any subtree depth
Backups🔵 managed daily⚠ PITR is a deferred decision, and an enterprise review will ask. Say so
Tenant audit trail🔴 does not exist⚠ The honest gap. See architecture validation §3.5
Data deletion / DPDP🔵 partialAccount and data deletion is a standard; per-tenant export is a contract commitment we should make

Sell the proof, not the iron

🔎 Most "we are not comfortable sharing infrastructure" objections are a request for evidence, not for hardware. A dealer who is shown a passing pgTAP suite that proves a stranger can read nothing, plus a written export commitment, is usually satisfied — and it costs us nothing.

⚠ Escalate to a dedicated model only when a procurement checkbox genuinely requires it, not when a technical objection can be answered. Every dedicated environment we sell is a permanent tax on a two-person team.

⚠ Two gaps to name before the dealer finds them

PITR and the tenant audit trail. 🔎 Naming a gap yourself converts it from a discovered weakness into a roadmap item, and both are cheap to close relative to a dedicated deployment. Bringing them up first is also the stronger negotiating position: it makes the isolation story credible rather than promotional.

3 · Option C: the shape, if a dealer genuinely requires it ​

ElementRequirement
DatabaseOwn Supabase project. Region chosen with the customer
AuthOwn user pool. ⚠ Their staff cannot also be users of the shared platform with the same login
Edge FunctionsDeployed per project. Same code, no forks
StorageOwn bucket, own media base URL
FrontendSame Worker build, own hostname, own environment vars
MigrationsThe same ordered set, applied to N projects, verified by read-back
MonitoringOwn Sentry project or own tag. Own uptime target
Backups / DRManaged daily minimum; PITR is a paid line here, not an assumption
SupportNamed contact, stated response time, enterprise SLA

⚠ The hard prerequisite: this cannot be sold before promotion is automated

📘 The pre-promotion checklist has seven lines, and today every one is answered by a human reading: migrations applied in both directions, the EF set equal to the repo's with no extras, secrets present, the client pointed at the right project, critical workflows passing against the target.

🧮 At N=2 that manual process has already produced two measured drifts. At N=5 it produces a customer incident. The automation is designed as QRS-696.

Prerequisite, stated as a gate: no dedicated deployment is sold until a single command can verify a target environment against the repo, in both directions, and print its output.

4 · Option D: refused, with the condition for revisiting ​

What was askedAn almost entirely dedicated environment for a highly sensitive group
Verdict🔴 Refused for now
Why🔎 Self-hosting Supabase or deploying into a customer's VPC means owning Postgres, Auth, Storage, a function runtime, upgrades and CVE response for someone else's infrastructure. That is a managed-services business, not a product line, and 📘 this repo already refuses the labour businesses that do not scale past two people
What we say instead"Option C gives you a dedicated database, auth pool, storage and functions in your chosen region, under a contract that names your data-export and deletion rights. Full self-hosting is not something we operate today."
Revisit whenThree signed Option C customers, an automated promotion pipeline, and a dedicated infrastructure engineer. All three, not any one

5 · The version-parity strategy ​

📘 The owner's concern is the correct one: "avoid creating a situation where every dedicated dealership becomes a completely different codebase."

The rule, and it is a generalisation of a decision this platform already made

📘 "A new vertical is configuration, not code." Extended:

A new TENANT is configuration, not code. One codebase, one migration set, many deployment targets.

⚠ A customer-specific code fork is refused, permanently. Customer-specific configuration — feature_grants, industry composition, palette, templates, plan limits — is unlimited and free.

ConcernPosition
Version management📘 One release.json per release, all targets. A dedicated project is another target row, not another release
ReleasesShared first, then dedicated targets on a controlled window the enterprise SLA names
MigrationsThe same ordered set everywhere. 📘 Expand-contract always — with multiple targets, a breaking change in one step is unrecoverable
Backward compatibility📘 Contraction is bounded by the oldest live app build across all targets. A dedicated tenant on a slow upgrade cycle raises that floor for everyone — ⚠ the real hidden cost of dedicated deployments
Feature rollout⚠ Needs feature flags, which do not exist (QRS-296). Without them a per-target rollout means branching code, which is the thing we refuse
Security patchesApplied to every target inside a stated window, ahead of the upgrade cycle. Non-negotiable in the contract
Bug fixesSame code, same pipeline. No hotfix that exists only on one target
CustomisationConfiguration only. If a request cannot be expressed as configuration, it becomes a product feature for everyone or it is declined
MonitoringPer-target dashboards; one alerting path
DRPer-target runbook; the same rollback mechanisms

⚠ The cost nobody puts in the proposal

🔎 A dedicated tenant on a controlled upgrade cycle becomes the slowest clock in the platform. Every contraction — a dropped column, a narrowed type, an EF signature change — waits for them. The price of a dedicated deployment therefore has to include the option value of the schema changes it delays, which is invisible at signing and painful at the second one. This is the strongest argument for keeping the count very small.

6 · Commercial shape ​

📘 The owner is right that this cannot use the shared-SaaS model. 🔎 Directional only — no dedicated customer exists and no infrastructure has been quoted.

LineShared SaaSDedicated (Option C)
InfrastructureIncluded⚠ Pass-through + margin. A dedicated project with real compute is 🔎 ₹1-3 lakh/yr before support
Implementation₹59,999-2,49,999Materially higher — provisioning, migration, verification, cutover
Annual platform fee₹79,999-2,99,999 per outletEnterprise-quoted
SupportStandardNamed contact, response-time SLA
UpgradesContinuousControlled window
CustomisationConfigurationConfiguration, contracted
DR / PITRManaged dailyA priced line

⚠ The floor, so nobody quotes a number that loses money

🔎 Infrastructure alone is ₹1-3 lakh/yr, and the operational overhead — N-target migrations, N secret sets, N monitoring surfaces, a controlled upgrade window and a named support contact — is 🔎 realistically 0.2-0.3 of a person. Against ~₹1,500/h loaded that is ₹5-9 lakh/yr of labour.

A dedicated deployment below roughly ₹8-12 lakh/yr is not a premium product; it is a subsidy.

❓ Every input here is unverified. The point is not the number — it is that the number is an order of magnitude above the shared SaaS book, so a dedicated deal must never be positioned as "Complete, but isolated."

7 · The decision tree for a dealer conversation ​

Signal from the dealerModelWhat to say
"Where is my data?"ARegion named, encryption, proven isolation
"Can another dealer see my customers?"A🧮 A passing test proves not. This is the strongest answer we have
"Our IT policy requires a separate database"C, if the gate is metEnterprise quote, own project, controlled upgrades
"We want it in our own cloud"D → declineOffer C with contractual data rights
"What if you go out of business?"anyExport commitment, and 📘 an escrow clause if they ask (O4)
"Give us the isolated version at the Complete price"⚠ refuseIt is an order of magnitude apart. Conceding here sets the market price for every future enterprise deal

💡 The capability this gives the sales conversation, which is the owner's actual objective

🔎 Being able to say "QR Setu supports multiple deployment models; based on your requirements we recommend this one" is worth more than any single model — it converts an objection into a qualification question.

⚠ And note the direction it usually resolves: most dealers who ask for isolation should end on Option A, because what they wanted was proof. The dedicated options exist so that the answer to "do you support it" is yes, not so that we sell many of them.