glueful / thallo-tenancy
Multi-tenancy foundation for Thallo: tenant-owned schema, scoping, seed/sync and enablement as a capability pack.
Requires
- php: ^8.3
- glueful/extension-contracts: *
- glueful/framework: ^1.68.0
- glueful/thallo-contracts: v1.0.0-beta.58
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v1.0.0-beta.58
- v1.0.0-beta.57
- v1.0.0-beta.56
- v1.0.0-beta.55
- v1.0.0-beta.54
- v1.0.0-beta.53
- v1.0.0-beta.52
- v1.0.0-beta.51
- v1.0.0-beta.50
- v1.0.0-beta.49
- v1.0.0-beta.48
- v1.0.0-beta.47
- v1.0.0-beta.46
- v1.0.0-beta.45
- v1.0.0-beta.44
- v1.0.0-beta.43
- v1.0.0-beta.42
- v1.0.0-beta.41
- v1.0.0-beta.40
- v1.0.0-beta.39
- v1.0.0-beta.38
- v1.0.0-beta.37
- v1.0.0-beta.36
- v1.0.0-beta.35
- v1.0.0-beta.34
- v1.0.0-beta.33
- v1.0.0-beta.32
- v1.0.0-beta.31
- v1.0.0-beta.30
- v1.0.0-beta.29
- v1.0.0-beta.28
- v1.0.0-beta.27
- v1.0.0-beta.26
- v1.0.0-beta.25
- v1.0.0-beta.24
- v1.0.0-beta.23
- v1.0.0-beta.22
- v1.0.0-beta.21
This package is auto-updated.
Last update: 2026-09-24 12:25:27 UTC
README
Multi-tenancy (workspaces) for Thallo: several independent sites on one
install, one code base and one PostgreSQL database. This pack owns Thallo's side of it: which
tables are workspace-owned, the staged enablement flow that widens them, request scoping, tenant
seed/sync, public origins, and workspace purge. The glueful/tenancy engine provides the tenant
registry and row-level enforcement.
What it provides
- Enablement flow (
src/Enablement): a staged, resumable, locked state machine that adds a workspace column to every workspace-owned table, widens unique constraints and adopts existing data into a first workspace. It pauses for a restart and blocks writes while the schema changes. Disabling turns scoping off and keeps the widened schema. - Admin API under
/v1/admin(behindcontent_permission:tenancy.manage):GET /tenancy/status,GET /tenancy/diagnose,POST /tenancy/begin|confirm|retry|cancel|finalize|disable, full request resolution (/tenancy/resolution…), the public origin (/tenancy/public-origin), and workspace, domain and membership management under/tenants…and/domains…. - Admin screens: Settings › Workspaces runs the enablement flow and holds the platform switches. Once workspaces are on, the sidebar's Workspaces group adds All workspaces, Domains, Members and Roles.
- Console commands:
thallo:tenancy:status,thallo:tenancy:enable(--slug,--name,--owner),thallo:tenancy:disable,thallo:tenancy:diagnose, thethallo:tenancy:resolution:*commands,thallo:tenancy:tenant,thallo:tenancy:domain,thallo:tenancy:member,thallo:tenant:seed,thallo:tenant:sync,thallo:tenant:blocks:sync,thallo:tenancy:purge:recover,thallo:tenancy:hosts:sweepandthallo:tenancy:single-store:repair, all run asphp glueful ….
Turning it on
The pack ships with Thallo: glueful/thallo-core requires it at the same version and the project's
config/serviceproviders.php loads its provider. It registers the thallo.tenancy capability,
whose owning package is glueful/tenancy. A new install is one site with tenancy off.
Workspaces are turned on only through the enablement flow: Settings › Workspaces in the admin,
or php glueful thallo:tenancy:enable from a shell. The engine's enforcement provider is listed
under protected in config/extensions.php, so php glueful extensions:enable glueful/tenancy
refuses it, and the Extensions › Capabilities switchboard cannot turn it on either: while
enforcement is off, enabling there answers 409 with a remedy that points at Settings › Workspaces.
Documentation
docs/concepts/08-workspaces.md: what a workspace owns and what turning workspaces on costs.docs/operations/07-multi-site.md: the enablement stages, commands and how to undo them.docs/internal/operations/tenancy.md: provider model, purge recovery and signup operations.
Contributing
This repository is a read-only mirror, published from
glueful/thallo on every release; its main is overwritten
by the next split, so nothing can land here. Issues and pull requests belong in glueful/thallo,
where this code lives at packages/thallo-tenancy/.