Neuer, von provisioning-server (anode) getrennter Dienst, siehe ADR-0011: FastAPI + Jinja2, eigene Postgres-DB (benutzer-Tabelle), eigenes Service-Token (TUXFLOTTE_KUNDENPLATTFORM_TOKEN) für die Kommunikation mit anode. Org-Zugehörigkeits-Prüfung passiert hier in der Anwendung vor jedem Aufruf gegen anode. Umfang v1: Login, Geräteliste, Auftragskatalog geräteweise aus-/abwählen (inkl. der standardbrowser-Option für Brave). systemd-Unit läuft unter eigenem unprivilegiertem System-User statt root. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
62 lines
2.2 KiB
Markdown
62 lines
2.2 KiB
Markdown
# kundenplattform
|
|
|
|
Kunden-Web-UI für den Tuxflotte-Auftragskatalog — von `provisioning-server`
|
|
(anode) bewusst getrennter Dienst, siehe [ADR-0011](https://git.tuxflotte.de/admin/platform-docs/raw/branch/main/adr/0011-kundenplattform-getrennter-dienst.md).
|
|
|
|
## Architektur
|
|
|
|
- FastAPI + Jinja2 (serverseitig gerendert, kein Frontend-Build).
|
|
- Eigene Postgres-Datenbank (`benutzer`-Tabelle: E-Mail/Passwort-Hash pro
|
|
Organisation) — getrennt von provisioning-servers Datenbank, keine
|
|
Cross-Database-Referenzen.
|
|
- Spricht mit anode ausschließlich über dessen HTTP-API, authentifiziert mit
|
|
einem eigenen Service-Token (`TUXFLOTTE_KUNDENPLATTFORM_TOKEN`, getrennt
|
|
vom Admin-Token). Organisationszugehörigkeits-Prüfung (darf dieser Login
|
|
auf dieses Gerät zugreifen?) passiert hier in der Anwendung, vor jedem
|
|
Aufruf gegen anode — siehe `find_device_in_organization()` in `app.py`.
|
|
|
|
## Setup (lokal)
|
|
|
|
```
|
|
python3 -m venv .venv
|
|
.venv/bin/pip install -r requirements.txt
|
|
KUNDENPLATTFORM_DATABASE_URL=postgresql://... .venv/bin/psql ... -f migrations/0001_initial_schema.sql
|
|
```
|
|
|
|
Env-Variablen:
|
|
|
|
- `TUXFLOTTE_ANODE_URL` (Default `http://127.0.0.1:8080`)
|
|
- `TUXFLOTTE_KUNDENPLATTFORM_TOKEN` — muss mit dem gleichnamigen Wert in
|
|
provisioning-servers `/etc/tuxflotte/provisioning-server.env` übereinstimmen
|
|
- `KUNDENPLATTFORM_DATABASE_URL`
|
|
- `KUNDENPLATTFORM_SESSION_SECRET` — beliebiger zufälliger String zum Signieren
|
|
der Session-Cookie (z.B. `openssl rand -base64 32`)
|
|
|
|
Start: `.venv/bin/uvicorn app:app --port 8081`
|
|
|
|
## Konto anlegen
|
|
|
|
Kein Self-Service in v1 (siehe ADR-0011) — Konten werden manuell angelegt:
|
|
|
|
```
|
|
KUNDENPLATTFORM_DATABASE_URL=... .venv/bin/python scripts/create_user.py \
|
|
--organization-id <organization-uuid> \
|
|
--email admin@schule-beispiel.de
|
|
```
|
|
|
|
## Deploy (anode)
|
|
|
|
Wie bei `provisioning-server`, git-basiert statt scp:
|
|
|
|
```
|
|
git pull --ff-only
|
|
systemctl restart kundenplattform
|
|
```
|
|
|
|
Läuft unter einem eigenen, unprivilegierten System-User `kundenplattform`
|
|
(nicht root, anders als provisioning-server) — siehe `kundenplattform.service`.
|
|
Port `8081` (provisioning-server belegt `8080`).
|
|
|
|
**Öffentliche Erreichbarkeit über Pangolin ist nicht Teil dieses Repos** —
|
|
das ist ein separater Ops/DNS/Reverse-Proxy-Schritt.
|