Jetstream Built-in Teams vs Custom Hierarchical Multi-tenancy for Nested Organizations
0 reputation · 07 Oct 2021, 00:22 UTC
Context
Laravel Jetstream ships with a first-party Team feature that models a flat many-to-many relationship between users and teams via a team_user pivot table. The active context is tracked by a current_team_id column on the User model, and authorization relies on Gates and Policies scoped to that single active team. This design assumes each user belongs to one active team at a time and does not natively represent parent-child team hierarchies or organizational units nested within other teams.
Constraint
The application must support organizations that contain multiple divisions, each with their own sub-teams, where permissions cascade from parent to child and users may hold different roles at different levels of the hierarchy simultaneously.
Trade-off
Extending the built-in pivot table with additional columns (e.g., parent_team_id, hierarchy_path) keeps the Jetstream authentication and session workflow intact but requires overriding core methods such as currentTeam and rewriting policy checks to traverse the hierarchy. Building a separate multi-tenancy layer (e.g., using a package like stancl/tenancy or a custom tenant resolver) cleanly isolates hierarchical logic but introduces a second tenancy context that must stay synchronized with Jetstream's current_team_id for features like team-scoped API tokens and UI switching components.
Which approach better balances long-term maintainability with the least friction against Jetstream's existing team-switching UI, invitation flow, and API token scoping?