Skip to main content

Inventory permissions

Category: Inventory Management — 10 modules, 52 permissions


1. The full list​

Unit of Measure — org_inv_uom (7)​

View unit of measures · .menu · .create · .edit · .delete · .deactivate · .createwithai

Raw Materials — org_inventory_rawmaterial (6)​

View Raw Materials · .menu · .create · .edit · .delete · .createwithai

Product Category — org_inv_prod_cat (6)​

View Product Category · .menu · .create · .edit · .delete · .createwithai

Product Attributes — org_inv_attributes (6)​

View Product atributes · .menu · .create · .edit · .delete · .createwithai

Orbit Products — org_inv_products (7)​

View Products · .menu · .create · .edit · .delete · .createwithai · .import

Procurement & Inbound — org_inv_procurement (4)​

View Inventory Procurements · .menu · .create · .approve

Production & Manufacturing — org_inv_production (6)​

View Production and Manufacturing Trends · .menu · .create · .edit · .complete · .cancel

Sales & Outbound — org_inv_sales (3)​

View Inventory sales · .menu · .create

Maintenance & Quality Control — org_inv_maintainence (4)​

View Maintenance & Quality Control · .menu · .adjust · .waste

Inventory Audit View — org_inv_ledger (3)​

View Inventory Ledger · .menu · .export


2. Two traps in the naming​

Attributes use the prodcat.attribute.* prefix

The module is org_inv_attributes, but there is no org.inventory.attributes.* permission. Every one is under org.inventory.prodcat.attribute.*.

The permission to grant is View Product atributes.

The Maintenance module code is misspelled

org_inv_maintainence — with the typo. Its permissions are spelled correctly (org.inventory.maintenance.*). Only the module code carries it, and that is what a package_module_map row or an organization_modules row must match.


3. Four permissions that do nothing​

These can be granted. No route and no component reads them.

PermissionReality
Approve procurementThere is no approval step in Procurement at all
Export inventory ledgerThe Export button has no handler and there is no endpoint
Mark wastage of inventoryWastage is gated by .adjust — you cannot separate the two
Delete Product attributesDELETE /attributes is gated on .edit, so .delete is unreachable
Granting these creates a false sense of control

A role designed as "can receive stock but not approve it" is indistinguishable from one that can do both, because approval does not exist. Likewise "can count but not write off" is not achievable.


4. Where the UI checks, and where it does not​

Three different postures across one category:

ScreensIdiomChecks
ProductsusePermission()5
UoM, Categories, Attributes, Raw MaterialshasPermission() from the auth store16
Procurement, Production, Sales, Maintenance, Ledgernone0
The five operations screens hide nothing

Add Receipt Batch, New Production Order, Complete, Cancel, New Sale and New Entry all render for anyone holding the module's .view permission.

The API enforces the real permission, so a user without .create fills in an entire form and meets a failure on Save. That is the opposite of the product's own standard, which is to surface a missing prerequisite before the work rather than after it.

Until this is fixed, a .view-only role on those screens is a poor experience, not a safe one.

Two different idioms — usePermission() and hasPermission() — do the same job. Copy whichever the surrounding file uses.


5. Permissions that gate more than they look like​

PermissionAlso required for
products.editOpening a product at all. There is no read-only product page
products.createReaching /products/new
maintenance.adjustWastage as well as adjustments
Edit Product AttributesDeleting an attribute
uom.createBoth Seed defaults and Discover
products.importThe Import button — separate from products.create

6. Building roles​

Catalogue author​

Everything under products, categories, attributes, units and raw materials, including .createwithai if AI is entitled. No operations permissions.

Stock clerk​

procurement.view + .create, production.view + .create + .complete, sales.view + .create, maintenance.view + .adjust, ledger.view.

Note this role can also write stock off — .waste is not separable.

Auditor​

ledger.view + ledger.menu, plus .view on whatever else you want them to see.

An auditor cannot open a product

products.view grants the catalogue list only. To let an auditor inspect a product's fields you must grant products.edit, which also lets them change it. There is no read-only middle ground.

ledger.view exposes customer names and phone numbers

The ledger prints the undecoded [CUST:…] [PH:…] tags from direct sales. Anyone with ledger.view can read them. Treat it as a permission over personal data, not just over quantities. See The inventory ledger.


7. Module enablement — before permissions matter​

A permission only takes effect if the module is enabled for the organisation. Two independent paths grant that:

PathTable
Direct org enablementorganization_modules
Via a purchased packagepackage_module_map
A module with no package_module_map row denies everyone

Including the org owner. If nobody can reach an Inventory screen despite holding the permission, the module-to-package mapping is the first thing to check, not the role.


8. Troubleshooting​

SymptomCause
Attribute permissions do nothingWrong prefix — use prodcat.attribute.*
Nobody can open a module, including the ownerMissing package_module_map row
A role can see a button but Save failsThe operations screens do not gate their UI
.approve / .export / .waste appear to have no effectThey are enforced nowhere
An auditor cannot open a productproducts.view is list-only
A screen is missing from the menuThe .menu permission is separate from .view