docs(guide): institution create/delete is BCOS-only; MSP submits a request (msp#29) #20
@@ -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 2–10 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 2–10 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).
|
||||
|
||||
Reference in New Issue
Block a user