Full role-tab rollout: every customer module now has Customer/Internal/ Architect/Claude tabs, grounded per-module in real code. Backend serves 296 docs / 96 modules. Grounding surfaced ~20 real bugs across services (filed separately after verification). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.1 KiB
module, title, tab, order, audience
| module | title | tab | order | audience |
|---|---|---|---|---|
| devices.map | Map | Internal | 20 | internal |
Internal · ops/support. Grounded in
hiveops-devices/frontend/src/components/AtmMap/AtmMap.svelte+ the devices/incident backends, 2026-07-01.
What this view actually does
The Fleet Map is a read-only Leaflet view. It makes no writes. On mount and on each auto-refresh it pulls three lists and does all clustering, colouring, and filtering client-side:
| Data | Source (frontend fn) | Backend |
|---|---|---|
| ATMs (pins) | loadAtms() → atmAPI.getAll() |
hiveops-devices GET /api/atms |
| Open incidents (orange colour + Incident Type filter) | loadIncidents() → incidentAPI.getAll() |
hiveops-incident GET /api/incidents |
| Groups (Group filter) | loadAtmGroups() → atmGroupAPI.getAll() |
hiveops-devices GET /api/atm-groups |
Key consequence: the map straddles two services. Pins come from devices; the orange "Open Incident" colour and the Incident Type filter come from incident. They fail independently.
Roles required
- To view the map: any authenticated JWT. The three GET endpoints above have no
@PreAuthorize— reads are open to any logged-in role (incidents are still institution-scoped server-side viaInstitutionContext.resolveScope()). - To fix an unmapped ATM (set lat/long):
hasAnyRole('MSP_ADMIN','BCOS_ADMIN')— coordinates live on theatmsrow and are edited through the admin-gatedPUT /api/atms/{id}(ATM detail → properties). - To manage the groups that populate the Group filter:
MSP_ADMIN/BCOS_ADMIN(/api/atm-groupsmutations).
First things to check when it misbehaves
"Pins are missing / fleet looks half-empty"
- Almost always missing coordinates. Only ATMs with non-null
latitudeANDlongitudeare plotted; the rest are silently dropped and counted in the amber "N ATMs have no coordinates" banner. Fix: open each via View in ATM List → and set lat/long (admin). - A default group is active. If the user has a default group set (browser
localStorage: hiveops_defaultGroupId),loadAtms()switches toGET /api/atms/paginated?size=9999&groupId=<gid>— so the map only ever shows that group, capped at 9999 rows. - An active status/type/group filter is narrowing the set — check the "Filters:" tag bar and the legend count (
X of Y filtered). Hit Clear all.
"No ATMs show as Open Incident (nothing goes orange) / Incident Type filter is empty"
- The incident backend call failed or returned nothing. Pins still render (devices is independent), but incident colouring/filtering is gone. Check
hiveops-incidenthealth and thatGET /api/incidentsreturns 200 for this user's institution. - Only incidents with
status === 'OPEN'count — resolved/closed incidents never colour a pin.
"Two ATMs at the same site aren't clustered into one pin"
- Clustering keys on the exact
"lat,lon"string. Coordinates that differ even slightly get separate pins. To force a shared count-badge pin, give the co-located ATMs identical lat/long.
"My saved presets / filters vanished"
- Presets and the last filter state are browser-local only (
localStorage: hiveops_map_filters_v2), never stored server-side. Clearing site data, a different browser, or a different machine = presets gone. This is expected, not a bug.
"Map won't stop reloading / reloads too often (or never)"
- Auto-refresh is a client timer; interval =
settings.dashboardRefreshIntervalSeconds. The toggle state persists inlocalStorage: devices_map_autoRefresh. Each tick re-runsloadAtms()+loadIncidents().
"401/403 loading the map"
- Expired/again JWT, or the incident call is being blocked by nginx. The incident list is fetched at gateway path
/incident/incidents(nginx injects the/apisegment to reach the controller's/api/incidents); a stale nginx block forincident.*/devices.*is the usual culprit for a one-service failure.
What you can NOT fix from this screen
- You can't edit coordinates, status, or incidents here — the map only reads. All corrections happen in ATM Detail (devices) or the Incident app.