Skip to content

arqel-dev/core — API Reference

Namespace Arqel\Core\. Pacote raiz: Resources, Panel, Inertia bridge, controller HTTP.

Resources

Arqel\Core\Resources\Resource (abstract)

Base para Resources do utilizador. Subclasses só precisam declarar protected static string $model e public function fields(): array.

MétodoTipoDescrição
getModel()class-string<Model>Class FQN do model. Lança LogicException se $model não declarado
getSlug()stringSlug derivado do nome (UserResourceusers) ou override $slug
getLabel() / getPluralLabel()stringLabels auto-derivados ou override
getNavigationIcon() / getNavigationGroup() / getNavigationSort()?string / ?string / ?intSidebar metadata
fields()array<Field>Lista de fields (abstract — declarar)
table()mixedOpcional. Retornar Arqel\Table\Table quando precisar custom
form()mixedOpcional. Retornar Arqel\Form\Form quando precisar custom
actions()array<Action>Opcional. Default vazio
recordTitle(Model) / recordSubtitle(Model)string / ?stringIdentificador exibido em breadcrumbs/modais
indexQuery(Builder)BuilderHook para escopar listagem

Lifecycle hooks (todos protected, override na subclass):

php
beforeCreate(Model $record, array $data): void
afterCreate(Model $record): void
beforeUpdate(Model $record, array $data): void
afterUpdate(Model $record): void
beforeSave(Model $record, array $data): void   // create OR update
afterSave(Model $record): void
beforeDelete(Model $record): void
afterDelete(Model $record): void                // só dispara se delete() retornou truthy

Orchestrators (públicos, chamados pelo ResourceController):

php
runCreate(array $data): Model
runUpdate(Model $record, array $data): Model
runDelete(Model $record): bool

Arqel\Core\Resources\ResourceRegistry (final)

Singleton. Bound automaticamente em ArqelServiceProvider.

MétodoDescrição
register(class-string)Registra Resource. Valida is_subclass_of HasResource
registerMany(array<class-string>)Bulk
discover(string $namespace, string $path)Auto-discover via PSR-4 + Symfony Finder
findByModel(class-string<Model>)?class-string<Resource>
findBySlug(string)?class-string<Resource>
has(class-string) / clear() / all()Utilitários

Panel

Arqel\Core\Panel\Panel (final)

Builder fluente. Cria via PanelRegistry::panel($id).

php
$panels->panel('admin')
    ->path('admin')
    ->brand('Acme')
    ->theme('default')
    ->primaryColor('#6366f1')
    ->darkMode(true)
    ->middleware(['web', 'auth'])
    ->resources([UserResource::class])
    ->widgets([])
    ->navigationGroups([])
    ->authGuard('web')
    ->tenant(null);   // Phase 2

Cada setter retorna $this. Getters tipados existem para todos: getPath(): string, getBrand(): ?string, etc.

Arqel\Core\Panel\PanelRegistry (final)

Singleton. Métodos: panel(id): Panel (create-or-get), setCurrent(id), getCurrent(): ?Panel, all(), has(id), clear(). setCurrent em ID desconhecido lança PanelNotFoundException.

Contracts

InterfaceImplementadoresMétodos
HasResourceResource7 estáticos: getModel, getSlug, getLabel, getPluralLabel, getNavigationIcon, getNavigationGroup, getNavigationSort
HasFieldsResourcefields(): array
HasActionsResourcemarker (sem método)
HasPolicies(opcional)getPolicy(): ?class-string para override de Policy

HTTP

Arqel\Core\Http\Controllers\ResourceController (final)

7 endpoints polimórficos: index, create, store, show, edit, update, destroy. Resolve Resource por {resource} slug, autoriza via Gate::denies(viewAny|create|view|update|delete), delega ao InertiaDataBuilder para serializar payload.

Arqel\Core\Http\Middleware\HandleArqelInertiaRequests (final)

Estende Inertia\Middleware. Shared props: auth.user (only(['id','name','email'])), auth.can (via AbilityRegistry), panel, panel.navigation, tenant, flash, translations, arqel.version.

O método buildNavigation() popula a shared prop panel.navigation a partir dos Resources registados (ResourceRegistry::all()), agrupando por getNavigationGroup() e ordenando por getNavigationSort(). Cada item carrega { label, url, icon, group, sort, active } — consumido no client por useNavigation().

Esse middleware é publicado para app/Http/Middleware/HandleArqelInertiaRequests.php durante arqel:install para permitir override pelo utilizador.

Support

Arqel\Core\Support\InertiaDataBuilder (final)

Assembler dos payloads index/create/edit/show. Métodos: buildIndexData, buildCreateData, buildEditData, buildShowData. Detecta Resource::table() retornando Arqel\Table\Table via duck-typing e roteia para buildTableIndexData (delega ao TableQueryBuilder via Reflection — sem hard dep).

Arqel\Core\Support\FieldSchemaSerializer (final)

Serializador central de Fields para o payload Inertia (shape canónico em 06-api-react.md §4). Duck-typed contra Arqel\Fields\Field — sem hard dep. Filtra fields por canBeSeenBy(user, record).

Comandos Artisan

ComandoFunção
arqel:installScaffold inicial (ver detalhe abaixo)
arqel:make-user {--name=} {--email=} {--password=}Cria utilizador admin interactivamente (estilo filament:make-user)
arqel:resource {model} {--with-policy}Gera Resource a partir de model FQN curto

arqel:install — detalhe

Executado uma única vez por app. Operações:

  • Auto-regista ArqelServiceProvider em bootstrap/providers.php (Laravel 11+ structure)
  • Publica HandleArqelInertiaRequests em app/Http/Middleware/ e regista no kernel HTTP
  • Publica vite.config.ts com aliases Arqel + plugins React/Tailwind v4
  • Scaffold de app/Arqel/Resources/UserResource.php apontando para o User model do app
  • Publica assets de auth (public/arqel/login-hero.svg)
  • Cria config/arqel.php, resources/js/Pages/Arqel/, layout root e AGENTS.md
  • Adiciona scripts npm/composer ao package.json e composer.json

arqel:make-user

Comando interactivo (ou via flags) que cria um User com email_verified_at preenchido e password hasheada via Hash::make. Para gates panel-level (e.g. viewAdminPanel), o operador deve registar a ability separadamente — make-user apenas cria o registo.

Licença MIT — construído com Inertia + React + Laravel.