Skip to content

Actions, Data, And Settings

Capell packages use Actions for behavior and Data objects for typed boundaries.

Put package behavior in src/Actions.

<?php
declare(strict_types=1);
namespace Capell\Example\Actions;
use Lorisleiva\Actions\Concerns\AsObject;
final class BuildExampleReportAction
{
use AsObject;
public function handle(): mixed
{
return ExampleModel::query();
}
}

Filament pages, commands, listeners, and controllers call ::run() or ::dispatch(). They should not contain domain logic.

Use src/Data for structured input and output:

<?php
declare(strict_types=1);
namespace Capell\Example\Data;
use Spatie\LaravelData\Data;
final class ExampleHealthData extends Data
{
public function __construct(
public string $status,
public int $issueCount,
) {}
}

Use Data objects across HTTP, Filament, Livewire, JSON casts, and package boundaries.

Settings need a Spatie settings class, a settings migration, a Filament schema, and a package-owned extension settings page. The global Capell Settings page is reserved for core settings only.

final class ExampleSettings extends Settings
{
public bool $enabled = true;
public static function group(): string
{
return 'example';
}
}

Register settings from a provider:

use Capell\Core\Support\Settings\SettingsGroupMetadata;
use Capell\Core\Support\Settings\SettingsSchemaRegistry;
use Filament\Support\Icons\Heroicon;
$registry = resolve(SettingsSchemaRegistry::class);
$registry->registerSettingsClass('example', ExampleSettings::class);
$registry->registerMetadata(new SettingsGroupMetadata(
group: 'example',
label: 'example::settings.title',
icon: Heroicon::OutlinedCog6Tooth,
navigationGroup: 'capell-admin::navigation.group_system',
packageName: 'capell-app/example',
));
$registry->register('example', ExampleSettingsSchema::class);

Expose package settings through a Filament page that extends Capell\Admin\Filament\Pages\AbstractPackageSettingsPage and register it with CapellAdmin::registerExtensionPage($packageName, YourPackageSettingsPage::class). This adds the page to Filament, lists the package on the Extensions management page with a direct Edit action, and adds accessible registered pages to the grouped Filament sub-navigation on the Extensions page. Packages with multiple registered pages use the first page as the primary edit target and show the others as direct secondary links.