Skip to content

System Connections resource (/admin/system-connections)

Manages App\Models\SystemConnection — the links between a Tenant and an external e-commerce system. Each system connection holds the credentials and configuration needed to communicate with a specific system account.

Model attributes

Attribute Type Notes
id UUID Primary key via HasUuids
tenant_id UUID (FK), nullable Owning Tenant; FK uses restrictOnDelete
system_id UUID (FK) Target System
external_user_id string User identifier on the external system
name string, nullable Optional label; not exposed on the admin form
base_url string Root URL of the external system installation
credentials array, nullable Sensitive credentials; stored as encrypted:json
status SystemConnectionStatus Enum: active, inactive, error, pending, disconnected, uninstalled
meta array Arbitrary metadata; cast to array
configuration array, nullable Connector-widget opt-in per data domain; cast to array
last_connected_at datetime Timestamp of the last successful connection
disconnected_at datetime, nullable Set for exactly as long as status is disconnected; the grace-period deadline is derived from it
deleted_at timestamp Soft deletes enabled

Status values

Value Badge colour Meaning
active Green (success) System connection is healthy and in use
pending Amber (warning) Awaiting first successful contact
error Red (danger) Last connection attempt failed
inactive Grey (gray) Manually disabled
disconnected Blue (info) Ended by the shop; data kept for the grace period, reversible
uninstalled Red (danger) Ended by removing the plugin; everything deleted at once

List view columns

Column Source Behaviour
ID system_connections.id Searchable
Tenant tenant.name Searchable
System system.name Searchable
External User ID system_connections.external_user_id Searchable
Base URL system_connections.base_url Searchable
Status system_connections.status Badge with colours above
Last Connected At system_connections.last_connected_at Date-time, sortable
Disconnected At system_connections.disconnected_at Date-time, sortable; hidden by default
Created At system_connections.created_at Date-time, sortable; hidden by default
Updated At system_connections.updated_at Date-time, sortable; hidden by default
Deleted At system_connections.deleted_at Date-time, sortable; hidden by default

Filters: Tenant (relationship), System (relationship), Status (enum), Trashed.

Bulk actions: Delete (soft), Force Delete, Restore.

View page — A disconnected connection additionally shows Grace period ends, the derived deadline from SystemConnection::graceDeadline(), rendered as a relative window with the absolute date as a tooltip. The entry is hidden for every other status.

Role-based visibility

UI element SuperAdmin PlatformSupport Viewer
Create button yes
Edit / Delete actions yes
Bulk Sync yes own connections only
Credentials field on create yes
Credentials field on edit yes
Tenant selector options all tenants reachable tenants reachable tenants

PlatformSupport holds system_connections.view and system_connections.resync, and nothing else on this resource. Bulk Sync is therefore its only write-shaped action here, and it applies only to connections that are fully accessible — those pointing at a system the user operates. Viewer holds view alone.

Credentials — The Credentials textarea is hidden whenever the operation is not create and the user is not a SuperAdmin. Because system_connections.create is SuperAdmin-only, in practice only a SuperAdmin ever sees the field at all; the hidden() condition is the second guard rather than the first. Once saved, credentials cannot be read back through the UI by anyone but a SuperAdmin.

Tenant selector scoping — The Tenant Select binds tenant_id to the tenant relationship and passes modifyQueryUsing a closure calling Tenant::accessibleBy($user), so the dropdown lists only tenants within the user's reach. Since the form is only reachable by a SuperAdmin, for whom that scope short-circuits to everything, this too is a safety net rather than observable behaviour.

Sibling connections — A connection that lies under a reachable tenant but does not point at a system the user operates still appears in the list, read-only: status, last contact, health. SystemConnectionPolicy reads view from SystemConnection::accessibleBy() and update, delete and resync from SystemConnection::fullyAccessibleBy(). See Own connections in full, siblings by status.

Form fields (create / edit)

The create form is intended for development and debugging. System connections are normally created via API.

Field Type Validation Notes
Tenant Select (relationship) Required Bound to tenant_id; scoped to Tenant::accessibleBy($user) — see Role-based visibility above
System Select (relationship) Required Bound to system_id via system relation
External User ID TextInput Required
Base URL TextInput Required, URL
Credentials Textarea Required on create JSON; pretty-printed; stored as encrypted:json; hidden on edit for non-SuperAdmin
Status Select Required Default: pending
Configuration KeyValue Optional Connector-widget opt-in per data domain; read by SystemConnection::pullInCapabilities()
Meta KeyValue Optional Free-form key/value pairs
Last Connected At DateTimePicker Read-only; hidden on create

Edit page header actions: DeleteAction (soft delete), ForceDeleteAction, RestoreAction.

Soft-deleted system connections remain accessible on the edit route — getRecordRouteBindingEloquentQuery() strips SoftDeletingScope so trashed records can still be restored.

Bulk Sync action

The Bulk Sync header action on the connection edit page lets an operator manually trigger a full data export for a connection.

Availability: the button is enabled only when the connection is healthy (status active) and at least one data scope is available to sync. It is disabled with an explanatory tooltip otherwise: "Only active connections can be synced" for any non-active status, "This connection has no system" when the linked System is missing or soft-deleted, and "No active sync rule covers this connection" when no active SyncRule names the connection as source.

Interaction: clicking the button opens a modal with a CheckboxList labelled "Data scopes". The list holds exactly the domains SystemConnection::pullInCapabilities() returns — the platform's capabilities, narrowed by the connector-widget opt-in and by active outgoing SyncRules (see Sync Rules). All of them are pre-selected. A bulk-toggle control allows selecting or deselecting all scopes at once. A submitted scope that no active SyncRule covers is rejected with a validation error on the field rather than being quietly dropped. Three field rules enforce that together, and a hand-crafted Livewire payload has to clear all three: required (at least one scope), an explicit array shape rule, and the per-item in rule Filament derives from the option list itself. The shape rule is not redundant — the derived in rule binds at capabilities.*, which Laravel only applies to an array, so without it a scalar payload would pass validation untouched and then be decoded into an array by OptionsArrayStateCast after the gate.

Behaviour: on confirmation, a single BulkSyncJob is dispatched carrying all selected capabilities. The job resolves the integration for the connection's SystemDriver via IntegrationRegistry and calls requestBulkExport() once per capability. The job runs on the rabbitmq queue asynchronously — the operator's browser is not blocked.

BulkSyncJob implements ShouldBeUnique keyed on the connection ID. If a sync for the same connection is already queued or running, a new dispatch is silently dropped — only one sync per connection can be active at a time.

Aspect Detail
Available for Connections with status active that have at least one rule-backed data scope
Modal field CheckboxList of the connection's rule-backed SystemCapability values
Jobs dispatched One BulkSyncJob per trigger (carries all selected capabilities)
Uniqueness One active sync per connection (ShouldBeUnique)
Queue driver rabbitmq
Success notification "Bulk sync triggered"

Source files

File Purpose
app/Filament/Resources/SystemConnections/SystemConnectionResource.php Resource definition, query customisation
app/Filament/Resources/SystemConnections/Schemas/SystemConnectionForm.php Form schema
app/Filament/Resources/SystemConnections/Tables/SystemConnectionsTable.php Table columns, filters, actions
app/Filament/Resources/SystemConnections/RelationManagers/SyncBatchesRelationManager.php Sync batches tab
app/Filament/Resources/SystemConnections/Pages/ListSystemConnections.php List page
app/Filament/Resources/SystemConnections/Pages/CreateSystemConnection.php Create page
app/Filament/Resources/SystemConnections/Pages/ViewSystemConnection.php Detail page
app/Filament/Resources/SystemConnections/Pages/EditSystemConnection.php Edit page with header actions
app/Filament/Resources/SystemConnections/Pages/ConfigureSystemConnectionWidget.php Connector-widget configuration page

See also

  • Admin Panel — panel overview, authentication, auto-discovery
  • PoliciesSystemConnectionPolicy, its resync gate, and the full/status-only split
  • Roles & Permissions — the roles, the permission matrix, and why reach is derived