Files
hiveops-guide/backend/src/main/resources/content/devices/map/internal.md
T
johannes 2f94d62769 content(guide): role-tabs (Internal/Architect/Claude) for all 63 customer modules (DRAFT, Refs #1 #3)
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>
2026-07-01 12:14:54 -04:00

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 via InstitutionContext.resolveScope()).
  • To fix an unmapped ATM (set lat/long): hasAnyRole('MSP_ADMIN','BCOS_ADMIN') — coordinates live on the atms row and are edited through the admin-gated PUT /api/atms/{id} (ATM detail → properties).
  • To manage the groups that populate the Group filter: MSP_ADMIN/BCOS_ADMIN (/api/atm-groups mutations).

First things to check when it misbehaves

"Pins are missing / fleet looks half-empty"

  1. Almost always missing coordinates. Only ATMs with non-null latitude AND longitude are 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).
  2. A default group is active. If the user has a default group set (browser localStorage: hiveops_defaultGroupId), loadAtms() switches to GET /api/atms/paginated?size=9999&groupId=<gid> — so the map only ever shows that group, capped at 9999 rows.
  3. 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-incident health and that GET /api/incidents returns 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 in localStorage: devices_map_autoRefresh. Each tick re-runs loadAtms() + 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 /api segment to reach the controller's /api/incidents); a stale nginx block for incident.*/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.