Skip to content

Sections and roles

Permissions in Export119 are organized into sections. Each section is a logical area of the platform — cars, invoicing, vaults, ledger, etc. — and each user role gets per-section RWED flags: Read / Write (create) / Edit / Delete.

Sections visible in the Roles & Permissions matrix:

SectionSurface
dashboardThe home dashboard widgets
carsCars inventory page + per-car detail
invoicingQuotations, proformas, invoices, payments
vaultsVaults page + transactions
currenciesCurrency catalog + spot rates
ledgerGeneral ledger + manual journal entries
chart_of_accountsChart of Accounts
financial_reportsTrial balance, balance sheet, P&L
fx_exchangeFX Exchange Center
containersContainers page
shipping_schedulesShipping schedules (forwarder side)
customs_permitsCustoms broker queue
settingsCompany / users / cost types / etc.
migration_export119Migration wizard (trading-only)
platform_adminPlatform-admin-only sections

The visible set per role also depends on company type — a forwarder doesn’t see cars because forwarders don’t carry inventory.

FlagWhat it controls
ReadView the page, list data, run reports.
WriteCreate new entities (new car, new invoice, new vault).
EditModify existing entities (inline cell edit, change status via action, edit invoice draft).
DeleteDelete or cancel entities (delete vault tx, cancel car, void invoice).

A common confusion: the inline pencil-edit affordance is gated on cars:edit, NOT cars:write. Write means “create new”; Edit means “modify existing”. This trips up new admins who give Sales cars:write and wonder why they can’t fix typos.

Every role in Export119 falls into one of three buckets:

  • Owner — full access, bypass every permission gate. Set at sign-up (the user who created the company). At least one owner must exist.
  • Admin — full access except platform-admin actions. Bypasses section permissions.
  • Custom — bounded by section permissions and (optionally) per-view, per-vault, per-location ACLs.

Both Owner and Admin are “bypass” roles in the matrix — they show ”—” in every column because the matrix doesn’t gate them.

Some sections cluster in the sidebar — Accounting (Ledger + Chart of Accounts + Financial Reports), Invoicing (sub-pages), Car Inventory (parent + dynamic per-view children). Section groups have a master toggle that toggles all children on/off in one click.

When a user calls a tRPC procedure (e.g., cars.inlineUpdate), the server middleware calls requireSectionPermission(ctx, "cars", "edit"). If the user’s role doesn’t have cars:edit = true, the request fails with a 403 before any business logic runs. Hiding the menu item isn’t enough — the server is the canonical gate.