# Servers Inventory Page — Session Reference

Created: 2026-07-08
Files: `/var/www/ops/servers.html`, `/var/www/ops/nav.html`

## Data source structure

Fetched from `/data/ops-status.json` (auto-refresh 30s):

### `netcup_server` (object)

```json
{
  "id": 890903,
  "template": "RS 2000 G12",
  "ip": "152.53.192.33"
}
```

Field name mapping (for resilience): `name || hostname`, `template`, `ip || ip_address`.

### `hetzner_servers` (array)

```json
[
  {
    "name": "wphost02",
    "status": "running",
    "type": "cpx21",
    "ip": "5.161.62.38",
    "id": 51140464
  }
]
```

Field name mapping: `name || hostname`, `type || server_type`, `ip || ip_address || ipv4`, `status`, `id`.

No `location` field present in current data — shows `—` for all rows.

### Resource percentages

```json
{
  "overall": { "disk_used_pct": 6, "memory_used_pct": 39 },
  "disk_memory": { "disk_used_pct": 6, "memory_used_pct": 39 }
}
```

Fallback chain: `overall.disk_used_pct` → `disk_memory.disk_used_pct` → null.

## netcup plan specs

| Plan | vCPUs | RAM (GB) |
|------|-------|----------|
| RS 2000 G12 | 4 | 16 |

## Hetzner plan specs (CPX line)

| Plan | vCPUs | RAM (GB) |
|------|-------|----------|
| CPX11 | 2 | 4 |
| CPX21 | 3 | 8 |
| CPX31 | 4 | 16 |
| CPX41 | 4 | 16 |
| CPX51 | 8 | 32 |

## Environment

- Domain: `app.itpropartner.com` (or whatever Caddy routes to `/var/www/ops/`)
- Data endpoint: `/data/ops-status.json`
- Nav partial: `/nav.html`

## File permission

Both `servers.html` and `nav.html` created with `600` mode by `write_file`. Must `chmod 644` before Caddy can serve them without 403.
