Multi-tenancy is a seam problem, not a feature pro...
# wheels-dev
p
Multi-tenancy is a seam problem, not a feature problem. Wheels 4.0 puts the seam in the framework — the datasource resolver — so every model call, every association load, every background job routes by tenant automatically. <PR #1951 — Tenant-aware datasource switching> What that gets you: • In-core, not a plugin. Plugin-based tenancy catches about 80% of the data paths. The framework-level resolver catches the other 20% — the straggler query in a report action, the
CreateObject("java", ...)
that bypassed the ORM, the background job enqueued from a request that never asked "whose job is this?" • Three deployment models supported. Separate database per tenant (cleanest isolation, GDPR erasure =
DROP DATABASE
), shared database with separate schema (middle ground), shared database with row-level scoping (most discipline required). Pick by isolation requirement, not framework limit. • Tenant context restored on the worker side. A job enqueued in tenant A's request runs against tenant A's datasource when the worker picks it up — no
tenant_id
in payload, no
with_tenant(...)
wrapper. Pairs naturally with yesterday's post on the DB-backed queue — tenant-aware enqueueing falls out of this resolver design. Honesty clause from the post: don't use it for admin / ops consoles or cross-tenant reports. Those need a deliberate system datasource. The framework makes the right thing easy; it doesn't make the cross-cutting thing impossible. <Read the full post>