inertia start
Features

Teams

Multi-team support with role-based access control.

Opt-in feature

The Teams feature is available on the teams branch of the Inertia Start repository. It is not included in the main branch. If you don't need teams, you can work directly from main. To use this feature, start your project from the teams branch.

Inertia Start's Teams feature provides full multi-team (organization) support. Every user automatically gets a personal team, and can create or join additional teams. A role-based permission system controls what each member can do within a team.

Features

  • Personal Team: Every user gets a personal team automatically upon registration.
  • Multiple Teams: Users can create and belong to multiple teams simultaneously.
  • Team Switching: Switch between teams from anywhere in the app using the team switcher.
  • Role-Based Access: Three roles (Owner, Admin, and Member) with granular per-action permissions.
  • Member Management: Owners and Admins can invite, update roles, and remove members.
  • Email Invitations: Invite people by email. Invitations expire after 3 days and are validated on acceptance.
  • Safe Deletion: Deleting a team gracefully reassigns all affected members to their fallback team.
  • App Admins Team: A dedicated reserved team for application administrators, separate from regular teams.

Roles & Permissions

Regular Teams

Teams use three roles:

RoleLevelPermissions
Owner3All permissions (update team, delete team, manage members, manage invitations)
Admin2Update team name, create and cancel invitations
Member1View team (read-only)

The Owner role is assigned to the team creator and cannot be reassigned. Admins can invite new members as Admin or Member, but cannot promote anyone to Owner.

App Admins Team

The App Admins team uses its own set of roles, separate from regular team roles:

RolePermissions
Super AdminUpdate team, create and cancel invitations. Bypasses all non-team-scoped authorization gates.
AdminNo team-management permissions. Accesses the admin area without bypassing gates.

All users present in the App Admins team are granted access to the admin area. Additionally, those having the Super Admin role bypass all non-team-scoped authorization gates, giving them full application access (see in app/Providers/AppServiceProvider.php). Team-scoped gates (actions within a specific team) are deliberately not bypassed, so Super Admins still follow normal team permissions when acting within a team.

How It Works

Personal Team

Every user is automatically assigned a personal team at registration. The personal team:

  • Cannot be deleted.
  • Always serves as a fallback when another team is deleted.
  • Is marked with is_personal = true in the database.

Creating a Team

Users can create a new team from the Teams section in their account, or from the team switcher. Each team gets a unique name and a URL-friendly slug auto-generated from that name (duplicates are handled by appending a number, e.g. my-team-2).

After creation, the new team becomes the user's active team.

Switching Teams

The team switcher lists all teams the user belongs to. Clicking a team sets it as the current team (the app scope updates immediately).

Inviting Members

Team Owners and Admins can invite people from the team settings page:

  1. Click Invite Member and enter the invitee's email address and desired role (Admin or Member).
  2. The invitee receives an email with a secure acceptance link (valid for 3 days).
  3. The link requires the recipient to be authenticated with a matching email address.
  4. Upon acceptance, the user is added to the team and automatically switched to it.

Pending invitations are listed on the team settings page. They can be canceled at any time before acceptance.

Managing Members

From the team settings page, Owners and Admins can:

  • Update roles: Change a member's role between Admin and Member.
  • Remove members: Remove a member from the team. The removed user is not deleted (they simply lose access to that team).

Leaving a Team

Any team member can leave a team from the team settings page, subject to these rules:

  • Personal teams cannot be left.
  • Regular team members and Admins can leave at any time.
  • Regular team Owners can only leave if at least one other Owner remains on the team. This prevents a team from being left without an owner.
  • App Admins team: any member can leave, except the last Super Admin. There must always be at least one Super Admin in the application.

When a member leaves, they are immediately removed from the team and switched to their next available team.

Deleting a Team

Only Owners can delete a non-personal team, and only after confirming by typing the team name exactly. When a team is deleted:

  • All other members currently viewing that team are automatically switched to their personal team or next available team.
  • All pending invitations are removed.
  • All memberships are removed.
  • The team is soft-deleted (preserving historical data).

App Admins Team

The App Admins team (slug: app-admins) is a reserved team that separates application-level administration from regular team management. Members of this team can access the admin area of the application.

Initial Setup

During the initial Super Admin setup flow, the first Super Admin is automatically added to the App Admins team with the Super Admin role. The team is created automatically at this point if it doesn't already exist.

Inviting Admins

Super Admins can invite other users to the App Admins team from the team settings page. Two roles are available:

  • Super Admin: Full application access, can manage the App Admins team (invite members, cancel invitations).
  • Admin: Access to the admin area, without bypassing authorization gates or managing the App Admins team.

Admin Area Access

The admin area is protected by the IsAdmin middleware, which verifies that the user is a member of the App Admins team.

Artisan Commands

Sync Team Roles

php artisan inertia-start:sync-team-roles

This command synchronizes the role and permission records in the database with the current role enum definitions (app/Enums/TeamRole.php and app/Enums/AppAdminTeamRole.php). It:

  • Ensures all TeamPermission values exist as permission records.
  • Ensures the App Admins team exists.
  • Creates, updates, and removes roles for every team to match the current enums.
  • Clears the permission cache before and after syncing.

Run this command after deploying changes that add, remove, or rename roles or permissions in the role enums. It is idempotent (safe to run multiple times).

Database Structure

The Teams feature adds three database tables:

TablePurpose
teamsTeam records (name, slug, is_personal, soft deletes)
team_membersPivot table linking users to their teams
team_invitationsPending and accepted invitations with expiry tracking

A current_team_id foreign key is also added to the users table to track the active team per user.

Role and permission data is stored via the spatie/laravel-permission package. Every role and permission record is tied to a specific team.

Routes

MethodRouteDescription
GET/account/teamsList all teams for the authenticated user
POST/account/teamsCreate a new team
GET/account/teams/{team}Team settings page
PATCH/account/teams/{team}Update team name
DELETE/account/teams/{team}Delete a team
POST/account/teams/{team}/switchSwitch to a team
POST/account/teams/{team}/invitationsSend a team invitation
DELETE/account/teams/{team}/invitations/{invitation}Cancel a pending invitation
PATCH/account/teams/{team}/members/{user}Update a member's role
DELETE/account/teams/{team}/members/{user}Remove a member from a team
DELETE/account/teams/{team}/leaveLeave a team
GET/team-invitations/{id}/{token}/acceptAccept a team invitation

Teams are resolved by slug in URLs. Invitations are resolved by ID and a 40-character token for security.

Getting Started

To use the Teams feature, start your project from the teams branch:

git clone --branch teams https://github.com/inertia-start/inertia-start.git

Or, if you already have the repository, switch to the teams branch:

git checkout teams

Then run the migrations to create the teams-related tables:

php artisan migrate

The migration includes a backfill step that automatically creates a personal team for every existing user.

On this page