Take-Home · Part 3

Three decisions

Isolation, the eligibility score, and what breaks first at 300 clients. Short answers, each defended — and each naming what it gives up.

Decision 1

Isolation

Dedicated (silo) isolation per tenant — one deployment, one database per client

The key reason is Client C's regulatory requirement that data never leave infrastructure the clinic controls. A pooled architecture cannot guarantee that, even with RLS. Since regulated organizations are a core target market, I'm choosing the model that can serve all client types.

What I'm giving up, and who I lose

The tradeoff is cost and speed. Provisioning takes longer, infrastructure costs more, and maintenance scales with the number of tenants. I will lose price-sensitive, low-margin clients like a town that needs a cheap same-day pothole tracker. Pooling would serve those clients better, but it would exclude Client C and similar regulated clients. I'm betting the regulated market is more valuable.

Decision 2

The eligibility score

A tenant-scoped, versioned scoring definition, evaluated by one generic scoring engine

Where it lives

The formula structure is separated from its parameters: the structure changes infrequently, while weights and thresholds are configuration that the board can change per round without a deployment.

When the board changes it

Every change creates a new version, and each application is scored using the version active when it was submitted. I store the version, inputs, retrieved turnover value, and result so every decision is reproducible and auditable. If the registry API fails, I do not auto-reject; I send the application for human review.

When Client C asks for something similar but different

Client C uses the same scoring capability with different configuration and data sources. If genuinely new computation is required, I add a new versioned scoring plugin — not a client-specific code fork or if client == C.

Decision 3

What breaks first at 300 clients

The schema-migration and deploy pipeline — the control plane that must apply every change across 300 separate databases

Why that one

I chose silo isolation so tenants do not share a primary. The main scaling problem is now fan-out. Every client may need changes such as new fields, renamed statuses, or new roles. Each migration must be applied safely across 300 databases while keeping one codebase.

What I'd see when it happens

Longer deployments, partial rollouts, schema drift between tenants, and difficult rollbacks.

What I'd do

I would use backward-compatible expand/contract migrations, staged rollout waves with health checks, and centralized tracking of each tenant's schema version. Regulated and large tenants can have dedicated maintenance windows. I would also keep changes additive where possible — the existing custom_fields JSONB approach can handle many new fields without a migration. Silo removes noisy-neighbour database contention, but the tradeoff is that operational changes now cost 300×. That migration pipeline is the first thing I expect to fail.