3 Commits

Author SHA1 Message Date
c35145ef8e feat: Pico.css für Dark/Light-Mode und Responsivität
Klassenloses CSS-Framework (self-hosted unter static/, kein CDN), passt
zum bestehenden Ansatz ohne JS-Build-Schritt. Bringt automatisches
Dark/Light-Mode (prefers-color-scheme) und Responsivität ohne
Zusatzaufwand. Templates auf Picos semantische Konventionen umgestellt
(label/input-Paare, article für die Login-Karte, figure um Tabellen für
horizontales Scrollen). Eigene CSS-Regeln auf die zwei Farb-Utility-
Klassen (state-present/state-absent) reduziert, Rest kommt von Pico.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-05 08:16:43 +02:00
21c6210869 fix: password_hash aus DB als bytes statt str behandeln
psycopg liefert die TEXT-Spalte password_hash beim SELECT als bytes
zurück, nicht als str wie beim create_user.py-Insert - bcrypt.checkpw()
schlug dadurch bei jedem Login-Versuch mit AttributeError fehl. Gefunden
beim ersten E2E-Login-Test auf anode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 17:06:18 +02:00
c4825acd61 feat: initiale Kundenplattform (Login + Auftragskatalog-Auswahl)
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>
2026-08-04 17:00:03 +02:00