Skip to main content
The Object Model is the architectural pattern for building domain entities in Core. A domain object is a Laravel model that implements a standard contract, giving it a consistent identity across the UI — title, icon, breadcrumbs, global search, activity logging — with no per-object wiring required.

Object Contract Hierarchy

Core uses a three-tier contract hierarchy to define how objects are displayed and managed:

ObjectContract

The base contract for all displayable objects in the UI. Provides fundamental display methods that UI components like ObjectColumn, ObjectDetailedLink, and ObjectCard depend on. Responsibilities:
  • Display properties (title, subtitle, icon, avatar)
  • Navigation URLs (internal routes or external links)
  • Visual styling (badge icons, colors, tooltips)
  • Object references (related entities)

ResourceObjectContract

For external integration models that sync data from external systems (e.g. Fortnox invoices, Shopify orders). Additional capabilities:
  • ETL operations with fillTransformedData()
  • Raw JSON storage from external APIs
  • Batch import tracking with timestamps
  • Source data change detection with latestSourceUpdatedAt()
Uses the HasResourceObject trait. Stores raw data in a data JSON column. URLs typically point to the external system. No activity logging.

DomainObjectContract

For core business entities that users work with directly (e.g. User, Order, Customer). Additional capabilities:
  • Global search integration via Laravel Scout
  • Activity logging with custom formatting
  • Collection management (getDomainObjectCollectionUrl())
  • Search priority and authorization
Uses the HasDomainObject trait. Most models in your application should implement this contract.
Use ResourceObjectContract only for data synced from external systems. All first-party entities should be DomainObjectContract.

The Domain Object Contract

Implement DomainObjectContract and use the HasDomainObject trait:
app/Models/Company.php
use Inly\Core\Contracts\DomainObjectContract;
use Inly\Core\Models\Traits\HasDomainObject;

class Company extends Model implements DomainObjectContract
{
    use HasDomainObject, HasFactory, SoftDeletes;

    protected function casts(): array
    {
        return [
            'status' => CompanyStatus::class,
        ];
    }

    public function getObjectTitle(): ?string
    {
        return $this->name;
    }

    public function getObjectSubtitle(): ?string
    {
        return $this->org_number;
    }

    public function getObjectIcon(): ?string
    {
        return 'Building2';
    }

    public function getObjectUrl(): ?string
    {
        return route('companies.show', $this);
    }

    public static function getObjectCollectionTitle(?bool $singular = false): string
    {
        return $singular ? __('Company') : __('Companies');
    }

    public function getObjectDefaultSort(): string
    {
        return 'name';
    }
}
Use the casts() method instead of the $casts property for Laravel 12 compatibility.

Permissions

Every domain object requires two permissions in app/Enums/Permission.php:
case VIEW_COMPANIES = 'view_companies';
case MANAGE_COMPANIES = 'manage_companies';
VIEW permissions cover reading (index, show routes). MANAGE permissions cover mutations (create, update, delete actions).

Next Steps

Object Schema

Define typed properties and drive tables, forms, and UI from a single schema.

Object Capabilities

Enable search, activity logging, and other platform capabilities.

Actions

Create reusable, authorized operations for your domain objects.

Pages

Wire domain objects to Inertia pages using CoreShowPage and CoreIndexPage.