Loading...

This is taking longer than expected.

Configure teams

The config keys and environment variables the team layer adds, with what each one changes.

The team layer is configured by a handful of keys on top of the base's. Everything below has a working default: change a key only when your product needs the other behaviour. The base's own keys are documented on its site, in The environment file and Configure your project.

Environment variables

Variable Default What it does
APP_ENABLE_MULTI_TEAMS true Whether a person can create and belong to several teams. With false the switcher is skipped and the person is sent to their only team.
TEAM_INVITATION_MODE approval_required What happens when a member is added who has no account: approval_required invites them to register, auto_provision creates the account. See Members and invitations.
TEAM_DATA_IMPORT_TIMEOUT 21600 How many seconds the server may spend checking or importing one team data package before it gives up. Keep your queue's retry_after above it. See Move team data between environments.
TEAM_DATA_EXPORT_DISK local Where exported team packages are put together and then wait to be downloaded. The default works when the web server and every queue worker share a disk; otherwise name a disk on a private bucket, never one anybody can read without a signed link. See Move team data between environments.
BILLING_TEAM_ENABLED true Registers the team billing adapter, so plans and add-ons attach to the team.
BILLING_USER_ENABLED false Registers the base's user billing adapter next to the team's, for a product that sells to people and to teams. See Team plans and billing.

The base's FEATURE_PLANS_ENABLED and FEATURE_ADDONS_ENABLED still decide whether plans and add-ons exist at all.

config/app.php

'home_route' => '/app',
'enable_multi_teams' => env('APP_ENABLE_MULTI_TEAMS', true),

'permissions' => [
    'dashboard admin' => 'web',
    'dashboard user' => 'web',

    // * Media permissions
    'retrieve media' => 'web',
    'create media' => 'web',
    'update media' => 'web',
    'delete media' => 'web',
    'retrieve media_folder' => 'web',
    'create media_folder' => 'web',
    'update media_folder' => 'web',
    'delete media_folder' => 'web',
    'browse media_folder' => 'web',

    // * Team permissions
    'retrieve members' => 'team',
    'create members' => 'team',
    'update members' => 'team',
    'delete members' => 'team',
    'edit settings' => 'team',
    'manage plans' => 'team',
    'manage media' => 'team',

    // * Ticket permissions
    'answer ticket' => 'web',
    'view_team ticket' => 'team',
    'use assistant' => 'web',
],

'team_restricted_permissions' => [ // Team permissions the owner must NOT receive on signup
],

'team_owner_role' => 'administrator',
'team_default_role' => 'user',
'team_roles' => [
    'user' => [
        'retrieve members',
    ],
],
Key What it does
home_route Where a signed-in person lands: the team list, which opens the remembered team straight away. The base sets it to its own dashboard.
enable_multi_teams Read from APP_ENABLE_MULTI_TEAMS, above.
permissions Every permission, with its guard. The eight on the team guard are the ones the shipped team screens check; the web ones belong to the admin panel and the account. Add yours here with 'team' as the guard and seed; the seeder creates the permission but gives it to no role, so the existing teams need a migration, as Team roles and permissions explains.
team_restricted_permissions Team permissions the owner role of a new team does not receive. Empty as shipped, so the owner role gets every team permission.
team_owner_role The name of the role created in each team with every team permission except the restricted ones, assigned to the creator.
team_default_role The role every member added later receives. It must be one of the keys of team_roles.
team_roles The roles created inside each new team, each with the permissions it starts with.

See Team roles and permissions for how the role keys play together.

config/teams.php

'invitation_mode' => env('TEAM_INVITATION_MODE', 'approval_required'),

'data_import' => [
    'timeout' => (int) env('TEAM_DATA_IMPORT_TIMEOUT', 21600),
    'watch_seconds' => 15,
    'max_parts' => 10000,
],

'data_export' => [
    'budget_seconds' => 3,
    'chunk_rows' => 500,
    'tries' => 3,
    'stalled_after' => 3600,
    'keep_days' => 7,
    'disk' => env('TEAM_DATA_EXPORT_DISK', 'local'),
],
Key What it does
invitation_mode Read from TEAM_INVITATION_MODE, above.
data_import.timeout Read from TEAM_DATA_IMPORT_TIMEOUT, above.
data_import.watch_seconds When an import ends and its window asked for news within these seconds, the result is shown there; otherwise the person who started it gets a notification in the product.
data_import.max_parts The most parts S3 joins into one file. Times the upload part size, it is the largest package a bucket accepts.
data_export.budget_seconds How many seconds of work each step of an export does before it leaves the rest to the next step. An export is put together in many short steps, so your queue needs no special setting for it.
data_export.chunk_rows How many records each step of an export reads at most.
data_export.tries How many times a step of an export that fails is tried again before the export fails.
data_export.stalled_after How many seconds an export may go without moving forward before it is given up as interrupted, so the team can export again.
data_export.keep_days How many days an exported package can be downloaded before it is deleted.
data_export.disk Read from TEAM_DATA_EXPORT_DISK, above.

config/permission.php

'teams' => true,
'column_names' => [
    'team_foreign_key' => 'team_id',
],

Spatie Permission's teams mode, already on. team_id is the column added to roles, model_has_roles and model_has_permissions by the kit's migrations, and the value 0 in it means the global context of the admin panel. Leave both as they are unless you rename the column, in which case rename it in the migrations too.

packages/billing-team/config/billing-team.php

'enabled' => env('BILLING_TEAM_ENABLED', true),
'model' => App\Models\Team::class,
'owner_resolver' => null,
'plan_limits' => App\Classes\TeamPlanLimits::class,
'plan_features' => App\Classes\TeamPlanFeatures::class,
'user_billing_enabled' => env('BILLING_USER_ENABLED', false),
Key What it does
enabled Read from BILLING_TEAM_ENABLED.
model The model that owns a billing account: the team.
owner_resolver A class that answers which team is being billed in the current request. null uses the team() helper, which is right for every screen under /team.
plan_limits The class whose public methods count each limit for a team.
plan_features The class whose public methods declare the capabilities a team can buy.
user_billing_enabled Read from BILLING_USER_ENABLED.

What stays as in the base

Sign-in identities, verification, mail, SMS, storage, the AI provider, tracking, referrals and the public site keep the base's keys and meaning. Nothing about a team changes how a person signs in or which language they read.

Back