Multi-tenant với Team Feature

Cách hoạt động

Spatie team feature cho phép phân quyền theo từng công ty (company). Mỗi role/permission được gắn với một company_id.

Khi bật 'teams' => true trong config, Spatie tự động:

  1. Thêm cột company_id vào bảng roles, permissions, và các bảng pivot
  2. Unique constraint: (company_id, name, guard_name) cho roles và permissions
  3. Tự động scope permissions theo team context

Cấu hình

// config/permission.php
'teams' => true,
'column_names' => [
    'team_foreign_key' => 'company_id',
],

Sử dụng

Gán role trong ngữ cảnh company

// Gán role không có team (global)
$employee->assignRole('admin');

// Gán role trong company cụ thể
$employee->assignRole('manager', company_id: 1);

Kiểm tra permission (tự động scope theo team)

// Kiểm tra trong company hiện tại của employee
$employee->hasPermissionTo('department.create');

// Kiểm tra trong company cụ thể
$employee->hasPermissionTo('department.create', company_id: 1);

Set team context

use Spatie\Permission\PermissionRegistrar;

// Set company context
app(PermissionRegistrar::class)->setPermissionsTeamId($companyId);

// Kiểm tra permission sẽ tự động dùng company context này
$employee->hasPermissionTo('department.create');

// Reset về null (global)
app(PermissionRegistrar::class)->setPermissionsTeamId(null);

Company scope check trong Controller

Ngoài Spatie permission check, controller cũng kiểm tra company scope để đảm bảo employee chỉ truy cập dữ liệu của công ty mình:

$user = employee_account();
$companyId = $user->getCompanyAttribute()?->id;

// Kiểm tra department có thuộc company của employee không
if ($department->company_id != $companyId) {
    return $this->error('Forbidden', 403);
}

Lưu ý

← Seeders Hướng dẫn sử dụng trong code →