Reference

Relationship Types

Every link between two records carries a typed relationship — the catalog below is what each tenant ships with by default. Tenants can rename or extend any of these from the CRM admin; the APP picker stays in step via the per-tenant catalog cache.

How a link gets its label

A relationship type defines an asymmetric pair — one entity type sits on the left side, the other on the right. display_name is what the link reads when viewed from the left; inverse_display_name is what it reads when viewed from the right.

The mobile APP and the CRM share the same catalog, served by GET /api/v1/relationship-types. The APP caches the response per tenant in relationship_types_cache so the link picker can render the correct directional label offline. When the cache hasn't hydrated yet the picker falls back to a hardcoded seed that mirrors the default catalog.

RELATED_TO is always offered as a generic fallback — if no catalog row matches a given pair, the link still goes through and the server records it as a typed catch-all.

Pair sentinels. Two rows in the default catalog use any as the left-hand entity type: ASSIGNED_TO and PINNED_BY. any means "matches any entity type on this side" — useful for relationships that aren't tied to a specific kind of record (assigning a person to an asset, an event, an order … or pinning anything).

Default catalog

Seeded by DefaultRelationshipTypeSeeder for every new tenant. is_system = true, is_active = true.

System code Forward label Inverse label Pair (left → right) Dashboard signal
WORKS_AT Works At Has Worker person organisation No
OWNS Owns Owned By person asset Yes
ASSIGNED_TO Assigned To Assigned any person Yes
MEMBER_OF Member Of Has Member person organisation No
ATTENDED Attended Attended By person event Yes
REPORTED_BY Reported By Reported incident person Yes
INVOLVED_IN Involved In Involves person incident Yes
INSPECTED_BY Inspected By Inspected inspection person Yes
ASSET_OF Asset Of Has Asset asset organisation No
PINNED_BY Pinned By Has Pinned any person Yes
VISITED_AT Visited At Had Visit event organisation Yes
Source: database/seeders/DefaultRelationshipTypeSeeder.php

Legacy + CRM-defaults types

These come from CrmDefaultsSeeder and earlier APP releases. They cover the order & cross-link flows that aren't in the dashboard-focused default seeder. The APP keeps them in its offline-fallback seed so the picker still works for orders / events / parent-org links before the cache hydrates.

System code Forward label Inverse label Pair (left → right)
ORDERED_BY Ordered By Placed Order order person
ORDERED_FROM Ordered From Has Order order organisation
ORDER_FOR_ASSET Order For Asset Asset Has Order order asset
ORDER_FOR_EVENT Order For Event Event Has Order order event
ASSET_AT_EVENT Asset At Event Event Has Asset asset event
PARENT_ORG Parent Org Subsidiary organisation organisation
RELATED_TO Related To Related To any any (fallback)
Source: CrmDefaultsSeeder.php + APP lib/utils/constants.dart

What “dashboard signal” means

A relationship type with is_dashboard_signal = true shows up on a person's dashboard as work-on-their-plate — Assigned To, Reported By, Inspected By, etc. Identity-context links like Member Of and Works At stay quiet so the dashboard isn't drowned by org-chart links.

The flag is read by RelationshipType::scopeDashboardSignal() on the API and consumed by the dashboard payload (GET /api/v1/me/dashboard).

Customising for a tenant

Tenants can rename, deactivate, or add their own relationship types in the CRM admin (Filament). The APP picker reflects custom labels on the next sync — the catalog refreshes at boot, after a workspace switch, and via pull-to-refresh on the dashboard.

The wire payload is unchanged: the APP sends the system_code string, and the server's smart matcher resolves it against system_code, name, or display_name — case-insensitive — before falling back to entity-type pair inference.