5 Roles and Permissions
Hardik edited this page 2026-06-22 04:58:22 +05:30

Roles and Permissions

Authorisation is centralised in lib/permissions.ts. Server Actions call requirePermission(role, permission) at the top before any DB write; hasPermission(role, permission) gates UI and page segments. The PO state machine adds a second gate (status + role) on top of permissions — see PO Lifecycle.

The seven roles

Role Who they are Core capability
TECHNICAL Deck / engine crew Create, submit, track own POs; confirm receipt; add (unverified) vendors
MANNING Crew-management staff Same as Technical
ACCOUNTS Finance / accounts Process payments (records ref + date); manage/verify vendors; view all POs
MANAGER Department manager Review/approve/reject/request-edits; edit line items pre-approval; manage cost centres, items, vendors, sites; analytics; import
SUPERUSER Power user / ops lead Combined Technical + Manning + Manager authority across PO actions
AUDITOR Internal auditor Read-only access to all POs and reports
ADMIN System administrator Manage users, companies, accounting codes, cost centres, sites, items, vendors

Accounts are provisioned by an Admin or via Microsoft Entra SSO. There is no self-registration. SSO-only users have no password and may set one from their profile (any role can reach the profile page; only approvers upload a signature).

Permission → role matrix

The exact ROLE_PERMISSIONS map in lib/permissions.ts. ✓ = granted.

Permission TECH MANNING ACCOUNTS MANAGER SUPERUSER AUDITOR ADMIN
create_po
submit_po
edit_own_draft_po
view_own_pos
view_all_pos
approve_po
reject_po
cancel_po
request_edits
request_vendor_id
process_payment
confirm_receipt
view_analytics
export_reports
create_vendor
manage_vendors
manage_products
manage_sites
manage_vessels_accounts
manage_users

Notes on the shipped behaviour

  • create_vendor is held by submitters too — vendors they add are created unverified and become verified when a PO closes/pays with them, on import, or via a Manager/Accounts/Admin (manage_vendors). Only manage_vendors holders may assign the formal verified vendorId.
  • MANAGER is broad: it holds process_payment, confirm_receipt, and the manage_* permissions for vendors, products, sites, and vessels/accounts — in addition to the approval permissions.
  • ADMIN does not create/approve POs — it is an administration role (manage_users plus the catalogue/manage_* permissions) and can view/export.
  • AUDITOR is strictly read-only (view_*, export_reports).

Feature-flagged access

Submitter view-all (NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED)

By default submitters (TECHNICAL, MANNING) only see the POs they raised. When NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED="true" they gain read-only access to every PO:

  • the History page (/history) and its CSV/PDF report export;
  • any other user's PO detail page (/po/[id]);
  • the Export PDF / XLSX buttons on those POs (approved & cancelled POs only, same status gate as everyone else).

It is a pure read widening — it grants no approval, payment, edit, cancel, or admin rights, and does not change what non-submitter roles can do. The flag is opt-in (off unless the value is exactly "true").

Implementation lives in lib/permissions.ts:

Helper Meaning
isSubmitterRole(role) role ∈ {TECHNICAL, MANNING}
submitterCanViewAll(role) flag is on and isSubmitterRole(role)
canViewAllPos(role) hasPermission(role, "view_all_pos") || submitterCanViewAll(role)

canViewAllPos gates the PO detail page and the per-PO export route; submitterCanViewAll is OR'd into the export_reports gate on the History page, the report-export route, and the sidebar's History link. When the flag is off, all of these collapse to the prior behaviour (view_all_pos holders only). The my-orders "Closed Purchase Orders" list stays personal for submitters regardless — History is the all-POs surface.

Business rules layered on top

Beyond the permission map, server actions and the state machine enforce:

  • A vendor must be assigned before a manager can approve a PO.
  • Only verified vendors (with a vendorId) may be assigned via provideVendorId.
  • Discarding is only possible on DRAFT POs; the owner, MANAGER, or SUPERUSER may discard.
  • Receipt confirmation is the submitter's own PO (or SUPERUSER/MANAGER).
  • Payment date is compulsory and cannot be in the future.

See the Testing page for the permission test matrix that pins these rules down with integration tests.