feat(PROJ-17): Admin Dashboard Systemauslastung immer anzeigen

- Systemauslastungs-Sektion wird immer gerendert (nicht nur bei Erfolg)
- Fehlermeldung wenn /api/admin/system/stats nicht erreichbar ist
- Feature-Status auf In Review gesetzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-03-14 11:43:19 +01:00
parent a893084a88
commit d360c9a5ba
68 changed files with 11938 additions and 435 deletions
+86
View File
@@ -0,0 +1,86 @@
# PROJ-17: Admin Dashboard Systemauslastung & Archiv-Übersicht
## Status: In Review
**Created:** 2026-03-14
**Last Updated:** 2026-03-14
## Dependencies
- Requires: PROJ-1 (Authentifizierung) nur Admins sehen das Dashboard
- Requires: PROJ-5 (Speicherung) erste/letzte Mail aus dem Archiv
## User Stories
- Als Admin möchte ich die aktuelle CPU-Auslastung sehen, damit ich Engpässe erkennen kann.
- Als Admin möchte ich die RAM-Auslastung (gesamt / verwendet / frei) sehen.
- Als Admin möchte ich alle eingebundenen Festplatten/Partitionen mit Füllstand sehen (Balken).
- Als Admin möchte ich die älteste und neueste archivierte Mail sehen (Datum, Von, Betreff), damit ich den Archivierungszeitraum auf einen Blick erkenne.
## Acceptance Criteria
- [x] CPU: Load Average (1min / 5min / 15min) aus `/proc/loadavg`
- [x] RAM: MemTotal, MemUsed, MemAvailable aus `/proc/meminfo`; Prozentbalken
- [x] Disk: alle physischen Partitionen (keine tmpfs/proc/sysfs/devtmpfs/overlay) via `syscall.Statfs`; je Partition: Mountpoint, Gesamt, Belegt, Frei, Prozent
- [x] Erste Mail im Archiv: Datum, Von, Betreff (älteste Datei im Store)
- [x] Letzte Mail im Archiv: Datum, Von, Betreff (neueste Datei im Store)
- [x] Endpoint: `GET /api/admin/system/stats` (Admin-only)
- [x] Storage-Erweiterung: `store.FirstAndLastMail()` liefert Metadaten der ältesten und neuesten Mail
## API Response Schema
```json
{
"cpu": {
"load1": 0.42,
"load5": 0.38,
"load15": 0.31,
"num_cpu": 4
},
"ram": {
"total_bytes": 8388608000,
"used_bytes": 3221225472,
"free_bytes": 5167382528,
"used_pct": 38.4
},
"disks": [
{
"mount": "/",
"total_bytes": 53687091200,
"used_bytes": 12884901888,
"free_bytes": 40802189312,
"used_pct": 24.0,
"fstype": "ext4"
}
],
"archive": {
"first_mail": { "id": "abc123", "date": "2024-01-15T08:00:00Z", "from": "...", "subject": "..." },
"last_mail": { "id": "def456", "date": "2026-03-14T10:08:00Z", "from": "...", "subject": "..." }
}
}
```
## Technical Design
### Backend (`internal/api/server.go`)
- Neuer Handler `handleSystemStats`
- CPU: `/proc/loadavg` parsen → load1, load5, load15 + `runtime.NumCPU()`
- RAM: `/proc/meminfo` parsen → MemTotal, MemFree, MemAvailable, Buffers, Cached
- `used = total - available`
- Disks: `/proc/mounts` lesen, für jeden Eintrag `syscall.Statfs()` aufrufen
- Ausschließen: fstype in {tmpfs, proc, sysfs, devtmpfs, cgroup, cgroup2, overlay, squashfs, debugfs, tracefs, securityfs, pstore, efivarfs, bpf, hugetlbfs, mqueue, ramfs}
- Erste/letzte Mail: `store.FirstAndLastMail()` → walk store dir, min/max ModTime
### Storage (`internal/storage/storage.go`)
- Neue Methode `FirstAndLastMail() (*MailRef, *MailRef, error)`
- `MailRef{ID, ModTime}` → ID wird an `handleSystemStats` übergeben, der dann via `mailparser.Parse()` From+Subject+Date extrahiert
### Frontend (`src/app/admin/page.tsx`)
- Neue Kacheln im Dashboard-Tab:
- **CPU-Auslastung**: Load Average mit `num_cpu` Kontext
- **Arbeitsspeicher**: Fortschrittsbalken (used/total), Zahlen darunter
- **Festplatten**: eine Karte pro Partition mit Balken + Zahlen
- **Archivzeitraum**: erste und letzte Mail als kompakte Zeilen (Datum · Von · Betreff)
## Implementation Notes
- **Backend:** `handleSystemStats` in `internal/api/server.go` — CPU via `/proc/loadavg`, RAM via `/proc/meminfo`, alle Disks via `/proc/mounts` + `syscall.Statfs`, Archiv-Zeitspanne via `store.FirstAndLastMail()`
- **Storage:** `FirstAndLastMail()` + `MailRef` in `internal/storage/storage.go` — walkt Store-Verzeichnis, liefert älteste/neueste Mail per ModTime
- **Route:** `GET /api/admin/system/stats` (Admin-only, Token-Auth)
- **Frontend:** Dashboard-Tab in `src/app/admin/page.tsx` mit CPU, RAM, Disk-Partitionen und Archivzeitraum; Auto-Refresh alle 30 Sekunden
- **Bereit für Test auf** `root@192.168.1.131`