docs(guide): institution create/delete is BCOS-only; MSP submits a request (msp#29) #20

Merged
hiveiq merged 1 commits from docs/institution-keys-bcos-only into develop 2026-07-15 16:03:12 -04:00
5 changed files with 25 additions and 21 deletions
Showing only changes of commit 9cfb085339 - Show all commits
@@ -18,9 +18,9 @@ audience: bcos
|---------------|------|---------|
| GET `/api/institution-keys` | any JWT, scoped | `getAll` → `getAccessible` |
| GET `/api/institution-keys/accessible` | any JWT, scoped | `getAccessible` |
| POST `/api/institution-keys` | `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')` | `create` (body: `key`,`institutionName`,`supportedDeviceTypes`) |
| POST `/api/institution-keys` | `hasRole('BCOS_ADMIN')` | `create` — **BCOS only**; institution creation is a BCOS/mgmt task, not MSP (msp#29) |
| PUT `/api/institution-keys/{key}` | `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')` | `update` (body: `institutionName`,`supportedDeviceTypes`) |
| DELETE `/api/institution-keys/{key}` | `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')` | `delete` |
| DELETE `/api/institution-keys/{key}` | `hasRole('BCOS_ADMIN')` | `delete` — **BCOS only** (msp#29) |
| GET/PUT `/api/institution-keys/{key}/agent-properties` | GET scoped / PUT MSP_ADMIN,BCOS_ADMIN | agent config |
| GET `/api/institution-keys/{key}/agent-properties/flat` | scoped | flat CONFIG_UPDATE map |
| GET `/api/institution-keys/config-status` | scoped | pending-push status |
@@ -49,7 +49,8 @@ audience: bcos
## Roles
- Read (`getAll`/`accessible`/`config-*`): no `@PreAuthorize`; scoped by `InstitutionContext.resolveScope()`. `null` (BCOS_ADMIN/ADMIN/USER) = all; list (CUSTOMER/MSP_ADMIN) = JWT keys.
- Write (create/update/delete/save-agent-props): `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')` — plain `ADMIN` is **excluded**.
- Write — **create / delete**: `hasRole('BCOS_ADMIN')` only. Creating/removing an institution is a BCOS/mgmt responsibility, not MSP (msp#29); the MSP SPA hides the **+ Add Mapping** / **Delete** controls for non-BCOS.
- Write — **update / save-agent-props**: `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')`. Plain `ADMIN` is **excluded** from all writes.
## Gotchas
- `DeviceType` enum = `ATM, TCR, SRV`. `parseDeviceType` maps unknown/blank → **`ATM`** (silent fallback).
@@ -65,6 +66,7 @@ audience: bcos
- Do NOT look for an institution-keys endpoint/table in **hiveops-msp** or **hiveops-mgmt** — it's **hiveops-devices** only.
- Do NOT expect a Kafka event or `device_summary` update after a key rename — none fires.
- Do NOT change `key` on a mapping — recreate; PK is immutable.
- Do NOT grant create/edit to a plain `ADMIN` role and expect it to work — needs MSP_ADMIN/BCOS_ADMIN.
- Do NOT expect an MSP_ADMIN to create or delete institution keys — create/delete are **BCOS_ADMIN only** (msp#29); MSP edits existing mappings only. Plain `ADMIN` cannot write at all.
- Do NOT treat "devices owns institution creation" as correct long-term — it is a service-ownership gap (mgmt provisioning is canonical; devices has no mgmt→devices mirror; keys have diverged). Tracked in msp#29.
- Do NOT delete a key to "clean up" — it cascades away its agent config and blinds JWT holders of that key.
- Do NOT treat unknown-`deviceType` reg failures as typos — the fallback is ATM; a 403 is a real type mismatch.
@@ -17,8 +17,9 @@ Owning service is **hiveops-devices** (NOT hiveops-msp — the MSP SPA has no ba
- **Read** (list/search): any valid JWT. `GET` endpoints have **no `@PreAuthorize`**; results are scoped by `InstitutionContext.resolveScope()`.
- BCOS_ADMIN / ADMIN / USER → unrestricted (sees all).
- CUSTOMER / MSP_ADMIN → only their JWT-granted keys.
- **Create / Edit / Delete**: `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')` only.
- Note: a plain `ADMIN` (or USER) can *read all* but **cannot mutate** — the write `@PreAuthorize` does not include `ADMIN`. If a "why can't I add a key?" ticket comes in, check the caller's role first.
- **Create / Delete**: `hasRole('BCOS_ADMIN')` only. Creating or removing an institution is a BCOS/mgmt responsibility, not MSP (msp#29). MSP admins do not see the **+ Add Mapping** / **Delete** controls.
- **Edit** (rename / device types / agent props): `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')`.
- Note: a plain `ADMIN` (or USER) can *read all* but **cannot mutate**. A "why can't I add/delete a key?" ticket from an **MSP** is now **expected behaviour** — MSP cannot create/delete institutions; escalate to a BCOS admin.
## First things to check when it misbehaves
1. **New device won't come online / not visible.** The device's `deviceType` must be in `supported_device_types` for its key, and the key must exist. Registration (agent-proxy → devices `POST /api/internal/atms/register`) returns **403 `{linked:false, error:...}`** when the device type isn't supported. Add the missing type on the Edit panel.
@@ -6,18 +6,21 @@ order: 10
audience: customer
---
Institution Keys link a short institution code to the full institution name your devices use. Use this screen when you add a new institution, correct a name, or control which kinds of devices are allowed to connect.
Institution Keys link a short institution code to the full institution name your devices use. Use this screen to review mappings, correct a name, or control which kinds of devices are allowed to connect.
> **⚠️ Only BCOS can add an institution.** MSP and customer admins can view and edit existing mappings, but **cannot create or delete institutions** — you won't see the **+ Add Mapping** or **Delete** buttons. **To have a new institution added (or an existing one removed), submit a request to BCOS.**
## 🔎 Find a Mapping
1. Use the **Search** box to filter by key code or institution name.
2. Toggle **Auto-refresh** to keep the list current, or click the **↻** refresh button to update it now.
## Add a Mapping
1. Click **+ Add Mapping** in the toolbar.
2. Enter the **Key** — a short code of 210 uppercase letters (e.g. `AICU`).
3. Enter the **Institution Name** exactly as it appears on your devices — this is case-sensitive and must match precisely.
4. Choose the **Supported Device Types** (ATM, TCR, or both).
5. Click **Add Mapping** to save.
## Adding a New Institution (BCOS only)
Creating a new institution is handled by **BCOS**, so there is no **+ Add Mapping** button on this screen for MSP or customer admins. **Submit a request to BCOS** with:
- the **Key** you want — a short code of 210 uppercase letters (e.g. `AICU`),
- the **Institution Name** exactly as it appears on your devices (case-sensitive, must match precisely),
- the **Supported Device Types** (ATM, TCR, or both).
Once BCOS creates the mapping, you can edit its name and device types here.
## ✏️ Edit a Mapping
1. Click **Edit** on any row.
@@ -26,11 +29,8 @@ Institution Keys link a short institution code to the full institution name your
> The key code itself can't be changed after a mapping is created — only the name and device types.
## 🗑️ Delete a Mapping
1. Click **Delete** on the row you want to remove.
2. Confirm in the pop-up.
> Deleting a mapping means users tied to that key will no longer see any devices until a new mapping is created. Remove one only when you're sure it's no longer in use.
## 🗑️ Removing an Institution (BCOS only)
Deleting an institution is also a **BCOS-only** action — **submit a request to BCOS**. Removing a mapping means users tied to that key can no longer see any devices, so BCOS removes one only when it is confirmed no longer in use.
## 📋 What You're Looking At
- **Key** — the short institution code.
@@ -13,8 +13,8 @@ Log in at **msp.bcos.dev** — test accounts (all password `Passw0rd-d3v!`):
| Login | Role | Sees |
|-------|------|------|
| `bcos_a@bcos.dev` | Admin | All institutions (C1BD, C2BD, C3BD) · can add/edit/delete |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · can add/edit/delete |
| `bcos_a@bcos.dev` | BCOS admin | All institutions (C1BD, C2BD, C3BD) · **can add / edit / delete** |
| `msp_a@msp1.bcos.dev` | MSP admin | C1 + C2 only · **edit only — no add / delete** (adding/removing an institution is BCOS-only; MSP submits a request to BCOS) |
| `customer_a@customer1.bcos.dev` | Customer | C1 only · read-only |
The keys map to the simulator institutions **C1BD / C2BD / C3BD** (whose devices are `C1-ATM-001…`, `C1-TCR-001…`, etc.).
@@ -30,7 +30,7 @@ The keys map to the simulator institutions **C1BD / C2BD / C3BD** (whose devices
| 5 | Change the name or a device-type checkbox and click **Save Changes** | Toast confirms, and the row shows the updated name / device types |
| 6 | Click **Delete** on the `TEST1` row | A confirm pop-up naming **TEST1** appears; clicking **Delete** removes the row from the table |
| 7 | Turn the **Auto-refresh** toggle off then on, then click the **↻** refresh button | List reloads with no error and the `(60s)` countdown resets |
| 8 | Log in as `msp_a` and open Institution Keys | You see the **C1BD and C2BD** rows only **no C3BD** |
| 8 | Log in as `msp_a` and open Institution Keys | You see the **C1BD and C2BD** rows only (**no C3BD**), and there is **no + Add Mapping button** and **no Delete** on rows — MSP can **edit only** (adding/removing an institution is BCOS-only) |
| 9 | Log in as `customer_a` and open Institution Keys | You see **only C1BD**; if you try **+ Add Mapping** and save, an **error toast** shows and no new row is added (read-only) |
**Report a fail with:** the row #, which login you used, and what you actually saw.
@@ -89,6 +89,7 @@ Base paths: `/api/atms` + `/api/devices`, `/api/atm-groups`, `/api/atm-makes`, `
- **Stale CLAUDE.md.** `hiveops-devices/CLAUDE.md` says the app has no backend and calls `hiveops-incident`; that's outdated — the `backend/` service exists and owns these domains.
- **DB uses `DB_URL`** (full JDBC URL) via `spring.datasource.url=${DB_URL:...}`, not split host/port/name vars.
- **Two auth realms.** Admin controllers use `@PreAuthorize("hasAnyRole('MSP_ADMIN','BCOS_ADMIN')")`; internal/agent controllers (`/api/internal/*`) use `hasRole('INTERNAL')` (e.g. `InternalAtmController`, `AgentTokenInternalController`, `InternalLogController`).
- **Exception:** `POST` and `DELETE /api/institution-keys` are `hasRole('BCOS_ADMIN')` only — creating/removing an institution is a BCOS/mgmt task, not MSP (msp#29). `PUT`/update stays MSP+BCOS.
- **Phase-2 path aliases.** `/api/atms`, `/api/atm-groups`, `/api/atm-makes`, `/api/atm-models`, `/api/atm-field-definitions` each also respond on a `/api/device*` alias for the ongoing ATM→device rename; both must stay routable in nginx.
- **CDN token.** `agent.cdn.token` (env `CDN_TOKEN`) has a hardcoded fallback in `application.properties` used by the `/api/agent-profiles/modules-manifest` proxy.
- **Publish-on-every-change.** Device mirrors in incident/fleet/reports/recon depend on `hiveops.device.events`; any write path that skips `DeviceEventPublisher` leaves those mirrors stale (no reconciler).