---
module: msp.module-allocations
title: Module Allocations
tab: Internal
order: 20
audience: internal
---

Ops/support view for the **Module Allocations** screen in the MSP admin SPA (`msp.bcos.cloud`, port 5186). This screen lets an admin grant/revoke optional HiveIQ Browser app modules per user. The SPA has **no backend of its own** — it calls `hiveops-mgmt` (modules + institutions) and `hiveops-auth` (user list).

## Who can use it
- Every backing endpoint is gated `@PreAuthorize("hasAnyRole('MSP_ADMIN','BCOS_ADMIN')")`.
- **MSP_ADMIN** — sees only institutions/users under their own MSP. Scope is resolved **from the email domain** (`customer.domain`), not from the JWT institution-keys claim (the claim goes stale when new institutions are added after last login).
- **BCOS_ADMIN** — sees all institutions and all non-SYSTEM users.
- Any other role → 403 (or empty result set from `/auth/api/msp/users`).

## What the screen actually does
- Loads three lists in parallel: allocatable modules, users (paginated, `size=200`), institutions.
- **Allocatable module catalogue** = modules that are `enabled=true` AND `isDefault=false`. Default modules are intentionally hidden — everyone already gets them.
- Per-user allocations load lazily on row **hover** and on panel open.
- Saving does a **full replace**: the chosen module-id set overwrites the user's previous allocation (delete-all-then-insert), not a delta.
- Allocations take effect the **next time the user opens the HiveIQ Browser launcher** — no push, no live update.

## First things to check when it misbehaves
1. **"No modules to assign" / empty legend** — the catalogue is empty because no module row is both `enabled=true` and `isDefault=false`. Check `app_modules` in `hiveiq_mgmt`. A newly registered module must be `enabled=TRUE, is_default=FALSE` to appear here.
2. **User was granted a module but it never shows in their launcher** — this is the **institution gate**, not a bug in this screen. This screen writes *user* allocations only. The launcher (`GET /api/v1/users/me/modules`) returns defaults + user-allocations **filtered to modules the user's institution is allowed** (`institution_module_allocations`) unless the user is BCOS_ADMIN. If the institution has no allocation row for that module, the user won't see it. Fix: allocate the module to the institution too.
3. **A whole institution / all its users are missing** — MSP scope is domain-derived. If the admin's `customer.domain` doesn't match, or the MSP has no `customer_institution_access` rows, they see nothing. Verify the MSP customer record and its institution-access grants in `hiveiq_mgmt`.
4. **403 on load** — token role isn't MSP_ADMIN/BCOS_ADMIN, or the JWT isn't being forwarded. Both mgmt and auth enforce the same role check.
5. **Users load but allocations column stuck on "…"** — the per-user `GET /modules/users/{id}` is failing (network/CORS). Failures are swallowed silently in the UI (empty `catch`), so check the browser network tab / mgmt logs, not the screen.

## Common failure modes → fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Module not in the assign list | `enabled=false` or `is_default=true` | Toggle module flags in `app_modules` |
| Saved, but user still can't open module in browser | Institution gate blocks it | Add institution-level allocation for that module |
| MSP_ADMIN sees no institutions | Email domain ≠ `customer.domain`, or no access grants | Fix domain / add `customer_institution_access` rows |
| Users list empty for MSP_ADMIN | No institution keys in MSP scope | Grant institution access to the MSP customer |
| Changes "don't apply" | User hasn't reopened the launcher | Have them relaunch HiveIQ Browser |

## Notes
- Auto-refresh reloads the three base lists every 60s (toggle persisted in `localStorage` key `msp_allocations_autoRefresh`); it does **not** re-pull per-user allocation maps already cached in the session.
- Saving is idempotent-safe: re-saving the same set just rewrites the rows.
