Files
qweZabbixDashboard/CLAUDE.md
2026-04-20 17:10:57 +02:00

99 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
npm install # install dependencies
npm start # run production server (port 3000)
npm run dev # run with --watch (auto-restart on file changes)
```
There are no tests or linters configured.
Docker:
```bash
docker-compose up -d --build
```
## Architecture
Single-process Node.js app. `server.js` acts as both an API proxy (keeping the Zabbix token server-side) and a static file host for the vanilla JS frontend in `public/`.
```
server.js Express backend — Zabbix JSON-RPC proxy + REST API
public/
index.html Shell: header, view toggle, countries layout container, modal
style.css Light theme, CSS variables for hex sizing, hex grid layout
app.js All frontend logic — fetch, render, interactions
.env Runtime config (gitignored)
docker-compose.yml Reads ZABBIX_TOKEN from env or .env
```
## Config (env vars)
| Variable | Default | Purpose |
|---|---|---|
| `ZABBIX_URL` | `https://monitor.stranto.com` | Zabbix instance |
| `ZABBIX_TOKEN` | — | API bearer token (required) |
| `CUSTOMER_TAG_VALUE` | `QWE` | Zabbix host tag `customer=<value>` that identifies KFC hosts |
| `COUNTRY_TAG` | `country` | Zabbix host tag name used for country grouping |
| `PORT` | `3000` | HTTP port |
## Zabbix API conventions
- Auth: `Authorization: Bearer <token>` header (Zabbix 6.4+ style — NOT the legacy `auth` body field)
- All hosts are scoped by tag `customer=QWE` (operator `1` = equals)
- Host groups use `selectHostGroups` / `host.hostgroups` — NOT the deprecated `selectGroups` / `host.groups`
- Countries come from a `country` host tag (e.g. `AT`, `SK`)
- Restaurants group by `location` host tag; device types group by host group, keyed as `groupid__country`
- Severity 0 (Not classified) and 1 (Information) are treated as OK throughout
- Acknowledged problems are excluded via `withLastEventUnacknowledged: true`
- `expandDescription: true` on `trigger.get` resolves `{HOST.NAME}` and other macros in descriptions
## Backend API endpoints
| Endpoint | Returns |
|---|---|
| `GET /api/restaurants` | Array of `{ location, country, hostCount, problemCount, severity, problems[] }` |
| `GET /api/devices` | Same shape but grouped by host group; `name` instead of `location` |
| `GET /api/stats` | `{ [countryCode]: { hostCount, itemCount, triggerCount } }` — fetched in parallel with grid data |
| `GET /api/detail?type=&id=` | Per-host problem detail for modal |
| `GET /api/config` | `{ zabbixUrl, customerTagValue }` |
| `GET /api/health` | Zabbix connectivity check |
Each `problems[]` entry: `{ description, priority, lastchange (unix seconds), hostName }`, sorted by severity desc then time desc.
## Frontend data flow
1. Boot: fetch `/api/config`, then fetch grid data + `/api/stats` in parallel
2. Items are grouped by `country` field and rendered as equal-width `.country-col` columns
3. Each column renders: flag + country header → hex grid → problem list (locations with active problems)
4. Single click → detail modal (`/api/detail`); double click → Zabbix Problems page in new tab (240ms timer separates the two)
5. Auto-refresh every 30 seconds
## Hex grid geometry
For equal gaps on all 6 sides, the hex dimensions must satisfy `--hex-w = --hex-h × sin(60°) ≈ --hex-h × 0.866`. The row vertical overlap is:
```css
margin-top: calc(var(--hex-h) * -0.25 + var(--hex-gap) * 0.866);
```
Changing `--hex-gap` without updating `margin-top` will make diagonal gaps unequal. The even-row offset (`margin-left` on `.hex-row.offset`) is always `(hex-w + hex-gap) / 2`.
## Zabbix Problems URL format (7.x)
Parameters use **no** `filter_` prefix. Key params: `show=1` (recent), `evaltype=0`, `tags[N][tag/value/operator]`, `groupids[]`, `severities[]=2..5`. The legacy `filter_show`, `filter_tags`, `filter_set` format does not work in Zabbix 7.x.
## Severity mapping
| Zabbix priority | Label | Colour |
|---|---|---|
| -1 (no problems / ack / info) | OK | green `#2da44e` |
| 2 | Warning | amber `#c69026` |
| 3 | Average | orange `#e16f24` |
| 4 | High | red `#d1242f` |
| 5 | Disaster | purple `#8250df` (pulses) |