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étodo | Tipo | Descrição |
|---|---|---|
getModel() | class-string<Model> | Class FQN do model. Lança LogicException se $model não declarado |
getSlug() | string | Slug derivado do nome (UserResource → users) ou override $slug |
getLabel() / getPluralLabel() | string | Labels auto-derivados ou override |
getNavigationIcon() / getNavigationGroup() / getNavigationSort() | ?string / ?string / ?int | Sidebar metadata |
fields() | array<Field> | Lista de fields (abstract — declarar) |
table() | mixed | Opcional. Retornar Arqel\Table\Table quando precisar custom |
form() | mixed | Opcional. Retornar Arqel\Form\Form quando precisar custom |
actions() | array<Action> | Opcional. Default vazio |
recordTitle(Model) / recordSubtitle(Model) | string / ?string | Identificador exibido em breadcrumbs/modais |
indexQuery(Builder) | Builder | Hook para escopar listagem |
Lifecycle hooks (todos protected, override na subclass):
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 truthyOrchestrators (públicos, chamados pelo ResourceController):
runCreate(array $data): Model
runUpdate(Model $record, array $data): Model
runDelete(Model $record): boolArqel\Core\Resources\ResourceRegistry (final)
Singleton. Bound automaticamente em ArqelServiceProvider.
| Método | Descriçã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).
$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 2Cada 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
| Interface | Implementadores | Métodos |
|---|---|---|
HasResource | Resource | 7 estáticos: getModel, getSlug, getLabel, getPluralLabel, getNavigationIcon, getNavigationGroup, getNavigationSort |
HasFields | Resource | fields(): array |
HasActions | Resource | marker (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
| Comando | Função |
|---|---|
arqel:install | Scaffold 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
ArqelServiceProviderembootstrap/providers.php(Laravel 11+ structure) - Publica
HandleArqelInertiaRequestsemapp/Http/Middleware/e regista no kernel HTTP - Publica
vite.config.tscom aliases Arqel + plugins React/Tailwind v4 - Scaffold de
app/Arqel/Resources/UserResource.phpapontando para oUsermodel do app - Publica assets de auth (
public/arqel/login-hero.svg) - Cria
config/arqel.php,resources/js/Pages/Arqel/, layout root eAGENTS.md - Adiciona scripts npm/composer ao
package.jsonecomposer.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.
Related
- SKILL:
packages/core/SKILL.md - Source:
packages/core/src/ - Próximo:
arqel-dev/fields