Files
archivmail/features/PROJ-17-system-dashboard.md
T
sysops bb963a796f security: Zufallspasswörter beim Erststart, kryptographisch sichere JTI-Generierung
- seedDefaultUsers: generiert kryptographisch zufällige Passwörter (crypto/rand)
  statt hartkodiertes "archivmailrockz" — Passwörter werden einmalig im Terminal
  angezeigt und können danach nicht wiederhergestellt werden
- generateJTI: verwendet crypto/rand (16 Byte, hex) statt time.UnixNano XOR deadbeef

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 01:19:24 +01:00

87 lines
3.9 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.
# PROJ-17: Admin Dashboard Systemauslastung & Archiv-Übersicht
## Status: Deployed
**Created:** 2026-03-14
**Last Updated:** 2026-03-17
## 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`