Skip to content

TJK: Custom roles#7

Open
MatiasArriola wants to merge 10 commits into
release/est/tjk/0.9.7from
feat/custom-roles-tjk-0.9.7
Open

TJK: Custom roles#7
MatiasArriola wants to merge 10 commits into
release/est/tjk/0.9.7from
feat/custom-roles-tjk-0.9.7

Conversation

@MatiasArriola
Copy link
Copy Markdown

@MatiasArriola MatiasArriola commented May 22, 2026

📌 References

📝 Implementation

  • Added custom role definitions and migrations for:
    • Facility Storekeeper
    • Regional Warehouse User
    • RPC Superuser
    • Reporting User
  • Added centralized custom role policy enforcement through CustomRolePolicyService.
  • Applied custom role checks to backend route access, API access, menu visibility, dashboard behavior, and user/session permission payloads.
  • Updated frontend permission helpers and UI controls to hide or disable restricted actions for custom roles.
  • Added role-aware restrictions for inbound, outbound, purchasing, products, stocklists, and reporting flows.
  • Added backend and frontend tests covering custom role policy behavior and UI permission helpers.
  • Added OpenSpec documentation for the custom role access model and policy isolation.

✨ Description of Change

Description:

This PR adds the TJK custom role access model on top of the existing OpenBoxes role system. The change introduces four custom roles and enforces their access across backend controllers/APIs, menu configuration, session permissions, and frontend action visibility.

The main goal is to support location-scoped operational roles with more specific access than the existing core roles, while preventing restricted actions through both UI controls and direct URL/API access.

Permissions matrix:

Role Dashboard Inventory Purchasing Inbound Outbound Reporting Products Stocklists Comments
Facility Storekeeper Read Read/Write No Read/Write No Read Read No No access to Create Inbound Movement
Regional Warehouse User Read Read/Write No Read/Write Read/Write Read Read Read/Write No access to Create Inbound Movement
RPC Superuser Read Read/Write Yes Read/Write Read/Write Read Read/Write Read/Write
Reporting User Read Read No Read Read Read Read Read

Key behavior:

  • Facility Storekeeper can manage inventory and inbound workflows, but cannot access purchasing, outbound, stocklists, or create new inbound movements.
  • Regional Warehouse User can manage inventory, inbound, outbound, and stocklists, but cannot access purchasing or create new inbound movements.
  • RPC Superuser can manage purchasing, inventory, inbound, outbound, products, and stocklists, with restricted access only to unsafe admin/dashboard actions.
  • Reporting User has read-only access across supported modules and is blocked from create/update/delete/import workflow actions.
  • Higher core roles continue to take precedence over the custom role policies.

🔥 Notes to the tester

Please validate each custom role at a location where the role is assigned:

  • Confirm the menu only shows allowed modules/actions for each role.
  • Confirm restricted direct URLs and API requests are blocked, not only hidden in the UI.
  • Confirm Facility Storekeeper and Regional Warehouse User cannot create new inbound movements.
  • Confirm Facility Storekeeper cannot access outbound or stocklist management.
  • Confirm Regional Warehouse User can manage outbound and stocklists.
  • Confirm RPC Superuser can access purchasing, products, stocklists, inbound, and outbound.
  • Confirm Reporting User can view supported pages but cannot create, edit, delete, import, publish, send emails, or otherwise mutate records.

Follow-up Checks

High Priority: Custom role assignment scope

  • Decide whether custom operational roles can be assigned as default/global roles.
  • Confirm whether custom role policies should only apply to location-specific role assignments.
  • Prevent accidental cross-location access, especially for ROLE_RPC_SUPERUSER.

High Priority: Create Stock Request vs Create Inbound Movement

  • Confirm whether Create Stock Request should be allowed separately from Create Inbound Movement.
  • Current behavior blocks stock request creation when inbound movement creation is denied.
  • Decide whether to split the route/permission or add a narrow policy exception.
  • Align backend route checks and frontend visibility rules.

Medium Priority: Legacy JSON allow-lists

  • Review fragile custom role allow-lists for legacy JsonController stocklist actions.
  • Add tests confirming allowed stocklist JSON actions do not expose unrelated JsonController actions.

Medium Priority: RPC Superuser product/configuration scope

  • Review if write applies to configuration areas such as product types, units of measure, categories, catalogs, and attributes.
  • Confirm whether Product Sources, preferences, packages, and delete actions should remain editable.

Introduce ROLE_FACILITY_STOREKEEPER across backend and frontend role catalogs,\nwith migration support for role creation.

Enforce role access across multiple layers:\n- Interceptor-level route and API restrictions for denied domains\n- Menu filtering policy for section/action visibility\n- Location chooser and filtered locations compatibility\n- User/role checks hardened via role-name comparisons to avoid enum identity issues

Also align purchase order UI actions and session capability flags with the\nnew policy while preserving higher-role precedence behavior.
Introduce ROLE_REGIONAL_WAREHOUSE across backend and frontend role catalogs, including database migration and i18n label updates.

Add policy checks in interceptors/services to allow inventory and outbound operations while denying purchasing and inbound movement creation for regional warehouse users.

Update menu/session/location chooser and requisition/stock list UI behavior to expose role-aware client state and hide restricted actions.
Implement ROLE_RPC_SUPERUSER as a location-scoped custom policy with highest-role-wins semantics.

Wire role plumbing across backend and frontend session context, including migration and i18n.

Enforce access through RoleInterceptor allow/deny paths, menu policy filtering, and location-aware role checks.

Enable missing write UX paths for purchasing, products, and stocklists while preserving existing restricted-role behavior.
Implement ROLE_REPORTING_USER as a location-scoped operational role with highest-role-wins behavior and explicit policy predicates.

Wire role plumbing across backend and frontend (RoleType, JS constants, session payload/reducer, i18n label, location chooser support, and Liquibase role seed migration).

Enforce permissions in RoleInterceptor and MegamenuService: deny purchasing, keep reporting/menu visibility for reads, block write/mutation routes, and hide inbound/outbound create actions for reporting users.
- centralize custom role authorization in CustomRolePolicyService

- align backend/frontend visibility and route enforcement for custom roles

- fix detached-session lazy role access in role-policy/user-role checks

- archive openspec change custom-roles-refactor and sync main specs
… session flags

Unify custom-role branching behind canonical policy helpers to avoid duplicated role-specific checks and prevent omissions like Reporting User in authenticated routing branches.

Delegate megamenu minimum/supplemental role decisions to CustomRolePolicyService, keeping menu rendering focused on composition while policy exceptions stay in one authorization layer.

Drop redundant per-role policy booleans from app-context/session state and rely on canonical customRolePermissions payload, then add regression tests for generic hasAnyCustomPolicy behavior, app-context permissions shape, menu role helper decisions (including RPC superuser exceptions), and custom role hierarchy/priority expansion guarantees.

Also document frontend runtime requirement in CLAUDE.md: use nvm use 14 before frontend tests/build commands, since this repo’s frontend toolchain is pinned to Node 14 and mismatches cause false-negative test/build failures.
Hide server-rendered and React product write affordances for read-only custom roles by gating create/import/edit/delete controls behind product-management permissions.

Includes follow-up fixes from manual testing and review, plus archived OpenSpec documentation updates to keep upstream touch points accurate.
@MatiasArriola MatiasArriola marked this pull request as ready for review May 26, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant