SeaVesselManagerPlanned Maintenance & Fleet Management
← Support guides

Permissions Reference

What every permission is needed for - by module and function. Use it to decide which permissions each role in your company should have.

Version 15 October 202645 modules8 role presetsseavesselmanager.com

1. How permissions work

Two independent gates. To do something to a vessel's data a user needs both:

  1. A permission (this document): what they may do, e.g. modules.maintenance.complete. Permissions are ticked on a role (Portal → Roles) and a user holds one or more roles.
  2. Access to the vessel (Portal → Vessel Access, or a Fleet Group): where they may do it. A user with no vessel grant and no fleet group sees no vessel at all. Access is all-or-nothing per vessel - there are no per-vessel view/edit levels; an explicit denied entry blocks a vessel. Only the superadmin can grant vessel access.

Format. modules.<module>.<action>, e.g. modules.assets.edit. Standalone permissions have their own key (debug_terminal).

Rules the system applies

Where the document says API routes, they are the backend endpoints that accept the permission; UI lists the frontend files that check it.

2. Role presets

One-click starting points in Create/Edit Role. They are starting points, not locked templates - tick/untick freely after applying one.

👑 Full Access

Everything, including modules added in future updates.

Grants * (everything, including future modules).

👀 Read Only

Can open every page but change nothing.

Module Actions
Fleet Dashboard (dashboard) view
Vessel KPIs (vessels) view
Voyages (voyages) view
Standard Work (standard-work) view
Crew (crew) view
Codes (codes) view
Inventory (all) (inventory) view
Assets (assets) view
Movable Assets (movable-assets) view
Warehouse & Catalogs (catalogs) view
Spare Parts (spare-parts) view
Stock (stock) view
Alarm System (alarm-system) view
Certificates (certificates) view
Compliance (compliance) view
Medic (medic) view
Medical Items (medic-items) view
Procurement (procurement) view
Purchase Orders (po) view
Suppliers (suppliers) view
Budget (budget) view
Cost Centers (cost-centers) view
Maintenance (maintenance) view
Cargo Operations (cargo) view
Running Hours (running-hours) view
Postponed Work Orders (postponed) view
History (history) view
Alerts (alerts) view
Class Surveys (class-surveys) view
Voyage Reports (voyage-reports) view
Documents (documents) view
Reports (reports) view
Analytics (analytics) view
User Dashboard (user-dashboard) view
Messages (messages) view
Users (users) view
Roles (roles) view
Vessel Access (vessel-access) view
Fleet Groups (fleet-groups) view
Notifications (notifications) view
AIVA Assistant (aiva) view
QHSE (qhse) view
Admin Settings (settings) view
Audit Log (audit-log) view
Developer Console (dev_console) view

🧭 Master / Captain

Full operational authority on the vessel. No user or system admin.

Module Actions
AIVA Assistant (aiva) view
Fleet Dashboard (dashboard) view
Vessel KPIs (vessels) view, edit, set-position
Voyages (voyages) view, create, edit, delete
Maintenance (maintenance) view, create, edit, complete
Postponed Work Orders (postponed) view, approve
Running Hours (running-hours) view, edit
History (history) view, export
Alerts (alerts) view, acknowledge
Crew (crew) view, edit, rest-edit, rest-approve
Movable Assets (movable-assets) view, create, edit, pack, send, receive, finish, cancel
Certificates (certificates) view, create, edit
Compliance (compliance) view, edit
QHSE (qhse) view, create, edit, delete
Voyage Reports (voyage-reports) view, create, edit, export
Documents (documents) view, upload, edit
Messages (messages) view, send
Medic (medic) view, edit
Reports (reports) view, export

🔧 Chief Engineer

Technical operations: maintenance, assets, spares, running hours.

Module Actions
AIVA Assistant (aiva) view
Fleet Dashboard (dashboard) view
Vessel KPIs (vessels) view
Maintenance (maintenance) view, create, edit, complete
Running Hours (running-hours) view, edit
Postponed Work Orders (postponed) view, approve
History (history) view, export
Alerts (alerts) view, acknowledge
Assets (assets) view, create, edit, move
Spare Parts (spare-parts) view, create, edit, adjust
Stock (stock) view, adjust
Warehouse & Catalogs (catalogs) view
Alarm System (alarm-system) view, edit, acknowledge
Standard Work (standard-work) view, create, edit
Documents (documents) view, upload, edit
Reports (reports) view, export
Messages (messages) view, send

⚓ Crew

Day-to-day work: see and complete jobs, look up spares, send messages.

Module Actions
AIVA Assistant (aiva) view
User Dashboard (user-dashboard) view
Fleet Dashboard (dashboard) view
Crew (crew) rest-own
Maintenance (maintenance) view, complete
Running Hours (running-hours) view, edit
History (history) view
Assets (assets) view
Movable Assets (movable-assets) view
Spare Parts (spare-parts) view
Stock (stock) view
Documents (documents) view
Messages (messages) view, send
Medic (medic) view
QHSE (qhse) view
Alerts (alerts) view, acknowledge

🏢 Superintendent

Shore-side oversight across the fleet. No user or role administration.

Module Actions
AIVA Assistant (aiva) view
Fleet Dashboard (dashboard) view
Vessel KPIs (vessels) view, create, edit, set-position
Voyages (voyages) view, create, edit, delete
Standard Work (standard-work) view, create, edit, delete
Maintenance (maintenance) view, create, edit, complete
Postponed Work Orders (postponed) view, approve
Running Hours (running-hours) view, edit
History (history) view, export
Alerts (alerts) view, acknowledge
Assets (assets) view, create, edit, move, import
Spare Parts (spare-parts) view, create, edit, adjust
Certificates (certificates) view, create, edit
Compliance (compliance) view, edit
Class Surveys (class-surveys) view, create, edit, delete
Voyage Reports (voyage-reports) view, create, edit, export
Documents (documents) view, upload, edit
Reports (reports) view, export
Analytics (analytics) view
QHSE (qhse) view, create, edit, delete
Crew (crew) view, create, edit, rest-edit, rest-approve
Movable Assets (movable-assets) view, create, edit, approve, revoke, pack, send, receive, finish, cancel, manage
Messages (messages) view, send
Audit Log (audit-log) view, export

🛒 Procurement Officer

Requisitions, purchase orders, suppliers and budget.

Module Actions
AIVA Assistant (aiva) view
Fleet Dashboard (dashboard) view
Procurement (procurement) view, create, edit, delete
Purchase Orders (po) view, create, edit, approve
Suppliers (suppliers) view, create, edit, delete
Budget (budget) view, edit
Cost Centers (cost-centers) view, create, edit, delete
Spare Parts (spare-parts) view
Stock (stock) view
Warehouse & Catalogs (catalogs) view, create, edit, import
Documents (documents) view, upload, edit
Reports (reports) view, export
Messages (messages) view, send

🦺 QHSE Officer

Safety, incidents, certificates, surveys and compliance.

Module Actions
AIVA Assistant (aiva) view
Fleet Dashboard (dashboard) view
QHSE (qhse) view, create, edit, delete
Certificates (certificates) view, create, edit
Compliance (compliance) view, edit
Class Surveys (class-surveys) view, create, edit, delete
Documents (documents) view, upload, edit
Alerts (alerts) view, acknowledge
History (history) view, export
Reports (reports) view, export
Crew (crew) view
Medic (medic) view, edit
Audit Log (audit-log) view, export
Messages (messages) view, send

3. Which permission do I need to...?

Looked up from the real routes. "Any of" = holding one of them is enough. Every action also needs access to the vessel concerned (section 1).

To... Route Permission needed
See the list of vessels / pick a vessel GET /vessels signed in (no permission)
Open a vessel page GET /vessels/:id signed in (no permission)
Edit vessel particulars PATCH /vessels/:id modules.vessels.edit
Change a vessel's status PATCH /vessels/:id/status modules.vessels.edit
Set a vessel position by hand PATCH /vessels/:id/position modules.vessels.set-position
Delete a vessel DELETE /vessels/:id modules.vessels.delete
Browse the asset (equipment) register GET /assets/components any of modules.assets.view or modules.inventory.view
Create an asset POST /assets/components modules.assets.create
Edit / rename an asset PATCH /assets/components/:id modules.assets.edit
Move an asset in the SFI tree POST /assets/components/:id/move modules.assets.move
Scrap an asset POST /assets/components/:id/scrap modules.assets.edit
Delete an asset DELETE /assets/components/:id modules.assets.delete
Link a spare part to an asset POST /assets/components/:id/spare-parts modules.assets.edit
Raise a work order from an asset POST /assets/components/:id/work-orders modules.assets.edit
Get the next work-order number POST /maintenance/work-orders/generate-number any of modules.maintenance.create or modules.maintenance.edit or modules.assets.edit
List work orders GET /maintenance/work-orders modules.maintenance.view
Start a work order PATCH /maintenance/work-orders/:id/start modules.maintenance.edit
Release a work order someone else started PATCH /maintenance/work-orders/:id/release modules.maintenance.edit
Sign out (complete) a work order POST /maintenance/work-orders/:id/sign-out modules.maintenance.complete
Correct a completed work order PATCH /maintenance/work-orders/:id/correct modules.maintenance.correct
Reopen a cancelled work order (completed ones: superadmin only) PATCH /maintenance/work-orders/:id/reopen modules.maintenance.edit
Delete a work order DELETE /maintenance/work-orders/:id modules.maintenance.delete
View PM schedules GET /pm/schedules modules.maintenance.view
Create a PM schedule POST /pm/schedules modules.maintenance.create
Edit a PM schedule PATCH /pm/schedules/:id modules.maintenance.edit
Delete a PM schedule DELETE /pm/schedules/:id modules.maintenance.delete
Record a running-hours reading POST /running-hours modules.running-hours.edit
Create a spare part POST /assets/spares modules.spare-parts.create
Edit a spare part PATCH /assets/spares/:id modules.spare-parts.edit
Create a purchase order POST /po modules.po.create
Edit a purchase order PUT /po/:id modules.po.edit
Create a requisition POST /procurement/requisitions modules.procurement.create
Upload a document POST /documents/upload modules.documents.upload
Grant permissions on a document POST /documents/:id/permissions modules.documents.edit
Add a crew certificate POST /certificates/crew modules.certificates.create
Create a QHSE incident POST /qhse/incidents modules.qhse.create
Send a message POST /channels/:channelId/messages modules.messages.send
Create a user POST /users modules.users.create
Create / edit a role POST /roles modules.roles.create
Read the audit log GET /audit/logs modules.audit-log.view
Open the AI assistant GET /ai/status modules.aiva.view
Read Admin Settings (company profile, diagnostics) GET /settings/company-profile modules.settings.view
Send a test email POST /settings/email/test modules.settings.edit
Use the Developer Console (read-only) GET /dev-console/schema modules.dev_console.view

4. Module reference

Per module: what it covers, then every action with what it allows, how it is enforced, the API routes that accept it and the UI that checks it. Enforcement: API = backend routes; UI = frontend checks; service rule = enforced in service code (see section 5); not enforced = declared in the Roles screen but nothing checks it yet (ticking it has no effect).

🚢 Fleet

Fleet Dashboard (dashboard)

The Fleet Dashboard (home page): fleet map, KPIs, live alerts panel. Also unlocks the weather/maritime map data used on maps.

Action Permission What it allows Enforcement
View modules.dashboard.view Open the Fleet Dashboard pages and read their data. API + UI - 6 routes
modules.dashboard.view - 6 API route(s), 2 UI file(s)

API routes

  • GET /maritime-poi - Maritime service businesses (OSM) within a bounding box — Fleet Map POI layer (any of: view, view, view)
  • GET /weather/bounds - Get weather data for a map bounding box (3x3 grid) (any of: view, view, view)
  • GET /weather/forecast/point - Get point forecast for a location (any of: view, view, view)
  • POST /weather/grid - Get weather data for specific coordinate points (any of: view, view, view)
  • GET /weather/status - Get weather service status (any of: view, view, view)
  • GET /weather/webcams - Get webcams near a location (any of: view, view, view)

UI components/dashboard/fleet-dashboard.tsx, components/layout/sidebar.tsx

Vessel KPIs (vessels)

Vessel master data and the vessel pages: particulars, photo, status, manual position, AIS/track lookups (MarineTraffic, Barentswatch, Datalastic, Fiskeridir, Skipsregisteret) and the sync status of each vessel.

Action Permission What it allows Enforcement
View modules.vessels.view Open the Vessel KPIs pages and read their data. API + UI - 31 routes
Create modules.vessels.create Create new Vessel KPIs records. API + UI - 1 routes
Edit modules.vessels.edit Edit vessel particulars, change vessel status, upload/delete the vessel photo, fetch track data. API + UI - 58 routes
Delete modules.vessels.delete Delete Vessel KPIs records. API - 1 routes
Set Position modules.vessels.set-position Manually set a vessel's position. Intended only for the window before the vessel's first AIS ping. API + UI - 1 routes
modules.vessels.view - 31 API route(s), 4 UI file(s)

API routes

  • GET /fleet-groups (any of: view, view)
  • GET /fleet-groups/:id (any of: view, view)
  • GET /fleet-groups/:id/members (any of: view, view)
  • GET /fleet-groups/:id/users (any of: view, view)
  • GET /maritime-poi - Maritime service businesses (OSM) within a bounding box — Fleet Map POI layer (any of: view, view, view)
  • GET /positions/vessel/:vesselId - Get position history for a vessel
  • GET /positions/vessel/:vesselId/latest - Get latest position for a vessel
  • GET /positions/vessel/:vesselId/track - Get vessel track (position trail)
  • GET /sync/bootstrap - Get full data snapshot for vessel initialization
  • GET /sync/delta
  • GET /sync/metadata
  • GET /sync/status - Get sync status for a vessel
  • GET /telemetry/vessel/:vesselId/history - Get telemetry history
  • GET /telemetry/vessel/:vesselId/latest - Get latest telemetry for a vessel
  • GET /tracking/barentswatch/search - Search vessels by name via BarentsWatch (any authenticated user) — for auto-filling MMSI/IMO when adding a vessel
  • GET /tracking/barentswatch/vessel/:vesselId - Get BarentsWatch sync status + latest position for one vessel (any authenticated user)
  • GET /tracking/datalastic/ship-specs/:vesselId - Get saved ship specifications for a vessel from database
  • GET /tracking/fiskeridir/search - Search the Norwegian fishing vessel register (any authenticated user)
  • GET /tracking/skipsregisteret/search - Search the Norwegian Ship Register (NOR/NIS) — any authenticated user
  • GET /tracking/status - Get AISstream tracking status
  • GET /vessel-drawings - List a vessel’s Work Visualizer drawing sheets (ordered)
  • GET /vessels/:id/marinetraffic-latest - Get latest MarineTraffic position for vessel
  • GET /vessels/:id/marinetraffic-positions - Get MarineTraffic positions for vessel
  • GET /vessels/:id/operational-summary - Get live operational counts for the map floating card
  • GET /vessels/:id/photo/exists - Check if vessel has photo
  • GET /vessels/imo/:imo - Get vessel by IMO number
  • GET /weather/bounds - Get weather data for a map bounding box (3x3 grid) (any of: view, view, view)
  • GET /weather/forecast/point - Get point forecast for a location (any of: view, view, view)
  • POST /weather/grid - Get weather data for specific coordinate points (any of: view, view, view)
  • GET /weather/status - Get weather service status (any of: view, view, view)
  • GET /weather/webcams - Get webcams near a location (any of: view, view, view)

UI app/m/fleet/page.tsx, components/dashboard/widget-registry.tsx, components/layout/sidebar.tsx, lib/mobile/modules.ts

modules.vessels.create - 1 API route(s), 1 UI file(s)

API routes

  • POST /vessels - Create a new vessel (requires modules.vessels.create)

UI components/layout/topbar.tsx

modules.vessels.edit - 58 API route(s), 1 UI file(s)

API routes

  • POST /sync/resolve-conflict - Manually resolve a sync conflict
  • POST /telemetry - Store telemetry data
  • GET /tracking/aisstream/config - Get AISstream API configuration (Admin only)
  • PATCH /tracking/aisstream/config - Update AISstream API configuration (Admin only)
  • GET /tracking/aisstream/vessel-intervals - Get per-vessel AIS tracking intervals (Admin only)
  • PATCH /tracking/aisstream/vessel-intervals - Bulk-update per-vessel AIS tracking intervals (Admin only)
  • GET /tracking/barentswatch/config - Get BarentsWatch AIS configuration (Admin only)
  • PATCH /tracking/barentswatch/config - Update BarentsWatch AIS configuration (Admin only)
  • POST /tracking/barentswatch/historic/:vesselId - Fetch and import up to 14 days of historic AIS track for one vessel (Admin only)
  • GET /tracking/barentswatch/lookup/:mmsi - Look up a single MMSI directly against the current combined feed (Admin only, debug)
  • GET /tracking/barentswatch/queue - Get vessel sync queue with status (Admin only)
  • GET /tracking/barentswatch/stats - Get BarentsWatch sync statistics (Admin only)
  • POST /tracking/barentswatch/sync - Manually sync all vessel positions from BarentsWatch (Admin only)
  • POST /tracking/barentswatch/sync/:vesselId - Force sync a specific vessel from BarentsWatch (Admin only)
  • POST /tracking/barentswatch/test - Test the configured BarentsWatch credentials by requesting a token (Admin only)
  • PATCH /tracking/barentswatch/vessel/:vesselId/sync-enabled - Toggle sync enabled for a vessel (Admin only)
  • GET /tracking/cascade/status - Get cascade sync status (Datalastic → Marinesia → AISstream)
  • POST /tracking/cascade/sync-all - Cascade sync all vessels (Datalastic → Marinesia → AISstream)
  • POST /tracking/cascade/sync/:vesselId - Cascade sync a specific vessel (Datalastic → Marinesia → AISstream)
  • GET /tracking/datalastic/config - Get Datalastic API configuration (Admin only)
  • PATCH /tracking/datalastic/config - Update Datalastic API configuration (Admin only)
  • GET /tracking/datalastic/queue - Get vessel sync queue for Datalastic (Admin only)
  • POST /tracking/datalastic/ship-specs/:vesselId/fetch - Fetch ship specs from Datalastic API and save to vessel (Admin only)
  • GET /tracking/datalastic/stats - Get Datalastic sync statistics (Admin only)
  • POST /tracking/datalastic/sync/:vesselId - Force sync a specific vessel from Datalastic (Admin only)
  • GET /tracking/datalastic/vessel/:identifier - Get vessel position from Datalastic by MMSI or IMO
  • PATCH /tracking/datalastic/vessel/:vesselId/sync-enabled - Toggle Datalastic sync enabled for a vessel (Admin only)
  • POST /tracking/fiskeridir/apply-specs/:vesselId - Apply admin-confirmed specs from a previewSpecs() result to a vessel (Admin only)
  • GET /tracking/fiskeridir/config - Get Fiskeridirektoratet Fartøyregister configuration (Admin only)
  • PATCH /tracking/fiskeridir/config - Enable/disable Fiskeridirektoratet Fartøyregister (Admin only)
  • POST /tracking/fiskeridir/preview-specs/:vesselId - Look up a vessel in Fartøyregisteret and return what would be applied, WITHOUT saving anything (Admin only)
  • GET /tracking/marinesia/config - Get Marinesia API configuration (Admin only)
  • PATCH /tracking/marinesia/config - Update Marinesia API configuration (Admin only)
  • POST /tracking/marinesia/enrich/:vesselId - Enrich vessel profile data from Marinesia (Admin only)
  • GET /tracking/marinesia/location/latest/:mmsi - Get latest vessel position from Marinesia by MMSI (Admin only)
  • GET /tracking/marinesia/profile/:mmsi - Get vessel profile from Marinesia by MMSI (Admin only)
  • GET /tracking/marinesia/queue - Get vessel sync queue with status (Admin only)
  • GET /tracking/marinesia/stats - Get Marinesia sync statistics (Admin only)
  • POST /tracking/marinesia/sync - Manually sync all vessel positions from Marinesia (Admin only)
  • POST /tracking/marinesia/sync/:vesselId - Force sync a specific vessel from Marinesia (Admin only)
  • PATCH /tracking/marinesia/vessel/:vesselId/sync-enabled - Toggle sync enabled for a vessel (Admin only)
  • POST /tracking/pause - Pause AISstream ingestion (Admin only)
  • POST /tracking/persist-interval - Set AISstream persist interval (ms); 0 to persist every message (Admin only)
  • POST /tracking/resume - Resume AISstream ingestion (Admin only)
  • POST /tracking/simulate - Simulate vessel movement for demo purposes (Admin only)
  • POST /tracking/skipsregisteret/apply-specs/:vesselId - Apply admin-confirmed specs from a previewSpecs() result to a vessel (Admin only)
  • GET /tracking/skipsregisteret/config - Get Skipsregisteret configuration (Admin only)
  • PATCH /tracking/skipsregisteret/config - Enable/disable Skipsregisteret (Admin only)
  • POST /tracking/skipsregisteret/preview-specs/:vesselId - Look up a vessel in Skipsregisteret and return what would be applied, WITHOUT saving anything (Admin only)
  • POST /tracking/update-all - Manually trigger tracking update for all vessels (Admin only)
  • POST /tracking/vessel/:id - Track a specific vessel by ID (Admin only)
  • POST /tracking/vesselfinder/update-all - Manually trigger VesselFinder update for all vessels (Admin only)
  • POST /tracking/vesselfinder/update/:vesselId - Manually update vessel from VesselFinder API (Admin only)
  • PATCH /vessels/:id - Update vessel (requires modules.vessels.edit)
  • POST /vessels/:id/fetch-track-data - Fetch MarineTraffic track data for vessel
  • DELETE /vessels/:id/photo - Delete vessel photo
  • POST /vessels/:id/photo - Upload vessel photo
  • PATCH /vessels/:id/status - Update vessel status

UI app/vessels/[id]/page-client.tsx

modules.vessels.delete - 1 API route(s), 0 UI file(s)

API routes

  • DELETE /vessels/:id - Delete vessel (requires modules.vessels.delete)
modules.vessels.set-position - 1 API route(s), 1 UI file(s)

API routes

  • PATCH /vessels/:id/position - Manually set vessel position (requires modules.vessels.set-position)

UI components/dashboard/vessel-list.tsx

Voyages (voyages)

Voyage planning and execution: voyages, legs, port calls, fuel logs, ports registry and fuel profiles.

Action Permission What it allows Enforcement
View modules.voyages.view Open the Voyages pages and read their data. API + UI - 20 routes
Create modules.voyages.create Create new Voyages records. API + UI - 2 routes
Edit modules.voyages.edit Change existing Voyages records. API + UI - 9 routes
Delete modules.voyages.delete Delete Voyages records. API + UI - 2 routes
modules.voyages.view - 20 API route(s), 1 UI file(s)

API routes

  • GET /maritime-poi - Maritime service businesses (OSM) within a bounding box — Fleet Map POI layer (any of: view, view, view)
  • GET /voyages - List voyages
  • GET /voyages/:id - Get a voyage with its legs and port calls
  • GET /voyages/:id/cargo - List cargo attached to this voyage
  • POST /voyages/:id/estimate - Recompute the fuel + cost estimate and return the full breakdown
  • GET /voyages/:id/report.pdf - Download the voyage report as a branded PDF
  • GET /voyages/:id/report.xlsx - Download the voyage as an Excel workbook
  • POST /voyages/calculate - Calculate route alternatives + distance/fuel for a planned leg-set
  • GET /voyages/fuel-profile/:vesselId - Get (or auto-seed) a vessel fuel profile
  • GET /voyages/ports - Search ports by name, alias, LOCODE or country (max 500 per page)
  • GET /voyages/ports/:id - One port, including World Port Index details
  • GET /voyages/ports/map - All ports with a position as compact tuples [id, name, locode, lat, lon, wpiSize] for the maps
  • GET /voyages/ports/nearest - Nearest ports to a position, with distance in NM
  • GET /voyages/ports/registry/status - Port registry version and coverage
  • GET /voyages/ports/search - Search ports for the route builder (name, alias, LOCODE; best match first, max 20)
  • GET /weather/bounds - Get weather data for a map bounding box (3x3 grid) (any of: view, view, view)
  • GET /weather/forecast/point - Get point forecast for a location (any of: view, view, view)
  • POST /weather/grid - Get weather data for specific coordinate points (any of: view, view, view)
  • GET /weather/status - Get weather service status (any of: view, view, view)
  • GET /weather/webcams - Get webcams near a location (any of: view, view, view)

UI components/layout/sidebar.tsx

modules.voyages.create - 2 API route(s), 1 UI file(s)

API routes

  • POST /voyages - Create a voyage
  • POST /voyages/ports - Create a port

UI app/voyages/page.tsx

modules.voyages.edit - 9 API route(s), 1 UI file(s)

API routes

  • PATCH /voyages/:id - Update a voyage
  • POST /voyages/:id/actual-fuel - Record actual bunkered fuel (feeds the learning correction factor)
  • POST /voyages/:id/cargo - Attach a cargo shipment (maps its ports onto voyage legs; warns if off-route)
  • DELETE /voyages/:id/cargo/:shipmentId - Detach a cargo shipment from this voyage
  • PUT /voyages/:id/legs - Replace the voyage leg-set (canonical route)
  • PUT /voyages/:id/port-calls - Replace the voyage port-call set
  • PATCH /voyages/:id/status - Advance a voyage through its lifecycle
  • PUT /voyages/fuel-profile/:vesselId - Update a vessel fuel profile (marks it manual/trusted)
  • PATCH /voyages/ports/:id - Update a port

UI app/voyages/page.tsx

modules.voyages.delete - 2 API route(s), 1 UI file(s)

API routes

  • DELETE /voyages/:id - Soft-delete a voyage
  • DELETE /voyages/ports/:id - Delete a port

UI app/voyages/page.tsx

Standard Work (standard-work)

The Standard Work library (job templates that Planned Maintenance schedules are built from).

Action Permission What it allows Enforcement
View modules.standard-work.view Open the Standard Work pages and read their data. API + UI - 4 routes
Create modules.standard-work.create Create new Standard Work records. API + UI - 2 routes
Edit modules.standard-work.edit Change existing Standard Work records. API + UI - 4 routes
Delete modules.standard-work.delete Delete Standard Work records. API + UI - 1 routes
modules.standard-work.view - 4 API route(s), 1 UI file(s)

API routes

  • GET /standards - List imported Standard Jobs
  • GET /standards/:id - Get a Standard Job by ID
  • GET /standards/filter-options - Get unique filter options for standard jobs
  • GET /uploads/list/:entityId - List files by entity ID (any of: view, view)

UI components/layout/sidebar.tsx

modules.standard-work.create - 2 API route(s), 1 UI file(s)

API routes

  • POST /standards - Create a new Standard Job
  • POST /standards/import - Import Standard Jobs from Excel (.xlsx)

UI app/standard-work/page.tsx

modules.standard-work.edit - 4 API route(s), 1 UI file(s)

API routes

  • PUT /standards/:id - Update a Standard Job
  • POST /standards/:id/unvalidate - Set validated = false for a Standard Job
  • POST /standards/:id/validate - Set validated = true for a Standard Job
  • POST /uploads/upload - Upload a file to local storage (any of: upload, edit)

UI app/standard-work/page.tsx

modules.standard-work.delete - 1 API route(s), 1 UI file(s)

API routes

  • DELETE /standards/:id - Delete a Standard Job

UI app/standard-work/page.tsx

Crew (crew)

Crew roster, vessel assignments, crew certificates/training/medical records, analytics (competency matrix, expiry dashboard, availability) and Hours of Rest.

Action Permission What it allows Enforcement
View modules.crew.view Open the Crew pages and read their data. API + UI - 20 routes
Create modules.crew.create Create new Crew records. API - 3 routes
Edit modules.crew.edit Change existing Crew records. API + UI - 12 routes
Delete modules.crew.delete Delete Crew records. API - 1 routes
Hours of rest: own record modules.crew.rest-own Hours of rest: work with your OWN record only. Stands on its own - does not require Crew: view. API + UI - 3 routes
Hours of rest: fill in anyone's modules.crew.rest-edit Hours of rest: fill in anyone's record. API + UI - 1 routes
Hours of rest: approve modules.crew.rest-approve Hours of rest: approve (sign off) records. API + UI - 1 routes
modules.crew.view - 20 API route(s), 3 UI file(s)

API routes

  • GET /crew/analytics/availability - Crew availability overview
  • GET /crew/analytics/competency-matrix - Crew competency matrix (crew x certificates)
  • GET /crew/analytics/expiry-dashboard - Upcoming expirations across certs/training/medical/passport/seaman book
  • GET /crew/assignments - Get crew assignments for a vessel
  • GET /crew/departments - Get crew count by department
  • GET /crew/history/:crewMemberId - Get assignment history for a crew member
  • GET /crew/integrity - Crew data integrity report
  • GET /crew/members - List crew members
  • GET /crew/members/:id - Get a crew member
  • GET /crew/members/:id/medical - List medical records for a crew member
  • GET /crew/members/:id/responsibilities - List responsibilities for a crew member
  • GET /crew/members/:id/training - List training records for a crew member
  • GET /crew/members/by-user/:userId - Resolve a user
  • GET /crew/members/unlinked - Crew members with no linked user
  • GET /crew/on-board - Get active crew currently on board a vessel
  • GET /crew/responsibilities - Find responsibilities by scope
  • GET /crew/rest/member/:id - One crew member month of work/rest days, checked against the regulation (any of: view, rest-own)
  • GET /crew/rest/regulation/:vesselId - The hours-of-rest limits that apply on a vessel
  • GET /crew/rest/vessel/:vesselId - Month overview for everyone serving on a vessel
  • GET /crew/users/unlinked - Users with no linked crew profile

UI app/crew/rest-hours/page.tsx, components/auth/auth-debug.tsx, components/layout/sidebar.tsx

modules.crew.create - 3 API route(s), 0 UI file(s)

API routes

  • POST /crew/embark - Create a new crew assignment (embark)
  • POST /crew/members - Create a crew member (optionally linked to a user)
  • POST /crew/seed-demo - Seed demo crew members across vessels (idempotent)
modules.crew.edit - 12 API route(s), 1 UI file(s)

API routes

  • PATCH /crew/disembark/:id - Complete a crew assignment (disembark)
  • PATCH /crew/members/:id - Update a crew member
  • POST /crew/members/:id/link-user - Link a crew member 1:1 to a user
  • POST /crew/members/:id/medical - Add a medical record (snapshots latest onto member)
  • POST /crew/members/:id/photo - Set crew member profile photo path
  • POST /crew/members/:id/responsibilities - Add a maintenance responsibility
  • POST /crew/members/:id/training - Add a training record
  • POST /crew/members/:id/unlink-user - Unlink the user from a crew member
  • DELETE /crew/responsibilities/:rid - Delete a responsibility
  • PUT /crew/rest/regulation/:vesselId - Set the hours-of-rest limits for a vessel
  • DELETE /crew/training/:tid - Delete a training record
  • PATCH /crew/training/:tid - Update a training record

UI app/crew/rest-hours/page.tsx

modules.crew.delete - 1 API route(s), 0 UI file(s)

API routes

  • DELETE /crew/members/:id - Deactivate (soft-delete) a crew member
modules.crew.rest-own - 3 API route(s), 1 UI file(s)

API routes

  • GET /crew/rest/member/:id - One crew member month of work/rest days, checked against the regulation (any of: view, rest-own)
  • PUT /crew/rest/member/:id/day/:date - Record one day of work and rest (any of: rest-edit, rest-own)
  • GET /crew/rest/mine - The crew record linked to your login (for the own-record right)

UI app/crew/rest-hours/page.tsx

modules.crew.rest-edit - 1 API route(s), 1 UI file(s)

API routes

  • PUT /crew/rest/member/:id/day/:date - Record one day of work and rest (any of: rest-edit, rest-own)

UI app/crew/rest-hours/page.tsx

modules.crew.rest-approve - 1 API route(s), 1 UI file(s)

API routes

  • POST /crew/rest/member/:id/approval - Approve (lock) or reopen the recorded days in a date range (never your own)

UI app/crew/rest-hours/page.tsx

Codes (codes)

Company code lists used in drop-downs (departments, makers, categories, component types, ...).

Action Permission What it allows Enforcement
View modules.codes.view Open the Codes pages and read their data. API + UI - 4 routes
Create modules.codes.create Create new Codes records. API + UI - 4 routes
Edit modules.codes.edit Change existing Codes records. API + UI - 2 routes
Delete modules.codes.delete Delete Codes records. API + UI - 3 routes
modules.codes.view - 4 API route(s), 1 UI file(s)

API routes

  • GET /codes - List code values; filter by type with ?type=key
  • GET /codes/export.csv - Export all code values as CSV
  • GET /codes/export.xlsx - Export all code types and values as Excel (.xlsx)
  • GET /codes/types - List all code types

UI components/layout/sidebar.tsx

modules.codes.create - 4 API route(s), 2 UI file(s)

API routes

  • POST /codes - Create a code value
  • POST /codes/import - Import codes from CSV or XLSX (multipart file upload or raw text/csv body)
  • POST /codes/seed-defaults - Restore default code types and values (idempotent)
  • POST /codes/sync-from-spares - Import makers, suppliers, maker types from spare_parts (distinct values)

UI app/codes/page.tsx, components/form/code-combobox.tsx

modules.codes.edit - 2 API route(s), 1 UI file(s)

API routes

  • PATCH /codes/:id - Update a code value
  • PATCH /codes/types/:id - Update a code type

UI app/codes/page.tsx

modules.codes.delete - 3 API route(s), 1 UI file(s)

API routes

  • DELETE /codes/:id - Delete a code value
  • DELETE /codes/types/:id - Delete a company-created code type
  • POST /codes/types/:key/reset-values - Clear a code type\

UI app/codes/page.tsx

📦 Inventory

Inventory (all) (inventory)

Umbrella grant for the Inventory folder: many inventory screens and lookups accept inventory.view as an alternative to their own module permission (e.g. Assets or Spare Parts). inventory.edit is declared but not enforced anywhere.

Action Permission What it allows Enforcement
View modules.inventory.view Open the Inventory (all) pages and read their data. API + UI - 71 routes
Edit modules.inventory.edit Declared but not enforced anywhere. not enforced - 0 routes
modules.inventory.view - 71 API route(s), 6 UI file(s)

API routes

  • GET /assets - Get all asset items (paginated) (any of: view, view)
  • GET /assets/:id - Get asset item by ID (any of: view, view)
  • GET /assets/:id/documents - List documents for an asset (any of: view, view)
  • GET /assets/:id/documents/:docId/download - Get a pre-signed download URL for a document (or direct URL for external docs) (any of: view, view)
  • GET /assets/:id/history - Get maintenance history for an asset (any of: view, view)
  • GET /assets/:id/spare-parts - List spare parts linked to an asset (any of: view, view)
  • GET /assets/:id/work-orders - List work orders for an asset (any of: view, view)
  • GET /assets/change-logs/recent - Fleet-wide recent asset changes (dashboard Recent Activity feed) (any of: view, view)
  • GET /assets/components - List all components (any of: view, view)
  • GET /assets/components/:id (any of: view, view)
  • GET /assets/components/:id/can-delete - Check if asset can be deleted (any of: view, view)
  • GET /assets/components/:id/certificates - Get certificates for an asset (any of: view, view)
  • GET /assets/components/:id/change-logs - Get change log for an asset (any of: view, view)
  • GET /assets/components/:id/documents (any of: view, view)
  • GET /assets/components/:id/documents/:docId/download (any of: view, view)
  • GET /assets/components/:id/history (any of: view, view)
  • GET /assets/components/:id/job-history - Get all work order history for an asset (any of: view, view)
  • GET /assets/components/:id/spare-parts (any of: view, view)
  • GET /assets/components/:id/work-orders (any of: view, view)
  • GET /assets/components/:id/work-orders/:woId/spares - List spare parts linked to a work order (any of: view, view)
  • GET /assets/components/history - Get all maintenance history with optional filtering (any of: view, view)
  • GET /assets/components/scrapped/all - Get all scrapped assets across all vessels (any of: view, view)
  • GET /assets/components/search - Search components (autocomplete) (any of: view, view)
  • GET /assets/components/search - Search components by name or SFI code (autocomplete) (any of: view, view)
  • GET /assets/components/vessel/:vesselId (any of: view, view)
  • GET /assets/components/vessel/:vesselId/scrapped - Get all scrapped assets for a vessel (any of: view, view)
  • GET /assets/components/vessel/:vesselId/sfi/:sfiGroup (any of: view, view)
  • GET /assets/components/vessel/:vesselId/stats (any of: view, view)
  • GET /assets/components/vessel/:vesselId/total-value - Get total asset value for a vessel (direct SQL query) (any of: view, view)
  • GET /assets/spares - List all spare parts (any of: view, view)
  • GET /assets/spares/:id (any of: view, view)
  • GET /assets/spares/:id/asset-links - Get all assets/components this spare part is linked to (any of: view, view)
  • GET /assets/spares/:id/transactions - Get stock transaction history for a spare part (any of: view, view)
  • GET /assets/spares/:id/work-order-usage - Get work order usage history for this spare part (any of: view, view)
  • GET /assets/spares/locations - List spare locations. Provide parentId to lazy-load children, else returns all in tree order. (any of: view, view)
  • GET /assets/spares/low-stock - Get count of items below minimum stock level (any of: view, view)
  • GET /assets/spares/reorder-report - Get spare parts that are below minimum quantity (reorder report) (any of: view, view)
  • GET /assets/spares/stock - List all spare parts for a specific vessel (direct or via asset link) (any of: view, view)
  • GET /assets/spares/transactions/all - Get all stock transactions, optionally filtered by vessel (any of: view, view)
  • GET /assets/spares/unlinked - List spare parts not linked to any asset (any of: view, view)
  • GET /assets/vessel/:vesselId - Get assets by vessel ID (any of: view, view)
  • GET /assets/vessel/:vesselId/sfi/:sfiGroup - Get assets by vessel and SFI group (any of: view, view)
  • GET /assets/vessel/:vesselId/stats - Get asset statistics for a vessel (any of: view, view)
  • GET /catalog-folders - List all catalog folders with item counts (any of: view, view)
  • GET /catalogs - List/search catalog items with filters and pagination (any of: view, view)
  • GET /catalogs/stats - Get total catalog items and last import metadata (any of: view, view)
  • GET /inventory/alarm-systems - List alarm systems with filters and pagination (any of: view, view)
  • GET /inventory/certificates - List certificates with filters and pagination (any of: view, view)
  • GET /medic/activity-log - Get activity log for medical inventory (any of: view, view)
  • GET /medic/analytics/expiring - Get expiring items (any of: view, view)
  • GET /medic/analytics/summary - Get medical inventory summary/KPIs (any of: view, view)
  • GET /medic/categories - Get all medical categories (any of: view, view)
  • GET /medic/compliance/:vesselId - Get full MLC compliance dashboard for vessel (3-leg score) (any of: view, view)
  • GET /medic/export/items.csv - Export items catalog to CSV (any of: view, view)
  • GET /medic/export/stock.csv - Export stock to CSV (any of: view, view)
  • GET /medic/inspections - Get inspections (any of: view, view)
  • GET /medic/inspections/:id - Get inspection details (any of: view, view)
  • GET /medic/items - Get medical items catalog (any of: view, view)
  • GET /medic/items/:id - Get medical item details (any of: view, view)
  • GET /medic/kits - Get all medical kits (any of: view, view)
  • GET /medic/kits/:id - Get medical kit details with items (any of: view, view)
  • GET /medic/kits/:id/compliance/:vesselId - Get kit compliance for vessel (any of: view, view)
  • GET /medic/missing/:vesselId - Get missing items for vessel (all kits or specific kit) (any of: view, view)
  • GET /medic/stock - Get medical stock for vessel (any of: view, view)
  • GET /medic/stock/:id - Get stock item details (any of: view, view)
  • GET /medic/usage - Get usage logs (any of: view, view)
  • GET /medic/usage/export.csv - Export usage logs to CSV (any of: view, view)
  • GET /medic/vessel-kits/:vesselId - Get kit assignments for a vessel (any of: view, view)
  • GET /vendor-catalogs - List vendor catalogs with optional supplier/search filter (any of: view, view)
  • GET /vendor-catalogs/:id/items - List items in a vendor catalog with optional search/filter (any of: view, view)
  • GET /vendor-catalogs/stats - Vendor catalog stats: total catalogs, items, breakdown by format (any of: view, view)

UI app/assets/page.tsx, app/assets/scrapped/page.tsx, app/spare-parts/page.tsx, app/stock/page.tsx, app/vessel-spares/page.tsx, components/layout/sidebar.tsx

Assets (assets)

The equipment register (SFI tree), asset detail pages (specification, criticality, FMEA, risk, tracking, documents, certificates), work orders and spare links raised from an asset, and maintenance history of an asset.

Action Permission What it allows Enforcement
View modules.assets.view Open the Assets pages and read their data. API + UI - 45 routes
Create modules.assets.create Create new Assets records. API - 2 routes
Edit modules.assets.edit Edit an asset and everything attached to it: fields, criticality/FMEA/risk, documents, spare links, history entries, and raising work orders from the asset. Also required to scrap/restore an asset and to create a work-order number. API + UI - 33 routes
Delete modules.assets.delete Delete an asset that has no job history (assets with history can only be scrapped). API - 2 routes
Move / Reorganize Codes modules.assets.move Move an asset elsewhere in the SFI tree / reassign its code (the dedicated Move endpoint). API + UI - 1 routes
Import modules.assets.import Bulk-import assets from a spreadsheet. API - 1 routes
modules.assets.view - 45 API route(s), 6 UI file(s)

API routes

  • GET /assets - Get all asset items (paginated) (any of: view, view)
  • GET /assets/:id - Get asset item by ID (any of: view, view)
  • GET /assets/:id/documents - List documents for an asset (any of: view, view)
  • GET /assets/:id/documents/:docId/download - Get a pre-signed download URL for a document (or direct URL for external docs) (any of: view, view)
  • GET /assets/:id/history - Get maintenance history for an asset (any of: view, view)
  • GET /assets/:id/spare-parts - List spare parts linked to an asset (any of: view, view)
  • GET /assets/:id/work-orders - List work orders for an asset (any of: view, view)
  • GET /assets/change-logs/recent - Fleet-wide recent asset changes (dashboard Recent Activity feed) (any of: view, view)
  • GET /assets/components - List all components (any of: view, view)
  • GET /assets/components/:id (any of: view, view)
  • GET /assets/components/:id/can-delete - Check if asset can be deleted (any of: view, view)
  • GET /assets/components/:id/certificates - Get certificates for an asset (any of: view, view)
  • GET /assets/components/:id/change-logs - Get change log for an asset (any of: view, view)
  • GET /assets/components/:id/documents (any of: view, view)
  • GET /assets/components/:id/documents/:docId/download (any of: view, view)
  • GET /assets/components/:id/history (any of: view, view)
  • GET /assets/components/:id/job-history - Get all work order history for an asset (any of: view, view)
  • GET /assets/components/:id/spare-parts (any of: view, view)
  • GET /assets/components/:id/work-orders (any of: view, view)
  • GET /assets/components/:id/work-orders/:woId/spares - List spare parts linked to a work order (any of: view, view)
  • GET /assets/components/history - Get all maintenance history with optional filtering (any of: view, view)
  • GET /assets/components/scrapped/all - Get all scrapped assets across all vessels (any of: view, view)
  • GET /assets/components/search - Search components (autocomplete) (any of: view, view)
  • GET /assets/components/search - Search components by name or SFI code (autocomplete) (any of: view, view)
  • GET /assets/components/vessel/:vesselId (any of: view, view)
  • GET /assets/components/vessel/:vesselId/scrapped - Get all scrapped assets for a vessel (any of: view, view)
  • GET /assets/components/vessel/:vesselId/sfi/:sfiGroup (any of: view, view)
  • GET /assets/components/vessel/:vesselId/stats (any of: view, view)
  • GET /assets/components/vessel/:vesselId/total-value - Get total asset value for a vessel (direct SQL query) (any of: view, view)
  • GET /assets/history/all - List maintenance history across all assets (filters & paging) (any of: view, view)
  • GET /assets/history/analytics/cost-trends - Get maintenance cost trends over time (monthly aggregation) (any of: view, view)
  • GET /assets/history/analytics/equipment-breakdown - Get maintenance breakdown by equipment type (any of: view, view)
  • GET /assets/history/analytics/summary - Get maintenance summary statistics (any of: view, view)
  • GET /assets/history/analytics/top-issues - Get top problem equipment by maintenance frequency (any of: view, view)
  • GET /assets/history/export.csv - Export maintenance history as CSV (server-side, supports filters) (any of: view, view)
  • GET /assets/history/export.xlsx - Export maintenance history as XLSX (server-side, supports filters) (any of: view, view)
  • GET /assets/vessel/:vesselId - Get assets by vessel ID (any of: view, view)
  • GET /assets/vessel/:vesselId/sfi/:sfiGroup - Get assets by vessel and SFI group (any of: view, view)
  • GET /assets/vessel/:vesselId/stats - Get asset statistics for a vessel (any of: view, view)
  • GET /movable/components/:assetId/movable - One component (any of: view, view)
  • GET /reports/asset-data.pdf - Asset Data Report (dossier) for selected assets (any of: view, view)
  • GET /reports/class-compliance.pdf - Class Compliance (PMS) report (any of: view, view)
  • GET /reports/compliance.pdf - PM Compliance report (any of: view, view, view)
  • GET /reports/maintenance-history.pdf - Maintenance History report (completed work) (any of: view, view, view)
  • GET /reports/maintenance-schedule.pdf - Maintenance Schedule report (upcoming PM) (any of: view, view, view)

UI app/assets/page.tsx, app/assets/scrapped/page.tsx, app/m/assets/[id]/page.tsx, app/m/assets/page.tsx, components/layout/sidebar.tsx, lib/mobile/modules.ts

modules.assets.create - 2 API route(s), 0 UI file(s)

API routes

  • POST /assets - Create new asset item
  • POST /assets/components
modules.assets.edit - 33 API route(s), 6 UI file(s)

API routes

  • PATCH /assets/:id - Update asset item
  • POST /assets/:id/documents - Add document to an asset
  • DELETE /assets/:id/documents/:docId - Delete a document from an asset
  • PATCH /assets/:id/documents/:docId - Update a document (name or url)
  • POST /assets/:id/documents/upload-url - Get a pre-signed upload URL for MinIO (S3)
  • POST /assets/:id/history - Add maintenance history record to an asset
  • POST /assets/:id/spare-parts - Link a spare part to an asset (or create and link)
  • DELETE /assets/:id/spare-parts/:partId - Unlink a spare part from an asset
  • PATCH /assets/:id/spare-parts/:partId/stock - Adjust spare part stock or supplier
  • POST /assets/:id/work-orders - Create work order for an asset
  • DELETE /assets/:id/work-orders/:woId - Delete a work order
  • PATCH /assets/:id/work-orders/:woId - Update work order (status, dates, costs, assignee)
  • PATCH /assets/components/:id
  • POST /assets/components/:id/change-logs - Add a change log entry for an asset
  • POST /assets/components/:id/documents
  • DELETE /assets/components/:id/documents/:docId
  • PATCH /assets/components/:id/documents/:docId
  • POST /assets/components/:id/history
  • POST /assets/components/:id/scrap - Scrap an asset/component
  • POST /assets/components/:id/spare-parts
  • DELETE /assets/components/:id/spare-parts/:partId
  • PATCH /assets/components/:id/spare-parts/:partId/stock
  • POST /assets/components/:id/unscrap - Un-scrap an asset/component
  • POST /assets/components/:id/work-orders
  • DELETE /assets/components/:id/work-orders/:woId
  • PATCH /assets/components/:id/work-orders/:woId
  • POST /assets/components/:id/work-orders/:woId/spares - Link spare parts to a work order
  • DELETE /assets/components/:id/work-orders/:woId/spares/:spareId - Unlink spare part from work order
  • PATCH /assets/components/:id/work-orders/:woId/spares/:spareId - Update spare part quantity on work order
  • POST /assets/components/:id/work-orders/:woId/spares/consume - Consume (deduct from stock) all spare parts linked to a work order
  • POST /assets/components/upload-image - Upload asset image
  • POST /maintenance/work-orders/generate-number - Generate next WO number from sequence (any of: create, edit, edit)
  • POST /reports/service - Create a new service report for an asset (any of: edit, edit)

UI app/assets/[id]/fmea/page-client.tsx, app/assets/[id]/job-history/page-client.tsx, app/assets/[id]/risk-evaluation/page-client.tsx, app/assets/[id]/specification/page-client.tsx, app/assets/[id]/tracking/page-client.tsx, components/assets/sfi-grid.tsx

modules.assets.delete - 2 API route(s), 0 UI file(s)

API routes

  • DELETE /assets/:id - Delete asset item
  • DELETE /assets/components/:id
modules.assets.move - 1 API route(s), 1 UI file(s)

API routes

  • POST /assets/components/:id/move - Move/reorganize an SFI node + its subtree under a new parent (requires modules.assets.move). Use dryRun=true for a preview.

UI components/assets/sfi-grid.tsx

modules.assets.import - 1 API route(s), 0 UI file(s)

API routes

  • POST /assets/components/bulk - Bulk create SFI components (requires modules.assets.import)

Movable Assets (movable-assets)

Movable assets (tools/equipment transferred between vessels with pro-forma invoices), their categories, locations, in-transit tracking and due jobs.

Action Permission What it allows Enforcement
View modules.movable-assets.view Open the Movable Assets pages and read their data. API + UI - 13 routes
Create modules.movable-assets.create Create new Movable Assets records. API + UI - 4 routes
Edit modules.movable-assets.edit Change existing Movable Assets records. API + UI - 8 routes
Approve modules.movable-assets.approve Approve a pro-forma invoice (it gets its number and the shipping list locks). API + UI - 1 routes
Revoke approval modules.movable-assets.revoke Revoke the approval of an invoice, until the package is sent. The steps after approval then have to be done again. API + UI - 1 routes
Set to packed modules.movable-assets.pack Set an approved invoice to packed (the people packing tell the office it is ready). API + UI - 1 routes
Send modules.movable-assets.send Send the package: the assets go in transit, onboard can no longer change them, and their jobs can be paused. API + UI - 1 routes
Set as received modules.movable-assets.receive Register what the receiving vessel has received, partly if need be. Received assets move to the receiving vessel. API + UI - 1 routes
Finish and set active modules.movable-assets.finish Finish the invoice: the received assets become active onboard and their jobs come back on the due list. API + UI - 1 routes
Cancel modules.movable-assets.cancel Cancel an invoice that has not been sent. The assets are active onboard again. API + UI - 1 routes
Manage modules.movable-assets.manage Administer movable-asset categories and which vessels carry them. API + UI - 8 routes
modules.movable-assets.view - 13 API route(s), 2 UI file(s)

API routes

  • GET /movable/categories - Movable categories with the vessels designated to receive each
  • GET /movable/components - Movable components across the fleet
  • GET /movable/components/:assetId/movable - One component (any of: view, view)
  • GET /movable/due-in-transit - Open jobs of assets that are travelling, and which are paused
  • GET /movable/holding-bay - A vessel
  • GET /movable/in-transit - Assets on their way
  • GET /movable/invoices - Pro-forma invoices
  • GET /movable/invoices/:id - One invoice with its shipping list, packages, history and what may be done next
  • GET /movable/invoices/:id/files - Documents attached to the transfer
  • GET /movable/invoices/:id/warnings - Open jobs, permits and running-hours links worth knowing before the transfer
  • GET /movable/locations - Movable stock locations across the fleet
  • GET /movable/locations/:locationId/items - The items inside a movable stock location
  • GET /movable/movements - Transfer history of movable assets

UI components/assets/asset-movable-card.tsx, components/layout/sidebar.tsx

modules.movable-assets.create - 4 API route(s), 1 UI file(s)

API routes

  • DELETE /movable/invoice-lines/:lineId - Take an asset off the shipping list
  • POST /movable/invoices - Start a pro-forma invoice
  • POST /movable/invoices/:id/components - Add a movable component to the shipping list
  • POST /movable/invoices/:id/locations - Add a movable stock location to the shipping list

UI app/movable-assets/page.tsx

modules.movable-assets.edit - 8 API route(s), 1 UI file(s)

API routes

  • DELETE /movable/files/:fileId - Remove an attached document
  • PATCH /movable/invoices/:id - Change the invoice details
  • POST /movable/invoices/:id/files - Attach a document to the transfer
  • POST /movable/invoices/:id/jobs/disable - Pause the scheduled jobs of the assets on the invoice
  • POST /movable/invoices/:id/jobs/enable - Switch the paused jobs on again with the chosen due-date rule
  • POST /movable/invoices/:id/packages - Add a package
  • DELETE /movable/packages/:packageId - Remove a package
  • PATCH /movable/packages/:packageId - Change a package

UI app/movable-assets/page.tsx

modules.movable-assets.approve - 1 API route(s), 1 UI file(s)

API routes

  • POST /movable/invoices/:id/approve - Approve: number the invoice, lock the shipping list, check the receiver can take the categories

UI app/movable-assets/page.tsx

modules.movable-assets.revoke - 1 API route(s), 1 UI file(s)

API routes

  • POST /movable/invoices/:id/revoke - Revoke the approval (until the package is sent)

UI app/movable-assets/page.tsx

modules.movable-assets.pack - 1 API route(s), 1 UI file(s)

API routes

  • POST /movable/invoices/:id/pack - Set the invoice to packed

UI app/movable-assets/page.tsx

modules.movable-assets.send - 1 API route(s), 1 UI file(s)

API routes

  • POST /movable/invoices/:id/send - Send the package: the assets are in transit; their jobs can be paused

UI app/movable-assets/page.tsx

modules.movable-assets.receive - 1 API route(s), 1 UI file(s)

API routes

  • POST /movable/invoices/:id/receive - Register what the receiving vessel has received (partly if need be)

UI app/movable-assets/page.tsx

modules.movable-assets.finish - 1 API route(s), 1 UI file(s)

API routes

  • POST /movable/invoices/:id/finish - Finish: the assets are active onboard and their jobs come back

UI app/movable-assets/page.tsx

modules.movable-assets.cancel - 1 API route(s), 1 UI file(s)

API routes

  • POST /movable/invoices/:id/cancel - Cancel an invoice that has not been sent

UI app/movable-assets/page.tsx

modules.movable-assets.manage - 8 API route(s), 2 UI file(s)

API routes

  • POST /movable/categories - Add a movable category
  • DELETE /movable/categories/:id - Delete a category nothing uses
  • PATCH /movable/categories/:id - Change a movable category
  • PUT /movable/categories/:id/vessels - Set which vessels may receive this category
  • DELETE /movable/components/:assetId - Make a component fixed again
  • POST /movable/components/mark - Make a component (and its sub components) movable
  • DELETE /movable/locations/:locationId - Make a stock location fixed again
  • POST /movable/locations/mark - Make a stock location movable

UI app/movable-assets/page.tsx, components/assets/asset-movable-card.tsx

Warehouse & Catalogs (catalogs)

Warehouse catalogs and vendor catalogs (folders, items, imports).

Action Permission What it allows Enforcement
View modules.catalogs.view Open the Warehouse & Catalogs pages and read their data. API + UI - 6 routes
Create modules.catalogs.create Create new Warehouse & Catalogs records. API - 3 routes
Edit modules.catalogs.edit Change existing Warehouse & Catalogs records. API - 2 routes
Delete modules.catalogs.delete Delete Warehouse & Catalogs records. API - 4 routes
Import modules.catalogs.import Import Warehouse & Catalogs data. API - 5 routes
modules.catalogs.view - 6 API route(s), 1 UI file(s)

API routes

  • GET /catalog-folders - List all catalog folders with item counts (any of: view, view)
  • GET /catalogs - List/search catalog items with filters and pagination (any of: view, view)
  • GET /catalogs/stats - Get total catalog items and last import metadata (any of: view, view)
  • GET /vendor-catalogs - List vendor catalogs with optional supplier/search filter (any of: view, view)
  • GET /vendor-catalogs/:id/items - List items in a vendor catalog with optional search/filter (any of: view, view)
  • GET /vendor-catalogs/stats - Vendor catalog stats: total catalogs, items, breakdown by format (any of: view, view)

UI components/layout/sidebar.tsx

modules.catalogs.create - 3 API route(s), 0 UI file(s)

API routes

  • POST /catalog-folders - Create new catalog folder
  • POST /catalogs - Create a single catalog item
  • POST /vendor-catalogs - Create a new vendor catalog header (without items)
modules.catalogs.edit - 2 API route(s), 0 UI file(s)

API routes

  • PATCH /catalog-folders/:id - Update catalog folder
  • PATCH /catalogs/:id - Update catalog item fields (name, unit, makerPartNo, stockQty)
modules.catalogs.delete - 4 API route(s), 0 UI file(s)

API routes

  • DELETE /catalog-folders/:id - Delete catalog folder
  • DELETE /catalogs - Delete multiple catalog items by IDs
  • DELETE /vendor-catalogs/:id - Delete a vendor catalog and all its items (cascade)
  • DELETE /vendor-catalogs/items/:itemId - Delete a single vendor catalog item
modules.catalogs.import - 5 API route(s), 0 UI file(s)

API routes

  • POST /catalogs/bulk-import - Bulk import catalog items from parsed Excel data
  • POST /catalogs/import - Bulk import catalog items (IMPA/ISSA). Accepts CSV/XLSX-parsed array.
  • POST /catalogs/import/xlsx - Import catalog items from Excel (.xlsx) with headers: Item Code, Item Name, Catalog Type, Maker’s Part No, Unit, In Stock, SupplierId
  • POST /vendor-catalogs/:id/items/import-json - Bulk import items from parsed JSON array (for programmatic use)
  • POST /vendor-catalogs/:id/items/import-xlsx - Import items into a vendor catalog from Excel (.xlsx). Auto-detects IMPA / ISSA / Generic format.

Spare Parts (spare-parts)

Spare parts inventory: parts, stock locations, stock levels, imports, spare numbering.

Action Permission What it allows Enforcement
View modules.spare-parts.view Open the Spare Parts pages and read their data. API + UI - 11 routes
Create modules.spare-parts.create Create new Spare Parts records. API + UI - 4 routes
Edit modules.spare-parts.edit Change existing Spare Parts records. API + UI - 14 routes
Delete modules.spare-parts.delete Delete Spare Parts records. API - 2 routes
Adjust Stock modules.spare-parts.adjust Adjust stock quantities of a spare part. API + UI - 1 routes
modules.spare-parts.view - 11 API route(s), 7 UI file(s)

API routes

  • GET /assets/spares - List all spare parts (any of: view, view)
  • GET /assets/spares/:id (any of: view, view)
  • GET /assets/spares/:id/asset-links - Get all assets/components this spare part is linked to (any of: view, view)
  • GET /assets/spares/:id/transactions - Get stock transaction history for a spare part (any of: view, view)
  • GET /assets/spares/:id/work-order-usage - Get work order usage history for this spare part (any of: view, view)
  • GET /assets/spares/locations - List spare locations. Provide parentId to lazy-load children, else returns all in tree order. (any of: view, view)
  • GET /assets/spares/low-stock - Get count of items below minimum stock level (any of: view, view)
  • GET /assets/spares/reorder-report - Get spare parts that are below minimum quantity (reorder report) (any of: view, view)
  • GET /assets/spares/stock - List all spare parts for a specific vessel (direct or via asset link) (any of: view, view)
  • GET /assets/spares/transactions/all - Get all stock transactions, optionally filtered by vessel (any of: view, view)
  • GET /assets/spares/unlinked - List spare parts not linked to any asset (any of: view, view)

UI app/m/stock/[id]/page.tsx, app/m/stock/page.tsx, app/spare-parts/page.tsx, app/vessel-spares/page.tsx, components/dashboard/widget-registry.tsx, components/layout/sidebar.tsx, lib/mobile/modules.ts

modules.spare-parts.create - 4 API route(s), 1 UI file(s)

API routes

  • POST /assets/spares
  • POST /assets/spares/import - Import spare parts (dry-run or commit)
  • POST /settings/spare-sequence/generate - Generate next Spare Part number for a vessel (any of: create, edit)
  • POST /settings/spare-sequence/register - Register a manually entered spare part number to prevent reuse (any of: create, edit)

UI app/stock/page.tsx

modules.spare-parts.edit - 14 API route(s), 5 UI file(s)

API routes

  • PATCH /assets/spares/:id
  • PATCH /assets/spares/:id/block - Block or unblock a spare part
  • PATCH /assets/spares/:id/critical - Mark or unmark a spare part as critical
  • POST /assets/spares/locations - Create a location folder (root or subfolder). Provide name and optional parentId + map placement
  • DELETE /assets/spares/locations/:id - Delete a location. cascade=true also removes sub-locations, moves spare parts to No Location and clears component links.
  • PATCH /assets/spares/locations/:id - Rename a location folder and update descendant paths and assigned parts
  • PATCH /assets/spares/locations/:id/mapping - Save the Work Visualizer pin (normalized map_x/map_y + deck view) for a location. Pass null to clear a pin.
  • PATCH /assets/spares/move-location - Move multiple spare parts to a location (by id, path, or clear to No Location)
  • POST /settings/spare-sequence/generate - Generate next Spare Part number for a vessel (any of: create, edit)
  • POST /settings/spare-sequence/register - Register a manually entered spare part number to prevent reuse (any of: create, edit)
  • POST /vessel-drawings - Upload a drawing sheet. Send a renderable image as
  • DELETE /vessel-drawings/:id - Delete a drawing sheet (its pins are unlinked, not deleted)
  • PATCH /vessel-drawings/:id - Rename a drawing sheet
  • PATCH /vessel-drawings/reorder - Reorder a vessel’s drawing sheets

UI app/spare-parts/page.tsx, app/stock/page.tsx, components/locations/LocationSelect.tsx, components/spares/spare-detail-card.tsx, components/visualizer/LocationManager.tsx

modules.spare-parts.delete - 2 API route(s), 0 UI file(s)

API routes

  • DELETE /assets/spares/:id
  • POST /assets/spares/cleanup-unassigned - Delete all spare parts with no vessel assignment (vesselId IS NULL) — superadmin + password
modules.spare-parts.adjust - 1 API route(s), 1 UI file(s)

API routes

  • POST /assets/spares/:id/adjust - Adjust stock quantity (receive, consume, adjust, scrap, return)

UI app/m/stock/[id]/page.tsx

Stock (stock)

The Stock page (a stock view over spares). Enforced in the UI only.

Action Permission What it allows Enforcement
View modules.stock.view Open the Stock pages and read their data. UI only - 0 routes
Adjust Stock modules.stock.adjust Declared; stock changes are enforced through Spare Parts: adjust. not enforced - 0 routes
modules.stock.view - 0 API route(s), 2 UI file(s)

UI app/stock/page.tsx, components/layout/sidebar.tsx

Alarm System (alarm-system)

Alarm equipment tracking (fire, safety, engine alarms).

Action Permission What it allows Enforcement
View modules.alarm-system.view Open the Alarm System pages and read their data. API + UI - 1 routes
Edit modules.alarm-system.edit Change existing Alarm System records. API + UI - 3 routes
Acknowledge modules.alarm-system.acknowledge Acknowledge an alarm. Declared but not currently enforced. not enforced - 0 routes
modules.alarm-system.view - 1 API route(s), 1 UI file(s)

API routes

  • GET /inventory/alarm-systems - List alarm systems with filters and pagination (any of: view, view)

UI components/layout/sidebar.tsx

modules.alarm-system.edit - 3 API route(s), 1 UI file(s)

API routes

  • POST /inventory/alarm-systems - Create an alarm (Admin only)
  • DELETE /inventory/alarm-systems/:id - Delete an alarm (Admin only)
  • PATCH /inventory/alarm-systems/:id - Update an alarm (Admin only)

UI app/alarm-system/page.tsx

Certificates (certificates)

Crew and vessel certificates, certificate types and the reminder automation.

Action Permission What it allows Enforcement
View modules.certificates.view Open the Certificates pages and read their data. API + UI - 26 routes
Create modules.certificates.create Create new Certificates records. API + UI - 5 routes
Edit modules.certificates.edit Change existing Certificates records. API - 6 routes
Delete modules.certificates.delete Delete Certificates records. API - 4 routes
modules.certificates.view - 26 API route(s), 4 UI file(s)

API routes

  • GET /certificates/crew - Get all crew certificates
  • GET /certificates/crew/:id - Get crew certificate by ID
  • GET /certificates/crew/crew-member/:crewMemberId - Get all certificates for a crew member
  • GET /certificates/crew/crew-member/:crewMemberId/compliance - Get crew member compliance status
  • GET /certificates/crew/expired - Get expired crew certificates
  • GET /certificates/crew/expiring - Get expiring crew certificates
  • GET /certificates/crew/statistics - Get crew certificates statistics
  • GET /certificates/reminders/summary - Get certificate reminder automation summary
  • GET /certificates/reports/crew/:crewMemberId/pdf - Download crew certificates PDF report
  • GET /certificates/reports/fleet/pdf - Download fleet certificates snapshot PDF report
  • GET /certificates/reports/vessel/:vesselId/pdf - Download vessel certificates PDF report
  • GET /certificates/types - Get all certificate types
  • GET /certificates/types/:id - Get certificate type by ID
  • GET /certificates/types/code/:code - Get certificate type by code
  • GET /certificates/types/crew - Get all crew certificate types
  • GET /certificates/types/statistics - Get certificate types statistics
  • GET /certificates/types/vessel - Get all vessel certificate types
  • GET /certificates/vessel - Get all vessel certificates
  • GET /certificates/vessel/:id - Get vessel certificate by ID
  • GET /certificates/vessel/by-vessel/:vesselId - Get all certificates for a vessel
  • GET /certificates/vessel/by-vessel/:vesselId/compliance - Get vessel compliance status
  • GET /certificates/vessel/class-society/:classSociety - Get certificates by class society
  • GET /certificates/vessel/expired - Get expired vessel certificates
  • GET /certificates/vessel/expiring - Get expiring vessel certificates
  • GET /certificates/vessel/statistics - Get vessel certificates statistics
  • GET /inventory/certificates - List certificates with filters and pagination (any of: view, view)

UI app/m/certificates/page.tsx, components/dashboard/widget-registry.tsx, components/layout/sidebar.tsx, lib/mobile/modules.ts

modules.certificates.create - 5 API route(s), 2 UI file(s)

API routes

  • POST /assets/components/:id/certificates - Create a certificate for an asset
  • POST /certificates/crew - Create a new crew certificate
  • POST /certificates/types - Create a new certificate type (requires modules.certificates.create)
  • POST /certificates/vessel - Create a new vessel certificate
  • POST /inventory/certificates - Create a certificate (Admin only)

UI app/assets/[id]/certificates/page-client.tsx, app/certificates/page.tsx

modules.certificates.edit - 6 API route(s), 0 UI file(s)

API routes

  • PUT /assets/components/:id/certificates/:certId - Update an asset certificate
  • PUT /certificates/crew/:id - Update a crew certificate
  • PUT /certificates/vessel/:id - Update a vessel certificate
  • PATCH /inventory/certificates/:id - Update a certificate (Admin only)
  • POST /inventory/certificates/:id/attachments - Attach a file to the certificate (Admin only)
  • POST /inventory/certificates/:id/renew - Renew a certificate (Admin only)
modules.certificates.delete - 4 API route(s), 0 UI file(s)

API routes

  • DELETE /assets/components/:id/certificates/:certId - Delete an asset certificate
  • DELETE /certificates/crew/:id - Delete a crew certificate
  • DELETE /certificates/vessel/:id - Delete a vessel certificate
  • DELETE /inventory/certificates/:id - Delete a certificate (Admin only)

Compliance (compliance)

Compliance status per vessel: the "Can sail?" status, blocking issues, expiring items, compliance snapshots.

Action Permission What it allows Enforcement
View modules.compliance.view Open the Compliance pages and read their data. API + UI - 6 routes
Edit modules.compliance.edit Change existing Compliance records. API - 2 routes
modules.compliance.view - 6 API route(s), 1 UI file(s)

API routes

  • GET /compliance/blocking-issues - Get all vessels with blocking compliance issues
  • GET /compliance/can-sail - Check if vessel can sail
  • GET /compliance/expiring - Get items expiring within specified days
  • GET /compliance/status - Get all compliance checks for a vessel
  • GET /compliance/summary - Get vessel compliance summary
  • GET /reports/compliance.pdf - PM Compliance report (any of: view, view, view)

UI components/layout/sidebar.tsx

modules.compliance.edit - 2 API route(s), 0 UI file(s)

API routes

  • POST /compliance/evaluate-all - Trigger compliance evaluation for all vessels
  • POST /compliance/evaluate/:vesselId - Trigger compliance evaluation for a specific vessel

Medic (medic)

Medical inventory: kits, stock, inspections, usage logs, analytics and per-vessel kit assignment.

Action Permission What it allows Enforcement
View modules.medic.view Open the Medic pages and read their data. API + UI - 20 routes
Create modules.medic.create Create new Medic records. API - 3 routes
Edit modules.medic.edit Change existing Medic records. API + UI - 32 routes
Delete modules.medic.delete Delete Medic records. API + UI - 2 routes
modules.medic.view - 20 API route(s), 2 UI file(s)

API routes

  • GET /medic/activity-log - Get activity log for medical inventory (any of: view, view)
  • GET /medic/analytics/expiring - Get expiring items (any of: view, view)
  • GET /medic/analytics/summary - Get medical inventory summary/KPIs (any of: view, view)
  • GET /medic/categories - Get all medical categories (any of: view, view)
  • GET /medic/compliance/:vesselId - Get full MLC compliance dashboard for vessel (3-leg score) (any of: view, view)
  • GET /medic/export/items.csv - Export items catalog to CSV (any of: view, view)
  • GET /medic/export/stock.csv - Export stock to CSV (any of: view, view)
  • GET /medic/inspections - Get inspections (any of: view, view)
  • GET /medic/inspections/:id - Get inspection details (any of: view, view)
  • GET /medic/items - Get medical items catalog (any of: view, view)
  • GET /medic/items/:id - Get medical item details (any of: view, view)
  • GET /medic/kits - Get all medical kits (any of: view, view)
  • GET /medic/kits/:id - Get medical kit details with items (any of: view, view)
  • GET /medic/kits/:id/compliance/:vesselId - Get kit compliance for vessel (any of: view, view)
  • GET /medic/missing/:vesselId - Get missing items for vessel (all kits or specific kit) (any of: view, view)
  • GET /medic/stock - Get medical stock for vessel (any of: view, view)
  • GET /medic/stock/:id - Get stock item details (any of: view, view)
  • GET /medic/usage - Get usage logs (any of: view, view)
  • GET /medic/usage/export.csv - Export usage logs to CSV (any of: view, view)
  • GET /medic/vessel-kits/:vesselId - Get kit assignments for a vessel (any of: view, view)

UI components/layout/sidebar.tsx, lib/mobile/modules.ts

modules.medic.create - 3 API route(s), 0 UI file(s)

API routes

  • POST /medic/categories - Create medical category
  • POST /medic/stock - Add stock item
  • POST /medic/stock/logged - Add stock item with activity logging
modules.medic.edit - 32 API route(s), 1 UI file(s)

API routes

  • DELETE /medic/admin/wipe-all - FULL RESET: delete every medical record across all vessels, including the global catalog (items, categories, kits).
  • DELETE /medic/admin/wipe-vessel/:vesselId - Delete ALL medical data for one vessel (stock, usage logs, inspections, kit assignments). Keeps the shared catalog.
  • PUT /medic/categories/:id - Update medical category
  • POST /medic/import/items - Import items from JSON array
  • POST /medic/import/stock - Import stock from JSON array
  • POST /medic/inspections - Create inspection
  • POST /medic/inspections/:id/sign-off - Sign off inspection
  • POST /medic/kits - Create medical kit
  • DELETE /medic/kits/:id - Delete medical kit — stock items are preserved, kit_id is cleared on linked stock
  • PUT /medic/kits/:id - Update medical kit
  • POST /medic/kits/:id/items - Add item to kit
  • DELETE /medic/kits/items/:kitItemId - Remove item from kit
  • POST /medic/seed/all - Seed all medical data (categories, items, kits) and stock for a vessel
  • POST /medic/seed/categories - Seed default medical categories
  • POST /medic/seed/categories - Seed default medical categories
  • POST /medic/seed/items - Seed sample medical items catalog
  • POST /medic/seed/kits - Seed default medical kits
  • POST /medic/seed/kits - Seed default medical kits
  • POST /medic/seed/stock - Seed demo medical stock for a vessel
  • PUT /medic/stock/:id - Update stock item
  • POST /medic/stock/:id/adjust - Adjust stock quantity
  • POST /medic/stock/:id/adjust/logged - Adjust stock quantity with activity logging
  • POST /medic/stock/:id/assign-kit - Assign stock to a medical kit
  • POST /medic/stock/:id/consume - Consume stock (use for treatment) with activity logging
  • PUT /medic/stock/:id/logged - Update stock item with activity logging
  • POST /medic/stock/:id/remove-kit - Remove stock from its medical kit
  • POST /medic/stock/:id/restock - Add quantity as a dated batch (merges into a matching-expiry batch or creates a new one)
  • POST /medic/usage - Log medical supply usage
  • PUT /medic/vessel-kits/:id - Update vessel kit assignment (interval, auto-schedule)
  • POST /medic/vessel-kits/:vesselId/auto-populate - Auto-populate vessel kits from vessel MLC category (A/B/C)
  • POST /medic/vessel-kits/:vesselId/kits - Assign a kit to a vessel
  • DELETE /medic/vessel-kits/:vesselId/kits/:kitId - Remove a kit assignment from a vessel

UI app/medic/page.tsx

modules.medic.delete - 2 API route(s), 1 UI file(s)

API routes

  • DELETE /medic/categories/:id - Delete medical category
  • DELETE /medic/stock/:id - Remove stock item

UI app/medic/page.tsx

Medical Items (medic-items)

The medical item master list. Enforced in the UI only.

Action Permission What it allows Enforcement
View modules.medic-items.view Open the Medical Items pages and read their data. UI only - 0 routes
Create modules.medic-items.create Create new Medical Items records. API + UI - 1 routes
Edit modules.medic-items.edit Change existing Medical Items records. API + UI - 1 routes
Delete modules.medic-items.delete Delete Medical Items records. API + UI - 1 routes
modules.medic-items.view - 0 API route(s), 1 UI file(s)

UI app/medic/page.tsx

modules.medic-items.create - 1 API route(s), 1 UI file(s)

API routes

  • POST /medic/items - Create medical item

UI app/medic/page.tsx

modules.medic-items.edit - 1 API route(s), 1 UI file(s)

API routes

  • PUT /medic/items/:id - Update medical item

UI app/medic/page.tsx

modules.medic-items.delete - 1 API route(s), 1 UI file(s)

API routes

  • DELETE /medic/items/:id - Delete medical item

UI app/medic/page.tsx

🛒 Buy

Procurement (procurement)

Procurement documents: requisitions, RFQs, quotations and supplier comparison.

Action Permission What it allows Enforcement
View modules.procurement.view Open the Procurement pages and read their data. API + UI - 14 routes
Create modules.procurement.create Create new Procurement records. API - 3 routes
Edit modules.procurement.edit Change existing Procurement records. API - 12 routes
Delete modules.procurement.delete Delete Procurement records. API - 3 routes
modules.procurement.view - 14 API route(s), 1 UI file(s)

API routes

  • GET /po (any of: view, view)
  • GET /po/:id (any of: view, view)
  • GET /po/create (any of: view, view)
  • GET /po/vessel/:vesselId/stats (any of: view, view)
  • GET /procurement/quotations
  • GET /procurement/quotations/:id
  • GET /procurement/requisitions
  • GET /procurement/requisitions/:id
  • GET /procurement/requisitions/:id/history
  • GET /procurement/rfqs
  • GET /procurement/rfqs/:id
  • GET /procurement/suppliers - List suppliers with filters and pagination (any of: view, view)
  • GET /procurement/suppliers/template - Download supplier import template (.xlsx) (any of: view, view)
  • GET /procurement/suppliers/with-locations - Suppliers with geocoded coordinates (Fleet Map supplier layer) (any of: view, view)

UI components/layout/sidebar.tsx

modules.procurement.create - 3 API route(s), 0 UI file(s)

API routes

  • POST /procurement/quotations
  • POST /procurement/requisitions
  • POST /procurement/rfqs
modules.procurement.edit - 12 API route(s), 0 UI file(s)

API routes

  • PUT /procurement/quotations/:id
  • POST /procurement/quotations/:id/award
  • POST /procurement/quotations/:id/evaluate
  • POST /procurement/quotations/:id/reject
  • POST /procurement/quotations/:id/shortlist
  • PUT /procurement/requisitions/:id
  • POST /procurement/requisitions/:id/approve
  • POST /procurement/requisitions/:id/submit
  • PUT /procurement/rfqs/:id
  • POST /procurement/rfqs/:id/cancel
  • POST /procurement/rfqs/:id/close
  • POST /procurement/rfqs/:id/issue
modules.procurement.delete - 3 API route(s), 0 UI file(s)

API routes

  • DELETE /procurement/quotations/:id
  • DELETE /procurement/requisitions/:id
  • DELETE /procurement/rfqs/:id

Purchase Orders (po)

Purchase orders: creation, items, split orders, supplier quotes/inquiries, approval workflow and budget control.

Action Permission What it allows Enforcement
View modules.po.view Open the Purchase Orders pages and read their data. API + UI - 4 routes
Create modules.po.create Create new Purchase Orders records. API - 1 routes
Edit modules.po.edit Change existing Purchase Orders records. API + UI - 30 routes
Approve modules.po.approve Approve purchase orders at approval level 1. API - 1 routes
Approve: level 2 modules.po.approve-2 Approve purchase orders that need approval level 2 (higher value). service rule (Enforced in the PO approval service (approval level).) - 0 routes
Approve: level 3 modules.po.approve-3 Approve purchase orders that need approval level 3 (highest value). service rule (Enforced in the PO approval service (approval level).) - 0 routes
Approve over budget modules.po.approve-overspend Approve an order that takes a budget category past its tolerated overspend. service rule (Enforced in the PO approval service (budget control).) - 0 routes
Delete modules.po.delete Delete Purchase Orders records. API - 1 routes
modules.po.view - 4 API route(s), 1 UI file(s)

API routes

  • GET /po (any of: view, view)
  • GET /po/:id (any of: view, view)
  • GET /po/create (any of: view, view)
  • GET /po/vessel/:vesselId/stats (any of: view, view)

UI components/dashboard/widget-registry.tsx

modules.po.create - 1 API route(s), 0 UI file(s)

API routes

  • POST /po
modules.po.edit - 30 API route(s), 2 UI file(s)

API routes

  • PUT /po-depth/:id/budget-category - Set which budget category the order is charged to
  • POST /po-depth/:id/confirm - Record the supplier
  • POST /po-depth/:id/hold - Put the order on hold
  • POST /po-depth/:id/inquiries - Ask more suppliers to quote
  • POST /po-depth/:id/paid - Mark the order as paid: it moves from committed to used budget
  • POST /po-depth/:id/release - Release the order from hold
  • POST /po-depth/:id/revert - Move the order back a step, with a reason
  • POST /po-depth/:id/select - Choose the supplier: its prices are copied onto the order lines
  • POST /po-depth/:id/snooze - Silence the late-delivery reminder until a date
  • POST /po-depth/:id/split - Split the order between suppliers: one order each, this one is closed as split
  • DELETE /po-depth/inquiries/:inquiryId - Remove a supplier from the inquiry list
  • PUT /po-depth/inquiries/:inquiryId/quote - Record a supplier
  • POST /po-depth/inquiries/:inquiryId/send - Mark an inquiry as sent to the supplier
  • PUT /po/:id
  • POST /po/:id/cancel
  • POST /po/:id/complete
  • POST /po/:id/delivered/3rdparty
  • POST /po/:id/delivered/vessel
  • POST /po/:id/delivered/warehouse
  • POST /po/:id/in-transit
  • POST /po/:id/items
  • DELETE /po/:id/items/:itemId
  • PUT /po/:id/items/:itemId
  • POST /po/:id/items/:itemId/receive
  • POST /po/:id/order
  • POST /po/:id/quote-received
  • POST /po/:id/receive
  • POST /po/:id/send-order
  • POST /po/:id/send-rfq
  • POST /po/:id/submit

UI app/procurement/orders/[id]/page-client.tsx, components/procurement/po-depth-panels.tsx

modules.po.approve - 1 API route(s), 0 UI file(s)

API routes

  • POST /po/:id/approve
modules.po.delete - 1 API route(s), 0 UI file(s)

API routes

  • DELETE /po/:id

Suppliers (suppliers)

The supplier registry.

Action Permission What it allows Enforcement
View modules.suppliers.view Open the Suppliers pages and read their data. API + UI - 3 routes
Create modules.suppliers.create Create new Suppliers records. API - 2 routes
Edit modules.suppliers.edit Change existing Suppliers records. API + UI - 4 routes
Delete modules.suppliers.delete Delete Suppliers records. API - 1 routes
modules.suppliers.view - 3 API route(s), 1 UI file(s)

API routes

  • GET /procurement/suppliers - List suppliers with filters and pagination (any of: view, view)
  • GET /procurement/suppliers/template - Download supplier import template (.xlsx) (any of: view, view)
  • GET /procurement/suppliers/with-locations - Suppliers with geocoded coordinates (Fleet Map supplier layer) (any of: view, view)

UI components/layout/sidebar.tsx

modules.suppliers.create - 2 API route(s), 0 UI file(s)

API routes

  • POST /procurement/suppliers - Create a supplier (Admin only)
  • POST /procurement/suppliers/import - Import suppliers from Excel (.xlsx) (Admin only)
modules.suppliers.edit - 4 API route(s), 1 UI file(s)

API routes

  • PATCH /procurement/suppliers/:id - Update a supplier (Admin only)
  • POST /procurement/suppliers/:id/attachments - Attach a file to the supplier (Admin only)
  • POST /procurement/suppliers/:id/evaluate - Evaluate a supplier (Admin only): update status/rating/date
  • POST /procurement/suppliers/geocode-all - Geocode all suppliers without coordinates via Nominatim (Admin only, ~1s per supplier)

UI app/procurement/suppliers/page.tsx

modules.suppliers.delete - 1 API route(s), 0 UI file(s)

API routes

  • DELETE /procurement/suppliers/:id - Delete a supplier (Admin only)

Budget (budget)

Budgets and budget-vs-actual reporting.

Action Permission What it allows Enforcement
View modules.budget.view Open the Budget pages and read their data. API + UI - 9 routes
Edit modules.budget.edit Change existing Budget records. API - 2 routes
modules.budget.view - 9 API route(s), 1 UI file(s)

API routes

  • GET /financial/budget/summary - Get budget summary by department (cost centers) (any of: view, view)
  • GET /financial/budget/targets - Get budget targets for a vessel and year (any of: view, view)
  • GET /financial/budget/vs-actual - Budget vs actual PO spend for a vessel and year (any of: view, view)
  • GET /financial/cost-centers - Get all cost centers (any of: view, view)
  • GET /financial/cost-centers/:code - Get cost center by code (any of: view, view)
  • GET /financial/expense-categories - Get all expense categories (any of: view, view)
  • GET /financial/expense-categories/:code - Get expense category by code (any of: view, view)
  • GET /po-depth/budget/categories - The vessel (any of: .VIEW, view)
  • GET /po-depth/budget/overview - Budget, paid (used), committed and available per category for a vessel and year (any of: .VIEW, view)

UI components/layout/sidebar.tsx

modules.budget.edit - 2 API route(s), 0 UI file(s)

API routes

  • POST /financial/budget/targets - Upsert a budget target
  • DELETE /financial/budget/targets/:id - Delete a budget target

Cost Centers (cost-centers)

Cost centers and expense categories (categorisation only - there is no accounting).

Action Permission What it allows Enforcement
View modules.cost-centers.view Open the Cost Centers pages and read their data. API + UI - 7 routes
Create modules.cost-centers.create Create new Cost Centers records. API - 2 routes
Edit modules.cost-centers.edit Change existing Cost Centers records. API - 2 routes
Delete modules.cost-centers.delete Declared; not currently enforced. not enforced - 0 routes
modules.cost-centers.view - 7 API route(s), 1 UI file(s)

API routes

  • GET /financial/budget/summary - Get budget summary by department (cost centers) (any of: view, view)
  • GET /financial/budget/targets - Get budget targets for a vessel and year (any of: view, view)
  • GET /financial/budget/vs-actual - Budget vs actual PO spend for a vessel and year (any of: view, view)
  • GET /financial/cost-centers - Get all cost centers (any of: view, view)
  • GET /financial/cost-centers/:code - Get cost center by code (any of: view, view)
  • GET /financial/expense-categories - Get all expense categories (any of: view, view)
  • GET /financial/expense-categories/:code - Get expense category by code (any of: view, view)

UI components/layout/sidebar.tsx

modules.cost-centers.create - 2 API route(s), 0 UI file(s)

API routes

  • POST /financial/cost-centers - Create a cost center
  • POST /financial/expense-categories - Create an expense category
modules.cost-centers.edit - 2 API route(s), 0 UI file(s)

API routes

  • PATCH /financial/cost-centers/:id - Update a cost center
  • PATCH /financial/expense-categories/:id - Update an expense category

⚙️ Operations

Maintenance (maintenance)

Work orders (create, start, sign out, correct, reopen), the overdue checker, completed history, work-order spares, and the Planned Maintenance (PM) schedules and triggers.

Action Permission What it allows Enforcement
View modules.maintenance.view Open the Maintenance pages and read their data. API + UI - 39 routes
Create modules.maintenance.create Create work orders (also available through Assets: edit). API - 3 routes
Edit modules.maintenance.edit Edit work orders and PM schedules, start/release a job, link spares, trigger the overdue check, regenerate PM jobs. API + UI - 51 routes
Complete modules.maintenance.complete Sign out (complete) a work order. Ownership lock: if someone started the job, only that person can sign it out - everyone else must Release it first. An overdue job also needs an overdue reason. API + UI - 2 routes
Correct completed work modules.maintenance.correct Correct fields of an already-completed (signed) work order. API + UI - 1 routes
Lock docking specifications modules.maintenance.lock Lock docking specifications. API + UI - 2 routes
Delete modules.maintenance.delete Delete (soft-delete) a work order - it must be cancelled first - and delete PM schedules. API + UI - 4 routes
modules.maintenance.view - 39 API route(s), 10 UI file(s)

API routes

  • GET /docking/attachments/:entityId - Files attached to a project, or to an item or group
  • GET /docking/inquiries/:inquiryId/export - Download the Excel price inquiry sheet for one yard
  • GET /docking/inquiries/:inquiryId/quotes - The quote entry grid for one yard
  • GET /docking/projects - Docking / yard-stay projects for a vessel, with progress and cost roll-up
  • GET /docking/projects/:id - One project with its items (PMS state and roll-ups folded in), summary and audit trail
  • GET /docking/projects/:id/candidates - Open PMS jobs due by the end of the stay that can be pulled into the project
  • GET /docking/projects/:id/comparison - Quote comparison: one row per price detail, one column per yard, cheapest and dearest marked
  • GET /docking/projects/:id/costs - Costs for the whole project, or for one item/group and everything under it
  • GET /docking/projects/:id/events - Events logged in the project, or on one item/group and everything under it
  • GET /docking/projects/:id/inquiries - Yards asked to quote, with what each one quoted in total
  • GET /docking/projects/:id/inquiry-preflight - Items that have no price detail yet (they would be left out of the inquiry)
  • GET /docking/projects/:id/linkable-orders - Purchase orders on this vessel that can be linked to the project
  • GET /docking/projects/:id/orders - Purchase orders linked to the project, or to one item/group and everything under it
  • GET /docking/projects/:id/overview - Flat overview of all working items with orders, events and the checks to run on them
  • GET /docking/projects/:id/price-details - Price details for the whole project, or for one item/group and everything under it
  • GET /docking/projects/:id/report.pdf - The specification / job sheets as a PDF to send to the yards (part = spec, jobs or all)
  • GET /docking/projects/:id/shortlist/export - Download the job short list (open jobs and active events) as Excel
  • GET /docking/projects/:id/timeline - Schedule bars for the items, coloured by where each stands
  • GET /docking/templates - Predefined docking jobs for a vessel (optionally for one piece of equipment)
  • GET /maintenance/completed-this-month - Get count of completed jobs this month (from maintenance history)
  • GET /maintenance/fleet-efficiency - Get fleet maintenance efficiency (% of active work orders that are not overdue)
  • GET /maintenance/my-work-orders - Open work orders assigned to the current user
  • GET /maintenance/overdue - Get all overdue work orders
  • GET /maintenance/overdue/count-by-vessel - Get overdue work order count grouped by vessel
  • GET /maintenance/pm-schedules/:pmScheduleId/history - Get completed work order history for a PM schedule (any of: view, view)
  • GET /maintenance/rules - Company-wide maintenance rules the sign-out form must follow (mandatory fields, ...)
  • GET /maintenance/vessels/:vesselId/work-orders - List work orders by vessel
  • GET /maintenance/work-orders - List all work orders (optionally filtered)
  • GET /maintenance/work-orders/:id - Get a single work order by ID
  • GET /maintenance/work-orders/:id/history - Get history/audit trail for a specific work order (any of: view, view)
  • GET /maintenance/work-orders/:id/spares - List spare parts linked to a work order
  • GET /maintenance/work-orders/check-wo-number - Check if a WO number is unique
  • GET /pm/schedules - List PM schedules
  • GET /pm/triggers/counter/:counterId - List triggers driven by a given counter
  • GET /pm/triggers/schedule/:pmScheduleId - List the triggers of a maintenance plan
  • GET /pm/triggers/schedule/:pmScheduleId/evaluate - Evaluate a plan against its counters and calendar
  • GET /postponed/folders (any of: view, view)
  • GET /postponed/work-orders (any of: view, view)
  • GET /reports/maintenance-schedule.pdf - Maintenance Schedule report (upcoming PM) (any of: view, view, view)

UI app/m/assets/[id]/page.tsx, app/m/page.tsx, app/m/work-orders/[id]/page.tsx, app/m/work-orders/page.tsx, app/operations/postponed-work-orders/page.tsx, components/auth/auth-debug.tsx, components/dashboard/widget-registry.tsx, components/layout/sidebar.tsx, lib/hooks/use-notification-inbox.ts, lib/mobile/modules.ts

modules.maintenance.create - 3 API route(s), 0 UI file(s)

API routes

  • POST /maintenance/work-orders/generate-number - Generate next WO number from sequence (any of: create, edit, edit)
  • POST /pm/schedules - Create PM schedule
  • POST /pm/triggers - Add a trigger to a maintenance plan
modules.maintenance.edit - 51 API route(s), 3 UI file(s)

API routes

  • POST /docking/attachments/:entityId - Attach a file to a project, or to an item or group
  • DELETE /docking/attachments/file/:fileId - Remove an attached file
  • DELETE /docking/costs/:id - Remove a cost
  • DELETE /docking/events/:eventId - Remove an event
  • PATCH /docking/events/:eventId - Close or reopen an event
  • DELETE /docking/inquiries/:inquiryId - Remove a yard from the inquiry
  • PATCH /docking/inquiries/:inquiryId - Update an inquiry: status, currency and exchange rate, days, start date, remarks
  • PUT /docking/inquiries/:inquiryId/quotes - Save quoted prices typed into the grid
  • POST /docking/inquiries/:inquiryId/select - Choose this yard; optionally update prices from the quotation and book them as costs
  • DELETE /docking/items/:itemId - Remove an item
  • PATCH /docking/items/:itemId - Edit an item: status, progress, dates, costs, contractor and the specification (unless locked)
  • POST /docking/items/:itemId/events - Log an event (an unforeseen issue or a note) on an item
  • POST /docking/items/:itemId/price-details - Add a price detail to an item or group
  • DELETE /docking/order-links/:linkId - Remove an order link
  • DELETE /docking/price-details/:id - Remove a price detail
  • PATCH /docking/price-details/:id - Change a price detail
  • POST /docking/projects - Create a docking project
  • DELETE /docking/projects/:id - Delete a project that has not started, or a cancelled one
  • PATCH /docking/projects/:id - Edit project details
  • POST /docking/projects/:id/copy - Start a new project (or a template) as a copy of this one
  • POST /docking/projects/:id/costs - Book a cost on the project or one of its items
  • POST /docking/projects/:id/inquiries - Add yards (suppliers, or a name) to the price inquiry
  • POST /docking/projects/:id/inquiries/import - Import a returned price inquiry sheet; dryRun=true only previews
  • POST /docking/projects/:id/items - Add a group, spec or job item
  • POST /docking/projects/:id/jobs - Pull PMS work orders into the project as job items (optionally grouped by SFI main group)
  • POST /docking/projects/:id/orders - Link a purchase order to the project or one of its items
  • POST /docking/projects/:id/price-details/missing-totals - Give every item without a price detail a
  • POST /docking/projects/:id/shortlist/import - Import a returned short list; dryRun=true only previews
  • POST /docking/projects/:id/status - Request inquiries, start, complete, cancel or reopen a project
  • POST /docking/projects/:id/templates - Bring predefined jobs into a project (grouped by SFI, under a new group, or under an existing one)
  • POST /docking/templates - Create a predefined docking job
  • DELETE /docking/templates/:id - Delete a predefined docking job
  • PATCH /docking/templates/:id - Change a predefined docking job
  • POST /maintenance/overdue/check-now - Manually trigger overdue work order check (for testing)
  • PATCH /maintenance/work-orders/:id - Update a work order fields
  • PATCH /maintenance/work-orders/:id/release - Release an in-progress work order back to Open so another crew member can take it over
  • PATCH /maintenance/work-orders/:id/reopen - Reopen a cancelled work order, or (superadmin only) a completed one — back to open status
  • POST /maintenance/work-orders/:id/revoke - Revoke a completed work order (un-complete it). Superadmin only, within 30 days of completion.
  • POST /maintenance/work-orders/:id/spares - Link spare parts to a work order
  • DELETE /maintenance/work-orders/:id/spares/:spareId - Unlink spare part from work order
  • PATCH /maintenance/work-orders/:id/spares/:spareId - Update spare part quantity on work order
  • PATCH /maintenance/work-orders/:id/start - Start a work order (claims ownership for the current user)
  • POST /maintenance/work-orders/generate-number - Generate next WO number from sequence (any of: create, edit, edit)
  • PATCH /pm/schedules/:id - Update PM schedule
  • POST /pm/schedules/:id/copy-to-multiple-vessels - Copy PM schedule to multiple vessels at once
  • POST /pm/schedules/:id/copy-to-vessel - Copy PM schedule to another vessel
  • POST /pm/schedules/:id/instantiate - Instantiate work order from schedule and advance next due
  • POST /pm/schedules/:id/regenerate - Manually regenerate next work order for a PM schedule (uses today as completion date)
  • POST /pm/schedules/sync - Sync PM schedules - generate work orders for schedules without active WO
  • PATCH /pm/triggers/:id - Update a trigger
  • POST /reports/service - Create a new service report for an asset (any of: edit, edit)

UI app/docking/page.tsx, app/m/work-orders/[id]/page.tsx, components/assets/asset-detail-dialog.tsx

modules.maintenance.complete - 2 API route(s), 2 UI file(s)

API routes

  • PATCH /maintenance/work-orders/:id/complete - Complete a work order
  • POST /maintenance/work-orders/:id/sign-out - Sign out a work order with all completion details

UI app/m/work-orders/[id]/page.tsx, app/m/work-orders/[id]/signout/page.tsx

modules.maintenance.correct - 1 API route(s), 1 UI file(s)

API routes

  • PATCH /maintenance/work-orders/:id/correct - Correct the sign-out of a completed work order (within 30 days, with a reason; audited)

UI components/maintenance/work-order-detail-floating-card.tsx

modules.maintenance.lock - 2 API route(s), 1 UI file(s)

API routes

  • POST /docking/items/:itemId/lock - Lock or unlock one item specification
  • POST /docking/projects/:id/lock - Lock or unlock the whole specification (items added afterwards are variation orders)

UI app/docking/page.tsx

modules.maintenance.delete - 4 API route(s), 1 UI file(s)

API routes

  • DELETE /maintenance/work-orders/:id - Delete a work order (requires modules.maintenance.delete). Completed work orders cannot be deleted to preserve history.
  • DELETE /maintenance/work-orders/wipe-all - DELETE ALL work orders for ALL vessels — superadmin + password confirmation (DANGEROUS!). Also removes each WO\
  • DELETE /pm/schedules/:id - Delete PM schedule (and related work orders)
  • DELETE /pm/triggers/:id - Remove a trigger

UI components/assets/asset-detail-dialog.tsx

Cargo Operations (cargo)

Cargo operations: shipments, manifests, locations, loading/discharge, reconciliation, documents.

Action Permission What it allows Enforcement
View modules.cargo.view Open the Cargo Operations pages and read their data. API + UI - 10 routes
Create modules.cargo.create Create new Cargo Operations records. API - 3 routes
Edit modules.cargo.edit Change existing Cargo Operations records. API - 8 routes
Delete modules.cargo.delete Delete Cargo Operations records. API - 3 routes
modules.cargo.view - 10 API route(s), 1 UI file(s)

API routes

  • GET /cargo/locations - List cargo stowage locations with utilisation
  • GET /cargo/manifests - List cargo manifests (voyages)
  • GET /cargo/manifests/:id - Get a manifest with its consignment rows
  • GET /cargo/manifests/:id/manifest.pdf - Download the manifest as a PDF
  • GET /cargo/manifests/onboard - Manifests currently carrying cargo (onboard)
  • GET /cargo/onboard - What cargo is currently onboard (with per-location breakdown)
  • GET /cargo/reconciliation - Planned-vs-actual cargo reconciliation
  • GET /cargo/shipments - List cargo shipments
  • GET /cargo/shipments/:id - Get a cargo shipment
  • GET /cargo/shipments/:id/operations - List load/discharge operations for a shipment

UI components/layout/sidebar.tsx

modules.cargo.create - 3 API route(s), 0 UI file(s)

API routes

  • POST /cargo/locations - Create a cargo stowage location
  • POST /cargo/manifests - Create a cargo manifest
  • POST /cargo/shipments - Create a cargo shipment
modules.cargo.edit - 8 API route(s), 0 UI file(s)

API routes

  • PATCH /cargo/locations/:id - Update a cargo stowage location
  • PATCH /cargo/manifests/:id - Update a cargo manifest
  • POST /cargo/manifests/:id/discharge - Record discharge (date, port, signature) → completed
  • POST /cargo/manifests/:id/load - Record loading (date, port, signature) → onboard
  • PATCH /cargo/manifests/:id/status - Advance a manifest through its lifecycle
  • PATCH /cargo/shipments/:id - Update a cargo shipment
  • POST /cargo/shipments/:id/operations - Record a load or discharge operation
  • PATCH /cargo/shipments/:id/status - Advance a cargo shipment through its lifecycle
modules.cargo.delete - 3 API route(s), 0 UI file(s)

API routes

  • DELETE /cargo/locations/:id - Delete a cargo stowage location
  • DELETE /cargo/manifests/:id - Soft-delete a manifest and its rows
  • DELETE /cargo/shipments/:id - Soft-delete a cargo shipment

Running Hours (running-hours)

Running-hours counters and readings (the basis of hours-based PM) and AIS/telemetry estimates.

Action Permission What it allows Enforcement
View modules.running-hours.view Open the Running Hours pages and read their data. API + UI - 11 routes
Edit modules.running-hours.edit Change existing Running Hours records. API + UI - 6 routes
modules.running-hours.view - 11 API route(s), 5 UI file(s)

API routes

  • GET /running-hours - Get all running counters
  • GET /running-hours/:id - Get a specific counter by ID
  • GET /running-hours/:id/ais-estimate - Recompute and return the AIS estimate for one counter
  • GET /running-hours/:id/readings - Get reading history for a counter
  • GET /running-hours/ais/estimates - AIS-derived running-hour estimates
  • GET /running-hours/ais/stale - Counters whose official reading has gone stale
  • GET /running-hours/alerts - Get counters approaching warning/critical thresholds
  • GET /running-hours/asset/:assetId - Get all counters for a specific asset
  • GET /running-hours/overview - Counters with vessel, usage rate, next due and trend
  • GET /running-hours/summary - Get counter summary statistics
  • GET /running-hours/telemetry-sources - Get available telemetry sources for automatic counters

UI app/m/assets/[id]/page.tsx, app/m/running-hours/[id]/page.tsx, app/m/running-hours/page.tsx, components/layout/sidebar.tsx, lib/mobile/modules.ts

modules.running-hours.edit - 6 API route(s), 1 UI file(s)

API routes

  • POST /running-hours - Create a new running counter
  • DELETE /running-hours/:id - Deactivate a counter (soft delete)
  • PUT /running-hours/:id - Update a counter
  • POST /running-hours/readings - Record a new counter reading (manual update)
  • POST /running-hours/readings/bulk - Record multiple readings at once
  • POST /running-hours/sync/telemetry - Sync all automatic counters with telemetry for a vessel

UI app/m/running-hours/[id]/page.tsx

Postponed Work Orders (postponed)

Postponed work orders: folders of postponed jobs, resuming/moving them, and the rules on who may postpone what.

Action Permission What it allows Enforcement
View modules.postponed.view Open the Postponed Work Orders pages and read their data. API + UI - 2 routes
Approve modules.postponed.approve Approve/decide postponed work orders and folders. API - 6 routes
Postpone class jobs modules.postponed.postpone-class Postpone jobs flagged as Class jobs (a user without it cannot). service rule (Enforced in the postponement policy.) - 0 routes
Postpone critical jobs modules.postponed.postpone-critical Postpone jobs flagged as Critical (also requires the company rule to allow critical postponements: Settings > Maintenance rules). service rule (Enforced in the postponement policy.) - 0 routes
Postpone beyond the limit modules.postponed.postpone-unlimited Not bound by the postponement limit (otherwise a job can only be pushed a set percentage of its interval past its due date). service rule (Enforced in the postponement policy.) - 0 routes
modules.postponed.view - 2 API route(s), 1 UI file(s)

API routes

  • GET /postponed/folders (any of: view, view)
  • GET /postponed/work-orders (any of: view, view)

UI components/layout/sidebar.tsx

modules.postponed.approve - 6 API route(s), 0 UI file(s)

API routes

  • POST /postponed/folders
  • DELETE /postponed/folders/:id
  • PATCH /postponed/folders/:id
  • POST /postponed/work-orders
  • PATCH /postponed/work-orders/:id/move
  • PATCH /postponed/work-orders/:id/resume

History (history)

The Maintenance History pages (completed jobs per asset/vessel).

Action Permission What it allows Enforcement
View modules.history.view Open the History pages and read their data. API + UI - 10 routes
Export modules.history.export Declared; not currently enforced. not enforced - 0 routes
modules.history.view - 10 API route(s), 2 UI file(s)

API routes

  • GET /assets/history/all - List maintenance history across all assets (filters & paging) (any of: view, view)
  • GET /assets/history/analytics/cost-trends - Get maintenance cost trends over time (monthly aggregation) (any of: view, view)
  • GET /assets/history/analytics/equipment-breakdown - Get maintenance breakdown by equipment type (any of: view, view)
  • GET /assets/history/analytics/summary - Get maintenance summary statistics (any of: view, view)
  • GET /assets/history/analytics/top-issues - Get top problem equipment by maintenance frequency (any of: view, view)
  • GET /assets/history/export.csv - Export maintenance history as CSV (server-side, supports filters) (any of: view, view)
  • GET /assets/history/export.xlsx - Export maintenance history as XLSX (server-side, supports filters) (any of: view, view)
  • GET /maintenance/pm-schedules/:pmScheduleId/history - Get completed work order history for a PM schedule (any of: view, view)
  • GET /maintenance/work-orders/:id/history - Get history/audit trail for a specific work order (any of: view, view)
  • GET /reports/maintenance-history.pdf - Maintenance History report (completed work) (any of: view, view, view)

UI app/history/page.tsx, components/layout/sidebar.tsx

Alerts (alerts)

The alert feed (live alerts panel and the /alerts page): view, create system alerts, acknowledge/close.

Action Permission What it allows Enforcement
View modules.alerts.view Open the Alerts pages and read their data. API + UI - 3 routes
Edit modules.alerts.edit Create system alerts through the API (used by system generators). API - 1 routes
Acknowledge modules.alerts.acknowledge Acknowledge and close alerts. API + UI - 2 routes
Manage modules.alerts.manage Alerts page export and management buttons. Enforced in the UI only. UI only - 0 routes
modules.alerts.view - 3 API route(s), 2 UI file(s)

API routes

  • GET /alerts - List alerts across the fleet (dashboard Live Alerts panel + full /alerts page)
  • GET /alerts/count - Count alerts across the fleet (for the Live Alerts badge + /alerts stats)
  • GET /alerts/vessel/:vesselId - List alerts by vessel

UI app/alerts/page.tsx, components/layout/sidebar.tsx

modules.alerts.edit - 1 API route(s), 0 UI file(s)

API routes

  • POST /alerts - Create a new alert
modules.alerts.acknowledge - 2 API route(s), 1 UI file(s)

API routes

  • PATCH /alerts/:id/ack - Acknowledge an alert
  • PATCH /alerts/:id/close - Close an alert

UI app/alerts/page.tsx

modules.alerts.manage - 0 API route(s), 1 UI file(s)

UI app/alerts/page.tsx

📊 ReportsHub

Class Surveys (class-surveys)

Class surveys: surveys, findings, requirements/conditions of class, attachments, reports and KPIs.

Action Permission What it allows Enforcement
View modules.class-surveys.view Open the Class Surveys pages and read their data. API + UI - 20 routes
Create modules.class-surveys.create Create new Class Surveys records. API - 1 routes
Edit modules.class-surveys.edit Change existing Class Surveys records. API - 15 routes
Delete modules.class-surveys.delete Delete Class Surveys records. API - 1 routes
modules.class-surveys.view - 20 API route(s), 1 UI file(s)

API routes

  • GET /class-surveys
  • GET /class-surveys-v2/actions/:id
  • GET /class-surveys-v2/actions/survey/:surveyId
  • GET /class-surveys-v2/audit
  • GET /class-surveys-v2/recommendations/:id
  • GET /class-surveys-v2/recommendations/survey/:surveyId
  • GET /class-surveys/:id
  • GET /class-surveys/:id/full-report
  • GET /class-surveys/attachments/:id
  • GET /class-surveys/attachments/survey/:surveyId
  • GET /class-surveys/findings/:id
  • GET /class-surveys/findings/survey/:surveyId
  • GET /class-surveys/integrity
  • GET /class-surveys/reports/due-soon
  • GET /class-surveys/reports/fleet-matrix
  • GET /class-surveys/reports/kpis
  • GET /class-surveys/reports/overdue
  • GET /class-surveys/requirements/:id
  • GET /class-surveys/requirements/survey/:surveyId
  • GET /class-surveys/vessel/:vesselId/stats

UI components/layout/sidebar.tsx

modules.class-surveys.create - 1 API route(s), 0 UI file(s)

API routes

  • POST /class-surveys
modules.class-surveys.edit - 15 API route(s), 0 UI file(s)

API routes

  • POST /class-surveys-v2/actions
  • DELETE /class-surveys-v2/actions/:id
  • PUT /class-surveys-v2/actions/:id
  • POST /class-surveys-v2/recommendations
  • DELETE /class-surveys-v2/recommendations/:id
  • PUT /class-surveys-v2/recommendations/:id
  • PUT /class-surveys/:id
  • POST /class-surveys/attachments
  • DELETE /class-surveys/attachments/:id
  • POST /class-surveys/findings
  • DELETE /class-surveys/findings/:id
  • PUT /class-surveys/findings/:id
  • POST /class-surveys/requirements
  • DELETE /class-surveys/requirements/:id
  • PUT /class-surveys/requirements/:id
modules.class-surveys.delete - 1 API route(s), 0 UI file(s)

API routes

  • DELETE /class-surveys/:id

Voyage Reports (voyage-reports)

Voyage Reports pages. Enforced in the UI only.

Action Permission What it allows Enforcement
View modules.voyage-reports.view Open the Voyage Reports pages and read their data. not enforced - 0 routes
Create modules.voyage-reports.create Enforced in the UI only (no API routes). not enforced - 0 routes
Edit modules.voyage-reports.edit Change existing Voyage Reports records. not enforced - 0 routes
Export modules.voyage-reports.export Export Voyage Reports data. not enforced - 0 routes

Documents (documents)

The document library: documents, versions, tags, per-document permissions, approval workflow and audit trail.

Action Permission What it allows Enforcement
View modules.documents.view Open the Documents pages and read their data. API + UI - 10 routes
Upload modules.documents.upload Upload documents and new versions; edit a document's own fields. API + UI - 6 routes
Edit modules.documents.edit Manage a document: tags, per-document permissions, approval requests, mark-expired. API - 6 routes
Delete modules.documents.delete Delete a document. API - 2 routes
modules.documents.view - 10 API route(s), 1 UI file(s)

API routes

  • GET /documents
  • GET /documents/:id
  • GET /documents/:id/audit
  • GET /documents/:id/versions
  • POST /documents/approvals/:approvalId/respond
  • GET /documents/expiring
  • GET /documents/statistics
  • GET /uploads/:id - Get file metadata by ID
  • GET /uploads/list/:entityId - List files by entity ID (any of: view, view)
  • GET /uploads/stats/storage - Get storage statistics

UI components/layout/sidebar.tsx

modules.documents.upload - 6 API route(s), 3 UI file(s)

API routes

  • POST /documents
  • PUT /documents/:id
  • POST /documents/:id/upload-version
  • POST /documents/:id/versions
  • POST /documents/upload
  • POST /uploads/upload - Upload a file to local storage (any of: upload, edit)

UI app/m/qhse/page.tsx, components/qhse/incident-form.tsx, lib/api/uploads.ts

modules.documents.edit - 6 API route(s), 0 UI file(s)

API routes

  • POST /documents/:id/approve
  • POST /documents/:id/permissions
  • DELETE /documents/:id/permissions/:permissionId
  • DELETE /documents/:id/tags
  • POST /documents/:id/tags
  • POST /documents/mark-expired
modules.documents.delete - 2 API route(s), 0 UI file(s)

API routes

  • DELETE /documents/:id
  • DELETE /uploads/:id - Delete a file

Reports (reports)

The Reports pages and the server-side generated PDFs/Excel exports.

Action Permission What it allows Enforcement
View modules.reports.view Open the Reports pages and read their data. API + UI - 16 routes
Export modules.reports.export Declared; not currently enforced on its own. not enforced - 0 routes
modules.reports.view - 16 API route(s), 3 UI file(s)

API routes

  • GET /analytics/kpis/daily (any of: view, view)
  • GET /analytics/risk-scores (any of: view, view)
  • GET /reports/asset-data.pdf - Asset Data Report (dossier) for selected assets (any of: view, view)
  • GET /reports/class-compliance.pdf - Class Compliance (PMS) report (any of: view, view)
  • GET /reports/compliance.pdf - PM Compliance report (any of: view, view, view)
  • GET /reports/exports/assets - Export assets/equipment to Excel
  • GET /reports/exports/crew - Export crew assignments to Excel
  • GET /reports/exports/maintenance-history - Export maintenance history to Excel
  • GET /reports/exports/overdue-work-orders - Export overdue work orders to Excel
  • GET /reports/exports/spare-parts - Export spare parts to Excel
  • GET /reports/exports/work-orders - Export work orders to Excel
  • GET /reports/maintenance-history.pdf - Maintenance History report (completed work) (any of: view, view, view)
  • GET /reports/maintenance-schedule.pdf - Maintenance Schedule report (upcoming PM) (any of: view, view, view)
  • GET /reports/service/:id - Get a specific service report
  • GET /reports/service/:id/pdf - Generate PDF for a service report
  • GET /reports/service/asset/:assetId - Get all service reports for an asset

UI app/reports/page.tsx, components/assets/asset-detail-dialog.tsx, components/layout/sidebar.tsx

Analytics (analytics)

The Analytics pages (KPI trends, risk scores).

Action Permission What it allows Enforcement
View modules.analytics.view Open the Analytics pages and read their data. API + UI - 2 routes
modules.analytics.view - 2 API route(s), 1 UI file(s)

API routes

  • GET /analytics/kpis/daily (any of: view, view)
  • GET /analytics/risk-scores (any of: view, view)

UI components/layout/sidebar.tsx

👥 Portal

User Dashboard (user-dashboard)

Each user's personal dashboard (widget grid) and its saved layout.

Action Permission What it allows Enforcement
View modules.user-dashboard.view Open the User Dashboard pages and read their data. API + UI - 3 routes
modules.user-dashboard.view - 3 API route(s), 1 UI file(s)

API routes

  • DELETE /user-dashboard/layout - Reset the current user
  • GET /user-dashboard/layout - Get the current user
  • PUT /user-dashboard/layout - Save the current user

UI components/layout/sidebar.tsx

Messages (messages)

Messaging: channels, direct messages, read receipts.

Action Permission What it allows Enforcement
View modules.messages.view Open the Messages pages and read their data. API + UI - 11 routes
Send modules.messages.send Send messages and create channels. API - 10 routes
Delete modules.messages.delete Delete messages. API - 2 routes
modules.messages.view - 11 API route(s), 2 UI file(s)

API routes

  • GET /channels
  • GET /channels/:channelId/messages
  • GET /channels/:id
  • POST /channels/:id/read
  • GET /channels/:id/unread-count
  • GET /channels/unread-counts
  • GET /messages/:id
  • POST /messages/:id/read
  • GET /messages/:id/status
  • POST /messages/read-multiple
  • GET /messages/search

UI components/layout/sidebar.tsx, lib/hooks/use-notification-inbox.ts

modules.messages.send - 10 API route(s), 0 UI file(s)

API routes

  • POST /channels
  • POST /channels/:channelId/messages
  • PUT /channels/:id
  • POST /channels/:id/members
  • DELETE /channels/:id/members/:userId
  • PUT /channels/:id/members/:userId/role
  • PUT /messages/:id
  • POST /messages/:id/pin
  • POST /messages/:id/reactions
  • DELETE /messages/:id/reactions/:emoji
modules.messages.delete - 2 API route(s), 0 UI file(s)

API routes

  • DELETE /channels/:id
  • DELETE /messages/:id

Users (users)

User accounts: list, create, edit, activate/deactivate, assign roles, reset/set passwords, avatars.

Action Permission What it allows Enforcement
View modules.users.view Open the Users pages and read their data. API + UI - 1 routes
Create modules.users.create Create new Users records. API + UI - 1 routes
Edit modules.users.edit Change existing Users records. API - 4 routes
Delete modules.users.delete Delete Users records. API - 1 routes
modules.users.view - 1 API route(s), 3 UI file(s)

API routes

  • GET /users

UI app/users/page.tsx, components/auth/auth-debug.tsx, components/layout/sidebar.tsx

modules.users.create - 1 API route(s), 1 UI file(s)

API routes

  • POST /users

UI app/users/page.tsx

modules.users.edit - 4 API route(s), 0 UI file(s)

API routes

  • PATCH /users/:id
  • DELETE /users/:id/avatar
  • POST /users/:id/avatar
  • PATCH /users/:id/roles
modules.users.delete - 1 API route(s), 0 UI file(s)

API routes

  • DELETE /users/:id

Roles (roles)

Roles and their permission lists.

Action Permission What it allows Enforcement
View modules.roles.view Open the Roles pages and read their data. API + UI - 2 routes
Create modules.roles.create Create new Roles records. API - 1 routes
Edit modules.roles.edit Change existing Roles records. API - 2 routes
Delete modules.roles.delete Delete Roles records. API - 1 routes
modules.roles.view - 2 API route(s), 3 UI file(s)

API routes

  • GET /roles
  • GET /roles/:id

UI components/auth/access-denied.tsx, components/auth/auth-debug.tsx, components/layout/sidebar.tsx

modules.roles.create - 1 API route(s), 0 UI file(s)

API routes

  • POST /roles
modules.roles.edit - 2 API route(s), 0 UI file(s)

API routes

  • PUT /roles/:id
  • POST /roles/update-user-counts
modules.roles.delete - 1 API route(s), 0 UI file(s)

API routes

  • DELETE /roles/:id

Vessel Access (vessel-access)

Viewing your own vessel grants. NOTE: granting/changing/revoking vessel access is superadmin-only (see "Superadmin-only").

Action Permission What it allows Enforcement
View modules.vessel-access.view Open the Vessel Access pages and read their data. API + UI - 6 routes
Manage modules.vessel-access.manage Declared but not enforced: granting vessel access is superadmin-only. not enforced - 0 routes
modules.vessel-access.view - 6 API route(s), 1 UI file(s)

API routes

  • GET /vessel-access/audit - Get vessel access audit logs (SuperAdmin only)
  • GET /vessel-access/can-access/:vesselId - Check if I can access a specific vessel
  • GET /vessel-access/grants - Get all vessel access grants (SuperAdmin only)
  • GET /vessel-access/grants/:id - Get vessel access grant by ID (SuperAdmin only)
  • GET /vessel-access/my-grants - Get my vessel access grants
  • GET /vessel-access/my-vessels - Get vessel IDs I can access

UI components/layout/sidebar.tsx

Fleet Groups (fleet-groups)

Fleet groups (named sets of vessels) and their members.

Action Permission What it allows Enforcement
View modules.fleet-groups.view Open the Fleet Groups pages and read their data. API + UI - 4 routes
Create modules.fleet-groups.create Create new Fleet Groups records. API + UI - 1 routes
Edit modules.fleet-groups.edit Change existing Fleet Groups records. API + UI - 4 routes
Delete modules.fleet-groups.delete Delete Fleet Groups records. API + UI - 1 routes
modules.fleet-groups.view - 4 API route(s), 2 UI file(s)

API routes

  • GET /fleet-groups (any of: view, view)
  • GET /fleet-groups/:id (any of: view, view)
  • GET /fleet-groups/:id/members (any of: view, view)
  • GET /fleet-groups/:id/users (any of: view, view)

UI app/portal/vessel-access/page.tsx, components/layout/sidebar.tsx

modules.fleet-groups.create - 1 API route(s), 1 UI file(s)

API routes

  • POST /fleet-groups

UI app/portal/vessel-access/page.tsx

modules.fleet-groups.edit - 4 API route(s), 1 UI file(s)

API routes

  • DELETE /fleet-groups/:groupId/members/:memberId
  • PATCH /fleet-groups/:groupId/members/:memberId
  • PATCH /fleet-groups/:id
  • POST /fleet-groups/:id/members

UI app/portal/vessel-access/page.tsx

modules.fleet-groups.delete - 1 API route(s), 1 UI file(s)

API routes

  • DELETE /fleet-groups/:id

UI app/portal/vessel-access/page.tsx

Notifications (notifications)

The notification feed and delivery preferences.

Action Permission What it allows Enforcement
View modules.notifications.view Open the Notifications pages and read their data. API + UI - 5 routes
Manage modules.notifications.manage Declared but not currently enforced. not enforced - 0 routes
modules.notifications.view - 5 API route(s), 2 UI file(s)

API routes

  • GET /notifications - Get notifications for the authenticated user
  • PATCH /notifications/:id/acknowledge - Mark one of the caller\
  • PATCH /notifications/:id/read - Mark one of the caller\
  • POST /notifications/mark-all-read - Mark all of the caller\
  • GET /notifications/unread-count - Get unread notifications count for the authenticated user

UI components/layout/sidebar.tsx, lib/hooks/use-notification-inbox.ts

AIVA Assistant (aiva)

AIVA, the AI assistant: open and use the chat, list providers/models. Its API keys and provider configuration stay superadmin-only.

Action Permission What it allows Enforcement
View modules.aiva.view Open the AIVA Assistant pages and read their data. API + UI - 9 routes
modules.aiva.view - 9 API route(s), 2 UI file(s)

API routes

  • POST /ai/chat - Send a message to AI assistant (non-streaming)
  • GET /ai/conversations - Get user conversation history
  • DELETE /ai/conversations/:id - Delete a conversation
  • GET /ai/conversations/:id - Get a specific conversation
  • GET /ai/providers - List all available AI providers with models
  • GET /ai/providers/:id/models - Get models for a provider
  • GET /ai/status - Get AI assistant status (enabled/disabled)
  • GET /ai/user-preference - Get current user AI preference
  • PUT /ai/user-preference - Update current user AI preference

UI app/aiva/page.tsx, components/ai/ai-chat-widget.tsx

🛡️ QHSE

QHSE (qhse)

QHSE: incidents, inspections and findings, corrective actions, documents, risk assessments, NCRs.

Action Permission What it allows Enforcement
View modules.qhse.view Open the QHSE pages and read their data. API + UI - 36 routes
Create modules.qhse.create Create new QHSE records. API + UI - 8 routes
Edit modules.qhse.edit Change existing QHSE records. API - 17 routes
Delete modules.qhse.delete Delete QHSE records. API - 6 routes
modules.qhse.view - 36 API route(s), 3 UI file(s)

API routes

  • GET /qhse-utils/integrity - Check QHSE data integrity
  • GET /qhse/corrective-actions - Get all corrective actions for current vessel
  • GET /qhse/corrective-actions/:id - Get a single corrective action by ID
  • GET /qhse/corrective-actions/delta - Get corrective actions modified since timestamp
  • GET /qhse/corrective-actions/related/:type/:id - Get corrective actions for a related entity
  • GET /qhse/corrective-actions/stats - Get corrective action statistics
  • GET /qhse/documents - Get all documents (vessel-specific + company-wide)
  • GET /qhse/documents/:id - Get a single document by ID
  • GET /qhse/documents/company-wide - Get only company-wide documents
  • GET /qhse/documents/delta - Get documents modified since timestamp
  • GET /qhse/documents/expiring-soon - Get documents expiring in next 30 days
  • GET /qhse/documents/stats - Get document statistics
  • GET /qhse/failure-reports - List failure reports for a vessel
  • GET /qhse/failure-reports/:id - One failure report with its history
  • GET /qhse/failure-reports/stats - Open count, mean time to repair and out-of-production hours (optionally for one equipment)
  • GET /qhse/incidents - Get all incidents for current vessel
  • GET /qhse/incidents/:id - Get a single incident by ID
  • GET /qhse/incidents/delta - Get incidents modified since timestamp (for offline sync)
  • GET /qhse/incidents/stats - Get incident statistics for dashboard
  • GET /qhse/inspection-findings/:id - Get a single finding by ID
  • GET /qhse/inspection-findings/by-inspection/:inspectionId - Get all findings for an inspection
  • GET /qhse/inspection-findings/by-vessel - Get all findings for a vessel
  • GET /qhse/inspection-findings/inspection/:inspectionId/pdf - Generate PDF report for inspection findings
  • GET /qhse/inspection-findings/stats/inspection/:inspectionId - Get statistics for an inspection
  • GET /qhse/inspection-findings/stats/vessel - Get statistics for a vessel
  • GET /qhse/inspections - Get all inspections for current vessel
  • GET /qhse/inspections/:id - Get a single inspection by ID
  • GET /qhse/inspections/delta - Get inspections modified since timestamp
  • GET /qhse/inspections/stats - Get inspection statistics
  • GET /qhse/ncr - List non-conformance reports for a vessel
  • GET /qhse/ncr/:id - One NCR with its history
  • GET /qhse/ncr/stats - Open / overdue counts and a breakdown by status and type
  • GET /qhse/risk-assessments - Get all risk assessments for current vessel
  • GET /qhse/risk-assessments/:id - Get a single risk assessment by ID
  • GET /qhse/risk-assessments/delta - Get risk assessments modified since timestamp
  • GET /qhse/risk-assessments/stats - Get risk assessment statistics

UI app/m/qhse/page.tsx, components/layout/sidebar.tsx, lib/mobile/modules.ts

modules.qhse.create - 8 API route(s), 1 UI file(s)

API routes

  • POST /qhse/corrective-actions - Create a new corrective action
  • POST /qhse/documents - Create a new QHSE document
  • POST /qhse/failure-reports - Start a failure report (as a draft)
  • POST /qhse/incidents - Create a new incident report
  • POST /qhse/inspection-findings - Create a new inspection finding
  • POST /qhse/inspections - Create a new inspection/checklist
  • POST /qhse/ncr - Raise a supplier or manual NCR (the others are created from maintenance data)
  • POST /qhse/risk-assessments - Create a new risk assessment

UI app/m/qhse/page.tsx

modules.qhse.edit - 17 API route(s), 0 UI file(s)

API routes

  • PUT /qhse/corrective-actions/:id - Update a corrective action
  • POST /qhse/corrective-actions/bulk - Bulk upsert corrective actions
  • PUT /qhse/documents/:id - Update a document
  • POST /qhse/documents/bulk - Bulk upsert documents (server wins for policy docs)
  • PATCH /qhse/failure-reports/:id - Edit a failure report that is not closed
  • POST /qhse/failure-reports/:id/status - Move a failure report along its lifecycle
  • PUT /qhse/incidents/:id - Update an incident
  • POST /qhse/incidents/bulk - Bulk upsert incidents (for offline sync)
  • PATCH /qhse/inspection-findings/:id - Update a finding
  • PUT /qhse/inspections/:id - Update an inspection
  • POST /qhse/inspections/:id/signoff - Sign off an inspection
  • POST /qhse/inspections/bulk - Bulk upsert inspections
  • PATCH /qhse/ncr/:id - Edit the text of an open NCR
  • POST /qhse/ncr/:id/status - Move an NCR along its lifecycle (report / handle / close / escalate)
  • POST /qhse/ncr/scan - Run the automatic NCR scan now (it also runs every hour)
  • PUT /qhse/risk-assessments/:id - Update a risk assessment
  • POST /qhse/risk-assessments/bulk - Bulk upsert risk assessments
modules.qhse.delete - 6 API route(s), 0 UI file(s)

API routes

  • DELETE /qhse/corrective-actions/:id - Delete a corrective action
  • DELETE /qhse/documents/:id - Delete a document
  • DELETE /qhse/incidents/:id - Delete an incident
  • DELETE /qhse/inspection-findings/:id - Delete a finding
  • DELETE /qhse/inspections/:id - Delete an inspection
  • DELETE /qhse/risk-assessments/:id - Delete a risk assessment

⚡ Admin

Admin Settings (settings)

Admin Settings: company profile, email/SMTP, sequences (WO/PO/spare), maintenance & procurement rules, API configuration, diagnostics, database/replication/tracking admin pages.

Action Permission What it allows Enforcement
View modules.settings.view Open the Admin Settings pages and read system diagnostics (health details, licence details, replication/queue status, company profile). API + UI - 26 routes
Edit modules.settings.edit Change settings and operate admin tools: SMTP/email test and sending, sequences, API/tracking/replication/updates configuration, grid views, demo data, database admin, error logs. API + UI - 51 routes
modules.settings.view - 26 API route(s), 2 UI file(s)

API routes

  • GET /db/connection-status - Get current database connection status
  • GET /health/details
  • GET /license/details - Full license details (customer, expiry, last verification)
  • GET /queue/metrics
  • GET /replication/authority - Get all authority rules (bidirectional ownership model)
  • GET /replication/authority/:entityType - Get authority matrix for an entity type
  • GET /replication/health/vessels/:vesselId - Get replication health for a vessel
  • GET /settings/company-profile - Get the company profile used on document headers (manifests, reports)
  • GET /settings/grid-views - List grid views for a scope. If ownerUserId provided, returns user views and shared views
  • GET /settings/layout-edit - Get whether layout edit mode is enabled globally
  • GET /settings/maintenance-rules - Get the company-wide maintenance rules (mandatory sign-out fields, ...)
  • GET /settings/page-layout - Get saved page layout for a scope (e.g., /codes)
  • GET /settings/page-layouts - List all saved page layouts
  • GET /settings/po-sequence - Get Purchase Order number sequence settings (optionally per-vessel)
  • GET /settings/procurement-rules - Get the company-wide procurement rules (approval separation, overspend control, ...)
  • GET /settings/spare-sequence - Get Spare Part number sequence settings (optionally per-vessel)
  • GET /settings/spare-sequence/all-vessels - Get all per-vessel Spare Part sequences
  • GET /settings/spare-sequence/check-available/:spareNumber - Check if a spare part number is available (not already used)
  • GET /settings/spare-sequence/check/:vesselId - Check if a vessel has Spare Part sequence configured
  • GET /settings/spare-sequence/usage-history - Get usage history of spare part numbers
  • GET /settings/spare-sequence/vessels-status - Get all vessels with their Spare Part sequence configuration status
  • GET /settings/voyage-sequence - Get the voyage (cargo manifest) numbering sequence
  • GET /settings/wo-sequence - Get Work Order number sequence settings (optionally per-vessel)
  • GET /settings/wo-sequence/all-vessels - Get all per-vessel WO sequences
  • GET /settings/wo-sequence/check/:vesselId - Check if a vessel has WO sequence configured
  • GET /settings/wo-sequence/vessels-status - Get all vessels with their WO sequence configuration status

UI app/admin/settings/page.tsx, components/layout/sidebar.tsx

modules.settings.edit - 51 API route(s), 4 UI file(s)

API routes

  • POST /api/sync/push
  • GET /db/asset-value-check
  • POST /email/alerts/send
  • GET /email/alerts/settings
  • PUT /email/alerts/settings
  • GET /email/alerts/settings/:alertType
  • POST /email/alerts/settings/:alertType/toggle
  • GET /email/alerts/statistics
  • GET /email/alerts/templates
  • POST /email/alerts/templates
  • DELETE /email/alerts/templates/:id
  • GET /email/alerts/templates/:id
  • PUT /email/alerts/templates/:id
  • POST /email/alerts/templates/:id/clone
  • POST /email/alerts/test/:alertType
  • POST /email/cache/clear
  • GET /email/configs
  • POST /email/configs
  • DELETE /email/configs/:id
  • GET /email/configs/:id
  • PUT /email/configs/:id
  • GET /email/configs/default/get
  • POST /email/send
  • POST /email/test
  • GET /settings/api-config - Get API configuration (MyShipTracking, etc.). Keys are never returned - see the *Set flags.
  • PATCH /settings/company-profile - Update the company profile (Admin only)
  • PATCH /settings/company-theme - Save company custom theme (Admin only)
  • POST /settings/compliance/evaluate-all - Run compliance evaluation for all vessels
  • GET /settings/email - Get email settings (SMTP host/user/recipients). Password is never returned - see smtpPassSet.
  • PATCH /settings/email - Update email settings. Omit/blank/masked smtpPass leaves it unchanged; null clears it.
  • POST /settings/email/test - Send test email to verify SMTP configuration
  • PATCH /settings/grid-views - Upsert a grid view (columns with widths/visibility). Use isShared to allow others to use it.
  • POST /settings/grid-views/delete - Delete a grid view by name/scope/owner (only owner or admin should do this – add auth if needed)
  • PATCH /settings/maintenance-rules - Update the company-wide maintenance rules (any subset)
  • PATCH /settings/po-sequence - Update Purchase Order number sequence settings (global or per-vessel via body.vesselId)
  • PATCH /settings/procurement-rules - Update the company-wide procurement rules (any subset)
  • POST /settings/seed/ports - Seed demo world ports (pass ?dryRun=true to preview without writing)
  • PATCH /settings/spare-sequence - Update Spare Part number sequence settings (global or per-vessel via body.vesselId)
  • POST /settings/spare-sequence/init-defaults - Initialize default Spare Part sequences for all vessels that do not have one configured
  • POST /settings/spare-sequence/reset - Reset Spare Part sequence to specified value (global or per-vessel)
  • POST /settings/spare-sequence/reset-all - Reset ALL Spare Part sequences to 1
  • PATCH /settings/voyage-sequence - Update the voyage numbering sequence
  • PATCH /settings/wo-sequence - Update Work Order number sequence settings (global or per-vessel via body.vesselId)
  • POST /settings/wo-sequence/create-default/:vesselId - Create default WO sequence for a vessel (WO-0001 format)
  • POST /settings/wo-sequence/reset - Reset WO sequence to specified value (global or per-vessel)
  • POST /settings/wo-sequence/reset-all - Reset all WO sequences (global + all vessels) to 1
  • POST /telemetry/simulate/:vesselId - Start telemetry simulation for a vessel
  • POST /telemetry/simulate/:vesselId/stop - Stop telemetry simulation for a vessel
  • POST /tracking/refresh - Refresh AISstream subscription (MMSI list)
  • POST /voyages/ports/registry/apply-bundled - Install the port registry bundled with this release (adds/updates, keeps user edits)
  • POST /voyages/ports/registry/update-online - Download the latest UN/LOCODE + World Port Index and apply them (needs internet)

UI app/admin/settings/page.tsx, app/settings/page.tsx, components/settings/maintenance-rules-panel.tsx, components/settings/procurement-rules-panel.tsx

Audit Log (audit-log)

The unified Audit Log (who changed what, with before/after).

Action Permission What it allows Enforcement
View modules.audit-log.view Open the Audit Log pages and read their data. API + UI - 4 routes
Export modules.audit-log.export Export the audit log. Declared; the export is gated in the UI only. not enforced - 0 routes
modules.audit-log.view - 4 API route(s), 1 UI file(s)

API routes

  • GET /audit/entity-history - Get audit history for a specific entity
  • GET /audit/entity-types - Get distinct entity types from audit log
  • GET /audit/logs - Get audit logs with filtering
  • GET /audit/summary - Get audit summary statistics

UI components/layout/sidebar.tsx

Developer Console (dev_console)

The read-only database console (queries, schema, health). A SELECT can read any table, so treat as a trusted grant. Write/maintenance functions in the console are superadmin-only.

Action Permission What it allows Enforcement
View modules.dev_console.view Open the Developer Console pages and read their data. API + UI - 4 routes
modules.dev_console.view - 4 API route(s), 1 UI file(s)

API routes

  • GET /dev-console/health - Database health: size, biggest tables, dead tuples, active queries, caches, WAL slots
  • POST /dev-console/query - Run a read-only SQL query (SELECT/WITH/EXPLAIN/SHOW). Enforced READ ONLY + timeout + row cap.
  • GET /dev-console/schema - List all tables with row estimates and sizes
  • GET /dev-console/schema/:table - Describe one table: columns, indexes, foreign keys

UI app/admin/settings/page.tsx

Debug Terminal (debug_terminal)

Access live system logs. Standalone permission (not tied to a module's view/edit).

Enforcement: API; UI: -

5. Rules enforced in code

These are behaviours attached to a permission that you cannot see from the route list.

Work orders (Maintenance) - Ownership lock: starting a job records who started it. Only that person can sign it out (maintenance.complete); another user must Release it first, then start it themselves. Jobs that were never started are not locked. - Sign-out identity: the "signed by" name always comes from the logged-in user, never from the request. - Overdue: signing out an overdue job requires an overdue reason, which is written to the work-order history. - Completed is locked: a completed work order cannot be moved back by a status update. Correcting it needs maintenance.correct; reopening or revoking a completed job is superadmin only (reopening a cancelled job needs maintenance.edit). - Status changes: a work order can only follow the allowed state machine (draft → open → in progress → completed; cancelled/postponed branches). "Completed" is only reachable through sign-out. - Permit to work: a job flagged "permit required" cannot be started until its permit number is entered on the work order. - Deleting: a work order must be cancelled before it can be deleted; deletion is a soft delete.

Assets - Delete vs scrap: an asset with any work order or maintenance history cannot be deleted - it can only be scrapped (needs a reason, at least 5 characters). Scrapping and restoring are written to the asset change log. A scrapped asset cannot receive new work orders. An asset that still has sub-components cannot be deleted. - Running hours cannot be lowered or set negative unless the change is explicitly confirmed (a replaced hour-meter); every change is logged. - SFI codes are unique per vessel; the parent is derived from the code only when the code itself changes.

Purchase orders - Each order needs an approval level decided by its value against the approval thresholds (level 1, 2 or 3). A user can approve up to the level they hold: po.approve = level 1, po.approve-2 = level 2, po.approve-3 = level 3 (holding a higher level covers the lower ones). The superadmin approves at any level. - po.approve-overspend is additionally required to approve an order that takes a budget category beyond the tolerated overspend (Settings > Procurement rules). - Segregation of duties and "had inquiries" rules apply per the procurement rules in Settings.

Postponed work orders - Postponing a Class job needs postponed.postpone-class; a Critical job needs postponed.postpone-critical and the company rule must allow postponing critical jobs (Settings > Maintenance rules). - A limited right can only push a job a set percentage of its interval past its due date; postponed.postpone-unlimited is not bound by that limit. The superadmin is never restricted.

Crew - Hours of rest - crew.rest-own lets a crew member work with their own hours of rest without being able to see the rest of the crew; rest-edit fills in anyone's; rest-approve signs records off.

Documents - A document belongs to a vessel through what it is attached to (the vessel, a piece of equipment, a work order, a crew member). Users see company-wide documents plus those of their vessels. Approving a document can only be done by the approver named on the request.

Vessel access and fleet groups - A grant (or fleet-group membership) means access to the vessel; denied blocks it, overriding a fleet group. Grants can expire. - Record ids in a request (path, body, even nested or in the query string of a write) are traced to the vessel that owns the record, so another vessel's record is refused even when the request never names a vessel. A record that belongs to two vessels (a transfer, a crew member's current/planned vessel) is allowed if either is accessible.

Replication / relay endpoints between vessel and office instances are authenticated with a shared node secret, not with user permissions.

6. Superadmin-only

These routes check for the reserved superadmin role - no ticked permission grants them. They are the highest-risk functions and deliberately cannot be delegated.

168 routes in 21 areas:

/ai - 8 route(s)
  • DELETE /ai/api-key - Clear AI API key (superadmin only)
  • GET /ai/provider-configs - Get all provider configs (admin)
  • POST /ai/provider-configs - Create provider config (admin)
  • DELETE /ai/provider-configs/:provider - Delete provider config (superadmin)
  • PUT /ai/provider-configs/:provider - Update provider config (admin)
  • GET /ai/settings - Get AI settings (admin only)
  • PUT /ai/settings - Update AI settings (admin only)
  • POST /ai/test-connection - Test AI API connection
/auth - 4 route(s)
  • DELETE /auth/sessions
  • GET /auth/sessions
  • GET /auth/sessions/:id
  • DELETE /auth/sessions/older-than/:days
/db - 26 route(s)
  • POST /db/apply - Apply new database connection (hot reload - superadmin only)
  • GET /db/check-schema - Check if vessels table has all required columns (superadmin only)
  • GET /db/check-vessels - Check vessel count in current database (superadmin only)
  • POST /db/clone - Clone database (PostgreSQL, superadmin only)
  • POST /db/clone-database - [REMOVED] Never copied data on Postgres — use /db/clone (superadmin only)
  • GET /db/config - Get current DB config (superadmin only)
  • POST /db/configure - Configure database connection (superadmin only)
  • POST /db/create-postgres-database - [REMOVED] Use migrations + manual CREATE DATABASE instead (superadmin only)
  • POST /db/create-tables - Create missing tables (superadmin only)
  • POST /db/execute-sql - Execute raw SQL (superadmin only — DANGEROUS, disabled in production)
  • POST /db/get-schema-info - Get schema information from current database (superadmin only)
  • GET /db/info - Get database server information (superadmin only)
  • POST /db/list-databases - List all databases on current server (superadmin only)
  • GET /db/list-databases-and-connection - List all databases and current connection (superadmin only)
  • GET /db/list-databases-public - List all databases on current server (superadmin only)
  • POST /db/run-migration - [REMOVED] Use
  • POST /db/save-connection - Save database connection after deployment (superadmin only)
  • DELETE /db/saved-connection/:name
  • GET /db/saved-connections
  • POST /db/seed-minimal
  • POST /db/seed-superadmin - [REMOVED] Was SQL Server-only T-SQL, never worked against Postgres (superadmin only)
  • POST /db/sync-schema - [REMOVED] Use TypeORM migrations instead (superadmin only)
  • GET /db/system-folder
  • POST /db/system-folder
  • POST /db/test - Test database connection (superadmin only)
  • POST /db/use-connection
/demo-data - 1 route(s)
  • GET /demo-data/status - Demo dataset status and row counts (superadmin only)
/dev-console - 2 route(s)
  • POST /dev-console/execute - Execute arbitrary write/DDL SQL (superadmin only — DANGEROUS)
  • POST /dev-console/maintenance - Run a curated maintenance action (superadmin only)
/diagnostics - 3 route(s)
  • GET /diagnostics/license - Get real license status (admin only)
  • GET /diagnostics/redis - Get Redis connection and statistics (admin only)
  • GET /diagnostics/storage - Get file storage statistics (admin only)
/license - 1 route(s)
  • POST /license/activate - Activate a license key (superadmin only)
/logs - 7 route(s)
  • GET /logs - Get logs for a specific date
  • DELETE /logs/clear - Clear all log files (superadmin only)
  • DELETE /logs/file/:date - Delete a specific log file by date (superadmin only)
  • GET /logs/files - Get list of available log files
  • DELETE /logs/old/:days - Delete log files older than X days (superadmin only)
  • GET /logs/recent - Get recent logs from today
  • GET /logs/stats - Get log statistics
/public - 6 route(s)
  • GET /public/roles
  • POST /public/roles
  • DELETE /public/roles/:id
  • GET /public/roles/:id
  • PUT /public/roles/:id
  • POST /public/roles/update-user-counts
/qhse-utils - 2 route(s)
  • POST /qhse-utils/clear - Clear all QHSE data for a vessel — superadmin + password confirmation (hard delete)
  • POST /qhse-utils/seed - Seed sample QHSE data for a vessel (dev/admin only)
/queue - 4 route(s)
  • GET /queue/email/jobs
  • GET /queue/email/status
  • POST /queue/email/test
  • GET /queue/status
/replication - 32 route(s)
  • GET /replication/changes - Get recent change log entries
  • POST /replication/changes/distribute - Distribute pending changes to vessel queues
  • POST /replication/distribute - Manually trigger distribution
  • GET /replication/export/:vesselId - Export a vessel for offline installation (SuperAdmin only)
  • GET /replication/export/preview/:vesselId - Get export preview for a vessel (SuperAdmin only)
  • GET /replication/health - Get replication health summary
  • GET /replication/health/nodes - Get health metrics for all nodes
  • GET /replication/health/nodes/:nodeId - Get health metrics for a specific node
  • POST /replication/import - Import a vessel export file (SuperAdmin only)
  • POST /replication/import/validate - Validate an import file without applying (SuperAdmin only)
  • POST /replication/inbound/process - Process pending inbound queue items
  • GET /replication/nodes - Get all registered vessel nodes
  • POST /replication/nodes/:nodeId/activate - Process vessel activation acknowledgment
  • PUT /replication/nodes/:nodeId/enable-sync - Enable sync for a vessel (any status except decommissioned)
  • POST /replication/nodes/:nodeId/package - Create incremental package for a vessel
  • GET /replication/nodes/:nodeId/packages - Get pending packages for a vessel
  • POST /replication/nodes/:nodeId/provision - Generate provisioning package for a vessel
  • GET /replication/nodes/:nodeId/provision/download - Download provisioning package as JSON file
  • PUT /replication/nodes/:nodeId/suspend - Suspend sync for a vessel
  • POST /replication/nodes/register - Register a vessel for replication
  • GET /replication/outbound - Get outbound queue items per vessel
  • PUT /replication/packages/:packageId/sent - Mark a package as sent
  • GET /replication/packages/stats - Get package statistics
  • POST /replication/pairing/apply - Apply office
  • GET /replication/pairing/status - This install
  • GET /replication/queue - Get all change log items
  • PUT /replication/relay/mode - Choose
  • POST /replication/relay/register - Manually (re)trigger relay registration now
  • GET /replication/relay/status - Get this install\
  • GET /replication/settings - Get replication settings
  • PUT /replication/settings/interval - Set distribution interval in seconds
  • GET /replication/status - Get overall replication status
/seeds - 22 route(s)
  • POST /seeds/alerts - Seed sample alerts - to specific vessel or distributed across all
  • POST /seeds/backfill-due-date - Backfill dueDate from scheduledDate where missing
  • POST /seeds/certificate-types - Seed real-world maritime certificate types (STCW, SOLAS, MARPOL, ISM Code)
  • POST /seeds/cleanup-orphans - Delete dangling Core PMS records for a vessel (spares preserved) — superadmin + password
  • POST /seeds/cleanup-spare-locations-orphans - Delete spare_locations with vessel_id not in vessels (orphan folders) — superadmin + password
  • POST /seeds/codes-defaults - Ensure codes schema and seed default types/values (idempotent)
  • POST /seeds/demo-certificates - Seed demo vessel certificates for a vessel (uses existing certificate types)
  • POST /seeds/demo-certificates/clear - Remove all vessel certificates for a vessel + dependent records — superadmin + password
  • POST /seeds/drop-legacy-workorders - Drop legacy work_orders table if it exists
  • POST /seeds/ensure-all-fks-indexes - Clean orphans and add DB-level FKs + indexes (idempotent, PostgreSQL)
  • POST /seeds/ensure-asset-wo-schema - Ensure asset_work_orders table has all required columns (idempotent)
  • POST /seeds/ensure-catalogs - Ensure catalogs table (catalog_items), indexes, and FK to suppliers (idempotent, PostgreSQL)
  • POST /seeds/ensure-spare-locations-fks - Clean invalid parentId in spare_locations and add DB-level FKs (idempotent)
  • POST /seeds/ensure-superadmin - Ensure SuperAdmin user exists (idempotent, superadmin only). First-boot bootstrap happens automatically at startup.
  • POST /seeds/fix-catalog-imports-timestamp - Fix catalog_imports.importedAt default value for PostgreSQL
  • POST /seeds/import-workorders - Import work orders into asset_work_orders with valid assetId/vesselId mapping
  • POST /seeds/migrate-legacy-workorders - Migrate legacy work_orders into asset_work_orders and drop legacy table
  • POST /seeds/random-workorders - Seed random work orders - to specific vessel or distributed across all
  • GET /seeds/random-workorders/stream - Seed random work orders with SSE progress streaming (admin / superadmin only)
  • POST /seeds/stock-prices - Add random prices to all stock items that have no price
  • POST /seeds/workorders - Seed sample work orders for all active vessels
  • POST /seeds/world-ports - Seed 150+ major world ports with UN/LOCODE, coordinates, timezone, and characteristics
/server - 3 route(s)
  • GET /server/active-users - Currently connected users (superadmin)
  • POST /server/backup - Trigger database backup (superadmin)
  • GET /server/sync-status - Cloud sync health status (superadmin)
/settings - 6 route(s)
  • PATCH /settings/api-config - Update API configuration (SuperAdmin only). Omit/blank/masked keys leave them unchanged; null clears.
  • PATCH /settings/base-currency - Set the system base currency (SuperAdmin only)
  • POST /settings/layout-edit - Set layout edit mode globally (true/false)
  • POST /settings/page-layout - Save page layout for a scope
  • POST /settings/seed/compliance-audit-voyages - Seed demo data for compliance, audit logs, and voyages
  • POST /settings/system/mark-initialized - Mark system as initialized (superadmin only)
/support - 11 route(s)
  • GET /support/admin/announcements - Get all announcements (admin only)
  • POST /support/admin/announcements - Create announcement (admin only)
  • DELETE /support/admin/announcements/:id - Delete announcement (admin only)
  • GET /support/admin/announcements/:id - Get announcement by ID (admin only)
  • PUT /support/admin/announcements/:id - Update announcement (admin only)
  • GET /support/admin/changelog - Get all changelog entries (admin only)
  • POST /support/admin/changelog - Create changelog entry (admin only)
  • DELETE /support/admin/changelog/:id - Delete changelog entry (admin only)
  • GET /support/admin/changelog/:id - Get changelog entry by ID (admin only)
  • PUT /support/admin/changelog/:id - Update changelog entry (admin only)
  • POST /support/admin/changelog/seed - Seed changelog from hardcoded entries (admin only)
/sync-admin - 14 route(s)
  • GET /sync-admin/alerts - Get sync alerts (failed imports, exports, silent vessels)
  • PUT /sync-admin/alerts/:id/acknowledge - Acknowledge an alert
  • PUT /sync-admin/alerts/:id/resolve - Resolve an alert
  • GET /sync-admin/config - Get sync configuration (folders, encryption, schedule)
  • PUT /sync-admin/config - Update sync configuration (superadmin only)
  • GET /sync-admin/conflicts - List recent conflict resolutions for audit
  • POST /sync-admin/import/force - Force vessel-side import scan now
  • GET /sync-admin/overview - Aggregated sync stats for dashboard
  • GET /sync-admin/vessels - List all vessels with sync status (registered and unregistered)
  • POST /sync-admin/vessels/:nodeId/force-send - Force send all pending packages to a vessel now
  • GET /sync-admin/vessels/:nodeId/secret - Reveal node decrypt key (superadmin only, for debugging)
  • PUT /sync-admin/vessels/:nodeId/sync-enabled - Enable or disable sync for a vessel
  • PUT /sync-admin/vessels/:nodeId/transport - Update vessel transport config (email, API URL)
  • POST /sync-admin/vessels/:vesselId/activate - Register and activate sync for a vessel (one-click setup)
/system - 6 route(s)
  • GET /system/error-logs
  • GET /system/performance
  • POST /system/update/check - Force an immediate release check (bypasses 6h cache)
  • GET /system/update/history - Update attempt history (newest first)
  • GET /system/update/status - Current version vs latest available release
  • POST /system/update/trigger - Trigger an update via the Update Agent (superadmin only)
/users - 2 route(s)
  • PATCH /users/:id/password
  • POST /users/:id/reset-password
/vessel-access - 3 route(s)
  • POST /vessel-access/grant - Grant vessel access to a user (SuperAdmin only)
  • DELETE /vessel-access/grants/:id - Revoke vessel access (SuperAdmin only)
  • PATCH /vessel-access/grants/:id - Update vessel access grant (SuperAdmin only)
/weather - 5 route(s)
  • DELETE /weather/cleanup - Clean up old cache entries (older than 24 hours)
  • GET /weather/config - Get weather API configuration (Admin only)
  • PATCH /weather/local/config - Update local weather API configuration (Admin only)
  • PATCH /weather/windy/config - Update Windy API configuration (Admin only)
  • POST /weather/windy/test - Test Windy API connection (Admin only)

Notably superadmin-only: granting, changing and revoking vessel access, license activation, AI provider keys/configuration, demo-data wipes, replication/provisioning, update agent, reopening/revoking completed work orders, and the console's write/maintenance functions.

7. Open and public routes

Routes with no permission. Nothing else in the system is reachable without one. A build test (route-protection.spec.ts) fails if a new route is added without a permission unless it is approved in that list.

Signed-in users only (no permission) - self-service by necessity

Public (no login)

Public routes are login/registration/reset flows, health and version probes, pre-login branding, replication endpoints that check a node secret, the lock-screen licence activation (only works while locked, rate-limited), the update-agent callback (shared secret), and file/photo URLs used by <img>/<iframe> (accepted trade-off - the URLs are guessable and permanent; signed URLs are recommended).

8. Known gaps

Permissions that exist in the Roles screen but are not (fully) enforced. Ticking them currently has little or no effect:

Permission Status Note
modules.inventory.edit not enforced Declared but not enforced anywhere.
modules.stock.view UI only Open the Stock pages and read their data.
modules.stock.adjust not enforced Declared; stock changes are enforced through Spare Parts: adjust.
modules.alarm-system.acknowledge not enforced Acknowledge an alarm. Declared but not currently enforced.
modules.medic-items.view UI only Open the Medical Items pages and read their data.
modules.cost-centers.delete not enforced Declared; not currently enforced.
modules.history.export not enforced Declared; not currently enforced.
modules.alerts.manage UI only Alerts page export and management buttons. Enforced in the UI only.
modules.voyage-reports.view not enforced Open the Voyage Reports pages and read their data.
modules.voyage-reports.create not enforced Enforced in the UI only (no API routes).
modules.voyage-reports.edit not enforced Change existing Voyage Reports records.
modules.voyage-reports.export not enforced Export Voyage Reports data.
modules.reports.export not enforced Declared; not currently enforced on its own.
modules.vessel-access.manage not enforced Declared but not enforced: granting vessel access is superadmin-only.
modules.notifications.manage not enforced Declared but not currently enforced.
modules.audit-log.export not enforced Export the audit log. Declared; the export is gated in the UI only.

Also: documents of type port call or trip have no vessel link and are treated as company-wide; company-wide reference tables (suppliers, code lists, templates) are not vessel-scoped by design; the docs for each permission are regenerated from the code, so a gap closed later disappears from this table when regenerated.