SeviaFlow Get Started

Resources

A Resource is the class that connects an Eloquent model to the surfaces SeviaFlow can provide. The model and database schema remain part of your Laravel application; a Resource describes columns, fields, filters and optional behavior for that model.

New to SeviaFlow?Follow Your First Resource to create a model, migration, UI form, registration entry and admin-panel access from start to finish. This page is the method reference for when you need the details.

Smallest Resource

Every Resource must point to an Eloquent model. This minimal class can be resolved after it is registered, but it has no custom table or form yet:

use App\Models\Customer;
use SeviaFlow\Core\Resources\Resource;

final class CustomerResource extends Resource
{
    protected static string $model = Customer::class;
}

Model

protected static string $model is required. Resource::model() returns this class and throws if it is missing or empty.

These optional properties control how the UI labels and groups the item:

protected static ?string $navigationLabel = 'Customers';
protected static ?string $navigationGroup = 'Operations';
protected static ?string $navigationIcon = 'users';
protected static ?int $navigationSort = 10;
protected static bool $shouldRegisterNavigation = true;

Definition Methods

MethodPurpose
table(Table $table): TableDefine index columns and filters. Column methods can enable search and sorting.
form(Form $form): FormDefine create/edit fields and sections.
show(Form $form): FormDefine show-page fields. Defaults to form().
api(ApiResource $api): ApiResourceOpt a Resource into REST/API exposure and define the allowed fields and operations.
export(ExportResource $export): ExportResourceConfigure export field access.
import(ImportResource $import): ImportResourceConfigure import field access and validation reuse.
events(ResourceEvents $events): ResourceEventsRegister lifecycle event handlers.
actions(): arrayReturn per-record Action instances.
bulkActions(): arrayReturn BulkAction instances.
relations(): arrayReturn relation definitions for related models.
workflow(Workflow $workflow): WorkflowDefine a state field, states and transitions.
query(Builder $query): BuilderCustomize the base Eloquent query before search, filters, sorting and pagination. Use this for per-tenant row scoping.

tableQuery() still exists for compatibility but is deprecated. Use query().

Example: how Resource definitions fit together

A Resource is a PHP class that extends Resource. The model is required; the other methods are extension points. Most applications start with table() and form(). show() uses the form definition by default. Add API, import/export, events, actions, relations or workflows only when your application needs them.

<?php

declare(strict_types=1);

namespace App\SeviaFlow\Resources;

use App\Models\Customer;
use SeviaFlow\Core\Resources\ApiResource;
use SeviaFlow\Core\Resources\Columns\TextColumn;
use SeviaFlow\Core\Resources\Fields\EmailField;
use SeviaFlow\Core\Resources\Fields\TextField;
use SeviaFlow\Core\Resources\Form;
use SeviaFlow\Core\Resources\Resource;
use SeviaFlow\Core\Resources\Table;

final class CustomerResource extends Resource
{
    protected static string $model = Customer::class;

    public static function table(Table $table): Table
    {
        return $table->columns([
            TextColumn::make('name')->label('Name')->searchable()->sortable(),
            TextColumn::make('email')->label('Email')->searchable(),
        ]);
    }

    public static function form(Form $form): Form
    {
        return $form->fields([
            TextField::make('name')->label('Name')->required(),
            EmailField::make('email')->label('Email')->required(),
        ]);
    }

    public static function api(ApiResource $api): ApiResource
    {
        return $api
            ->enabled()
            ->readable(['id', 'name', 'email'])
            ->creatable(['name', 'email'])
            ->updatable(['name', 'email'])
            ->requiredOnCreate(['name', 'email'])
            ->useFormFieldRules();
    }
}

Here, name and email refer to Eloquent attributes. The column methods control the index table; the field methods build the create/edit form. The API method is opt-in: it exposes only the listed fields when the API adapter is installed and the request passes authentication and authorization. Follow Your First Resource for the full model, migration, registration and panel setup. See Exposing a Resource for API access, and the dedicated guides for actions, relationships, workflows, events and import/export.

Query Customization

This hook changes the base set of rows before SeviaFlow applies search, filters, sorting and pagination. For example, a tenant-aware application can scope records to the current tenant:

use Illuminate\Database\Eloquent\Builder;

public static function query(Builder $query): Builder
{
    return $query->where('tenant_id', auth()->user()->tenant_id);
}

Adapt the tenant relation and guest behavior to your own app. A query scope limits visible rows; it does not replace policies that authorize individual operations.

The complete customer example with its searchable table and status filter is available in Your First Resource.