callcocam/inertia-rbac 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

callcocam/inertia-rbac

Composer 安装命令:

composer require callcocam/inertia-rbac

包简介

RBAC (roles & permissions) para Laravel + Inertia + Vue, com ULID, catálogo de permissões como fonte única e Wayfinder para o frontend.

README 文档

README

RBAC (roles & permissions) para Laravel + Inertia + Vue, construído sobre o spatie/laravel-permission com:

  • ULID em roles, permissions, pivots e morph keys.
  • Catálogo de permissões como fonte única (PermissionName), com metadata PT-BR.
  • Controllers no pacote (CRUD + sync) — o app não copia controller.
  • Páginas Vue no projeto — o pacote não traz .vue; você cria os componentes no visual do seu app e as ações usam os controllers do pacote via Wayfinder.
  • Teams (multi-tenant) opcional, reaproveitando a config de teams do Spatie.
  • Rollout gradual (rbac.enabled) e super-admin por system_name.

Filosofia: visual do projeto, ações do pacote. O HTML/estilo é 100% seu; o endpoint que processa cada ação é o controller do pacote.

Requisitos

  • PHP 8.3+
  • Laravel 12+/13+
  • Inertia v2+ (@inertiajs/vue3)
  • spatie/laravel-permission ^8.0 (instalado como dependência)

Instalação

composer require callcocam/inertia-rbac

# Config do pacote (só o específico do RBAC — o resto reusa o config do Spatie)
php artisan vendor:publish --tag=rbac-config

# Migrations com ULID (config-driven)
php artisan vendor:publish --tag=rbac-migrations

# (opcional) publicar o config do Spatie, se quiser editá-lo à mão
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag=permission-config

php artisan migrate

php artisan rbac:sync   # popula as permissões do catálogo

# roles de sistema (super-admin, admin) — publique o seeder e rode:
php artisan vendor:publish --tag=rbac-seeders
php artisan db:seed --class="Database\Seeders\RbacSeeder"

Reaproveitando a config do Spatie

O pacote alinha automaticamente o config/permission.php do Spatie no boot:

  • permission.models.roleCallcocam\InertiaRbac\Models\Role
  • permission.models.permissionCallcocam\InertiaRbac\Models\Permission
  • quando rbac.teams.enabled = true: liga permission.teams e define permission.column_names.team_foreign_key a partir de rbac.teams.foreign_key.

Ou seja: tabelas, colunas, cache, guards e teams core continuam no Spatie; o config/rbac.php só cobre views Vue, rollout, roles protegidas, redirects e rotas.

Preparar o model User

use Callcocam\InertiaRbac\Concerns\HasRbac;

class User extends Authenticatable
{
    use HasRbac; // HasRoles (Spatie) + HasUlids + isSuperAdmin()
}

O id do User deve ser ULID (as morph keys do RBAC são ULID).

Declarar as permissões do seu app

O catálogo do pacote traz só as permissões de gestão (roles.*, permissions.*). As suas você declara em config/rbac.phpPermissionName::all() mescla as duas:

// config/rbac.php
'permissions' => [
    'products.viewAny', 'products.view', 'products.create', 'products.update', 'products.delete',
    'orders.viewAny', 'orders.view',
],

// opcional: classificar recursos por tipo/contexto
'type_map' => ['products' => 'catalog', 'orders' => 'sales'],

Depois rode php artisan rbac:sync (ou o botão de sync na tela de permissões).

Policies dos recursos do seu app

Use o trait do pacote, que já respeita o rollout (rbac.enabled) e o super-admin:

use Callcocam\InertiaRbac\Concerns\ChecksRbacPermission;

class ProductPolicy
{
    use ChecksRbacPermission;

    public function viewAny($user): bool { return $this->allowByContext($user, 'products.viewAny'); }
    public function create($user): bool  { return $this->allowByContext($user, 'products.create'); }
    // ...
}

O Gate::before de super-admin (por system_name) já é registrado pelo pacote.

Páginas Vue (criadas no seu projeto)

O pacote não traz .vue. Crie os componentes nos caminhos de config('rbac.views.*') (default abaixo) em resources/js/pages/:

Config Componente default
rbac.views.roles.index rbac/roles/Index
rbac.views.roles.form rbac/roles/Form
rbac.views.permissions.index rbac/permissions/Index
rbac.views.permissions.form rbac/permissions/Form

Publique os stubs de referência e adapte ao visual do seu app:

php artisan vendor:publish --tag=rbac-stubs
# copia para base_path('stubs/inertia-rbac/...') — use como ponto de partida

Pontos-chave dos stubs:

  • Index: paginator chega como prop deferida (<Deferred> + skeleton). Botão "Novo" com v-if="can.create". Excluir por linha só com v-if="!row.is_protected".
  • Form: um único componente para create e edit; system_name/name imutáveis no edit; picker de permissões por type.

Wayfinder — ligando a UI às rotas do pacote

As ações nunca montam URL na mão: usam helpers gerados pelo laravel/wayfinder a partir das rotas nomeadas do pacote (rbac.roles.*, rbac.permissions.*).

composer require laravel/wayfinder --dev
npm install -D @laravel/vite-plugin-wayfinder
// vite.config.ts
import { wayfinder } from '@laravel/vite-plugin-wayfinder'

export default defineConfig({
  plugins: [/* laravel(), vue(), */ wayfinder({ formVariants: true })],
})
php artisan wayfinder:generate --with-form
import RoleController from '@/actions/Callcocam/InertiaRbac/Http/Controllers/RoleController'

RoleController.index.url()          // GET  index
RoleController.edit.url(role.id)    // GET  edit
// <Form v-bind="RoleController.store.form()">          (create)
// <Form v-bind="RoleController.update.form(role.id)">  (edit)

Se o gerador não rastrear os controllers do vendor, veja o fallback na seção "Wayfinder" do arquivo PROMPT.md.

Mostrar/esconder (server-driven)

  1. Botões por página: cada index já envia can: { create: boolean }. Use v-if="can.create". Ações de linha: v-if="!row.is_protected".
  2. Menu: decida os itens no servidor com o PermissionResolver:
use Callcocam\InertiaRbac\Support\PermissionResolver;
use Callcocam\InertiaRbac\Models\Role;

$resolver = app(PermissionResolver::class);

$menu = array_values(array_filter([
    $resolver->allows($user, 'viewAny', Role::class)
        ? ['label' => 'Papéis', 'href' => RoleController::index()] : null,
]));

Assim os itens não autorizados nem chegam ao cliente.

Configuração (config/rbac.php)

Chave Para quê
enabled Liga/desliga a checagem (rollout gradual).
guard Guard das roles/permissions.
connection Conexão isolada (ex.: landlord), ou null.
teams.enabled / teams.foreign_key Multi-tenant (espelha para o Spatie).
protected_roles / protected_permissions Não podem ser apagadas/renomeadas.
super_admin_role system_name da role com Gate::before.
permissions / type_map Catálogo do app + classificação por tipo.
views.* Caminhos dos componentes Vue.
routes.* / redirect.* Prefixo, nome, middleware e redirects.
per_page Paginação das telas.

Teams / multi-tenant (escopo de permissões por tenant)

O nome "teams" vem do Spatie e pode confundir: não é um recurso de "grupos de usuários", e o Laravel não tem teams nativo. rbac.teams liga a teams feature do Spatie = escopo de permissões por tenant: adiciona uma coluna team_foreign_key em roles/model_has_* para você ter roles/permissões diferentes por tenant. Não cria tabela teams nem model Team. Por isso não conflita com nada do framework.

Está desligado por padrão (single-tenant). Para ligar:

// config/rbac.php
'teams' => [
    'enabled' => true,
    'foreign_key' => 'tenant_id',                             // coluna de tenant nas tabelas do Spatie
    'resolver' => fn ($request) => $request->user()?->tenant_id, // null = lê a foreign_key do usuário
],

Isso liga o middleware SetPermissionTeamContext no grupo de rotas e espelha permission.teams / permission.column_names.team_foreign_key. A resolução do tenant atual é do app (por padrão o middleware lê a foreign_key do usuário autenticado; use resolver para buscar de outro lugar).

O Spatie suporta um team_foreign_key global. Se o app já usa a teams feature do Spatie para outra coisa, os dois precisam concordar no mesmo nome de coluna.

Testes

composer test        # Pest + Orchestra Testbench (SQLite em memória)
composer format      # Laravel Pint

Licença

MIT. Veja LICENSE.md.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-07-09

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固