diff --git a/saas-app/public/admin.php b/saas-app/public/admin.php index 9ee1a0f..4d3ed24 100644 --- a/saas-app/public/admin.php +++ b/saas-app/public/admin.php @@ -19,7 +19,28 @@ function admin_h(string $value): string function admin_badge(string $label, string $tone = 'neutral'): string { - return '' . admin_h($label) . ''; + $class = 'status'; + + if ($tone === 'success') { + $class .= ' status--success'; + } elseif ($tone === 'warning') { + $class .= ' status--warning'; + } elseif ($tone === 'error') { + $class .= ' status--danger'; + } + + return '' . admin_h($label) . ''; +} + +function admin_metric_value(array $metrics, string $label, string $fallback = '0'): string +{ + foreach ($metrics as $metric) { + if ((string) ($metric['label'] ?? '') === $label) { + return (string) ($metric['value'] ?? $fallback); + } + } + + return $fallback; } function admin_update_summary(array $items): array @@ -217,329 +238,1353 @@ SQL, ); } } + +$navItems = $admin === null + ? [ + ['href' => '/admin/login/', 'label' => 'Login', 'page' => 'login'], + ] + : [ + ['href' => '/admin/', 'label' => 'Übersicht', 'page' => 'overview'], + ['href' => '/admin/tenants/', 'label' => 'Mandanten', 'page' => 'tenants'], + ['href' => '/admin/updates/', 'label' => 'Updates', 'page' => 'updates'], + ['href' => '/admin/migration/', 'label' => 'Migrationen', 'page' => 'migration'], + ]; + +$pageTitle = match ($page) { + 'login' => 'Kaffeeliste Admin - Login', + 'overview' => 'Kaffeeliste Admin - Übersicht', + 'tenants' => 'Kaffeeliste Admin - Mandanten', + 'updates' => 'Kaffeeliste Admin - Updates', + 'migration' => 'Kaffeeliste Admin - Migrationen', + default => 'Kaffeeliste Admin', +}; + +$pageHero = match ($page) { + 'login' => [ + 'kicker' => 'Global-Admin', + 'title' => 'Zentrale Administration für die Kaffeeliste.', + 'lead' => 'Dieser Zugang ist ausschließlich für die globale Verwaltung gedacht und bleibt bewusst vom Mitglieder-Login getrennt.', + 'badges' => ['Getrennter Zugang', 'Mandanten', 'Updates & Migrationen'], + 'aside' => [ + ['label' => 'Zugang', 'value' => 'Separat', 'detail' => 'Der Global-Admin bleibt bewusst vom Mitglieder-Login getrennt.'], + ['label' => 'Oberfläche', 'value' => 'Zentral', 'detail' => 'Mandanten, Lizenzen und Betriebsaufgaben in einer Konsole.'], + ['label' => 'Version', 'value' => $appVersion, 'detail' => 'Aktuell bereitgestellter Stand der Anwendung.'], + ], + ], + 'overview' => [ + 'kicker' => 'Zentrale Übersicht', + 'title' => 'Portfolio, Lizenzen und Systemstände in einer Oberfläche.', + 'lead' => 'Die globale Verwaltung bündelt die wichtigsten Betriebsdaten und führt direkt in Lizenzpflege, Mandanten-Einstieg sowie Updates und Migrationen.', + 'badges' => ['Portfolio', 'Betrieb', 'Freischaltungen'], + 'aside' => [ + ['label' => 'Mandanten', 'value' => admin_metric_value($summaryMetrics, 'Mandanten gesamt'), 'detail' => 'Im zentralen Portfolio sichtbar.'], + ['label' => 'Updates offen', 'value' => (string) $updateSummary['pending'], 'detail' => 'Direkt aus der Weboberfläche ausführbar.'], + ['label' => 'Version', 'value' => $appVersion, 'detail' => 'Aktuell bereitgestellter Stand der Anwendung.'], + ], + ], + 'tenants' => [ + 'kicker' => 'Mandanten-Verwaltung', + 'title' => 'Mandanten zentral anlegen, lizenzieren und betreten.', + 'lead' => 'Hier pflegt der Global-Admin die Stammdaten aller Mandanten und steuert, welche Funktionspakete pro Lizenz freigeschaltet sind.', + 'badges' => ['Portfolio', 'Lizenzen', 'Mandantenzugang'], + 'aside' => [ + ['label' => 'Aktiv', 'value' => admin_metric_value($summaryMetrics, 'Aktive Mandanten'), 'detail' => 'Mandanten mit aktivem Status.'], + ['label' => 'Mitglieder', 'value' => admin_metric_value($summaryMetrics, 'Mitglieder gesamt'), 'detail' => 'Aktive Zuordnungen über alle Mandanten.'], + ['label' => 'SSO-Provider', 'value' => admin_metric_value($summaryMetrics, 'SSO-Provider'), 'detail' => 'Aktive Identitätsanbieter auf der Plattform.'], + ], + ], + 'updates' => [ + 'kicker' => 'Update-Center', + 'title' => 'System-Updates zentral prüfen und ausführen.', + 'lead' => 'Schema-Erweiterungen und Datenanpassungen werden versioniert dokumentiert und können direkt über die Weboberfläche angestoßen werden.', + 'badges' => ['Deployment', 'Web-Ausführung', 'Protokoll'], + 'aside' => [ + ['label' => 'Offen', 'value' => (string) $updateSummary['pending'], 'detail' => 'Warten auf Ausführung.'], + ['label' => 'Erfolgreich', 'value' => (string) $updateSummary['success'], 'detail' => 'Bereits dokumentiert abgeschlossen.'], + ['label' => 'Fehlgeschlagen', 'value' => (string) $updateSummary['failed'], 'detail' => 'Brauchen Aufmerksamkeit.'], + ], + ], + default => [ + 'kicker' => 'Migrations-Center', + 'title' => 'Datenbank-Migrationen zentral prüfen und ausführen.', + 'lead' => 'Die SQL-Migrationen aus database/migrations können hier nachvollziehbar über die zentrale Verwaltung eingespielt werden.', + 'badges' => ['Schema', 'Baseline', 'Web-Ausführung'], + 'aside' => [ + ['label' => 'Offen', 'value' => (string) $migrationSummary['pending'], 'detail' => 'Noch nicht eingespielt.'], + ['label' => 'Erfolgreich', 'value' => (string) $migrationSummary['success'], 'detail' => 'Bereits protokolliert.'], + ['label' => 'Fehlgeschlagen', 'value' => (string) $migrationSummary['failed'], 'detail' => 'Brauchen Aufmerksamkeit.'], + ], + ], +}; + +$flashClass = match ((string) ($flash['type'] ?? 'success')) { + 'error' => 'alert--danger', + 'warning' => 'alert--warning', + default => 'alert--success', +}; ?> - Kaffeeliste Admin + + <?= admin_h($pageTitle) ?> -
-
-
- Kaffeeliste Admin -

Zentrale Verwaltung für Mandanten, Lizenzen, Updates und Betriebsstatus.

-
- + + +
+ +
+
+ + + + + +
+ +
+
- -
- +
+ +
+ - -
-
Global-Admin
-

Zentrale Administration für die Kaffeeliste.

-

Dieser Zugang ist ausschließlich für die globale Verwaltung gedacht und bleibt bewusst vom Mitglieder-Login getrennt.

+
+
+
+

+

+

+
+
+ + + +
+
+
-
-
-
-
-

Anmelden

-
- - - - -
-
-
-
-

Hinweise zur Einrichtung

-
    -
  • Der erste Global-Admin wird im Installer angelegt oder aktualisiert.
  • -
  • Die Anmeldung prüft users.is_platform_admin = 1 und das gespeicherte Passwort.
  • -
  • Nach dem Login stehen Übersicht, Mandanten-Verwaltung und Update-Center zentral bereit.
  • -
-
-
- -
-
Zentrale Übersicht
-

Alle Mandanten, Lizenzen und Systemstände an einer Stelle.

-

Die globale Verwaltung bündelt die wichtigsten Betriebsdaten und führt direkt in Lizenzpflege, Mandanten-Einstieg und Updates.

-
-
-
- -
- -

-

+ + +
+ + + +
+ + + +
+ + + +
+
+

Zugang

+

Anmelden

+
+ + + + +
+ + Mitglieder-Login öffnen +
+
- -
-
-
-

Angemeldet als

-
-
-

-

-
-
-

Aktuelle Version

-

-
-
-
-
-

Schnellzugriffe

- -
    -
  • Mandanten können direkt mit einem passenden Lizenzplan angelegt werden.
  • -
  • Als Global-Admin kannst du jeden Mandanten öffnen und operativ prüfen.
  • -
  • System-Updates laufen über die Weboberfläche ohne Shell-Zugriff.
  • -
-
-
-

Update-Lage

-
-

Offen

Update(s) warten auf Ausführung.

-

Fehlgeschlagen

Update(s) brauchen Aufmerksamkeit.

-

Erfolgreich

Update(s) sind bereits dokumentiert.

-
-
-
- -
-
Mandanten-Verwaltung
-

Mandanten zentral anlegen, lizenzieren und betreten.

-

Hier pflegt der Global-Admin die Stammdaten aller Mandanten und steuert, welche Funktionspakete pro Lizenz freigeschaltet sind.

-
-
-
-
-

-
- - - - - - - -
- - Zur Übersicht -
-
- -

Die Lizenzpläne sind noch nicht verfügbar. Bitte zuerst die System-Updates ausführen.

- -
-
-

Lizenzrahmen

-
-

Free

Bis zu 10 aktive Mitglieder, inklusive Mandanten-Einstellungen, PDF-Listen und Papier-Nacherfassung.

-

Starter & Team

Mehr Mitglieder für wachsende Standorte, weiterhin mit vollem Drucklisten-Prozess als Kernfunktion.

-

Business & Enterprise

Zusätzliche Erweiterungen wie SSO, Benachrichtigungen, Auswertungen und individuelle Freischaltungen.

-
-
-
-
-

Vorhandene Mandanten

-
- - - - - - - - - - - - - - - - -
NameKeyStatusLizenzMitgliederAdminsSSOAktionen
-
- Bearbeiten -
- - - - -
-
-
-
-
- -
-
Update-Center
-

System-Updates zentral prüfen und ausführen.

-

Schema-Erweiterungen und Datenanpassungen werden versioniert dokumentiert und können direkt über die Weboberfläche angestoßen werden.

-
-
-
-
-

Stand der Anwendung

-
-

Version

-

Offene Updates

-

Fehlgeschlagen

-
-
-
-

Update-Ausführung

-

Updates laufen idempotent. Bereits erfolgreiche Updates werden übersprungen und bleiben im Protokoll sichtbar.

-
- - - -
-
-
-

Betriebsmodell

-
    -
  • Updates liegen versioniert unter saas-app/updates/.
  • -
  • Jede Ausführung wird in app_updates dokumentiert.
  • -
  • Dasselbe Verfahren kann lokal auch per php scripts/run-updates.php laufen.
  • -
-
-
-
-

Update-Protokoll

-
- - - - - 'success', - 'failed' => 'error', - 'running' => 'warning', - default => 'neutral', - }; - ?> - - - - - - - - - -
UpdateStatusBeschreibungAusgeführtDurch
-
-
- -
-
Migrations-Center
-

Datenbank-Migrationen zentral prüfen und ausführen.

-

Die SQL-Migrationen aus database/migrations/ können hier nachvollziehbar über die zentrale Verwaltung eingespielt werden.

-
-
-
-
-

Schema-Stand

-
-

Offene Migrationen

-

Erfolgreich

-

Fehlgeschlagen

-
-
-
-

Migration-Ausführung

-

Vorhandene Tabellen werden automatisch als bestehender Stand übernommen. Neue Migrationen werden nur einmal ausgeführt und protokolliert.

-
- - - -
-
-
-

Hinweise

-
    -
  • Migrationen liegen unter saas-app/database/migrations/.
  • -
  • Die Weboberfläche führt nur fehlende Migrationen aus.
  • -
  • Bereits vorhandene Zieltabellen werden als Baseline protokolliert.
  • -
-
-
-
-

Migrations-Protokoll

-
- - - - - 'success', - 'baselined' => 'success', - 'failed' => 'error', - 'running' => 'warning', - default => 'neutral', - }; - $label = match ($status) { - 'pending' => 'Offen', - 'baselined' => 'Baseline', - default => ucfirst($status), - }; - ?> - - - - - - - - - -
MigrationStatusZieltabellenAusgeführtDurch
- - - - -
-
-
- - -
+
+

Ablauf

+

So ist der Zugang gedacht

+
+
+

1. Globalen Zugang verwenden

+

Die Anmeldung prüft gezielt Plattform-Admins und bleibt vom normalen Mitglieder-Login getrennt.

+
+
+

2. Portfolio öffnen

+

Nach dem Login stehen Übersicht, Mandanten-Verwaltung, Updates und Migrationen zentral bereit.

+
+
+

3. Betrieb steuern

+

Mandanten wechseln, Lizenzen anpassen und Systemläufe direkt in der Oberfläche ausführen.

+
+
+
+ Der erste Global-Admin wird im Installer angelegt oder aktualisiert. Grundlage bleibt + users.is_platform_admin = 1 plus das gespeicherte Passwort. +
+
+ + +
+
+

Einrichtung

+

Was vorher bereitstehen sollte

+
    +
  • + Datenbank erreichbar
    + Die Admin-Oberfläche prüft zentrale Tabellen und den Plattform-Admin gegen dieselbe Zielumgebung. +
  • +
  • + Installer gelaufen
    + Der erste Zugang wird über den Installer vorbereitet und kann dort später auch aktualisiert werden. +
  • +
+
+ +
+

Trennung

+

Bewusst eigener Admin-Bereich

+
+ Kein Mischzugang + Globale Betriebsaufgaben bleiben von den täglichen Mitglieder- und Tenant-Abläufen getrennt. +
+
+ +
+

Systemstand

+

Aktuell bereitgestellt

+
+
+

Version

+
+

Aktueller Anwendungsstand.

+
+
+

Bereiche

+
4
+

Übersicht, Mandanten, Updates und Migrationen stehen nach dem Login bereit.

+
+
+
+
+ + +
+ +
+

+
+

+
+ +
+ + +
+
+

Sitzung

+

Angemeldet als

+
+
+

Global-Admin

+
+

+
+
+

Version

+
+

Bereitgestellter Stand der Anwendung.

+
+
+
+ + + +
+

Systemlage

+

Was gerade wichtig ist

+
+
+

Updates

+

offen, fehlgeschlagen, erfolgreich.

+
+
+

Migrationen

+

offen, fehlgeschlagen, erfolgreich.

+
+
+

Mandantenzugriff

+

Als Global-Admin kannst du jeden Mandanten öffnen und operative Pfade direkt prüfen.

+
+
+
+
+ +
+
+

Pflege

+

+
+ + + + + + + + +
+ +
+ Die Lizenzpläne sind noch nicht verfügbar. Bitte zuerst die System-Updates ausführen. +
+ +
+ +
+

Lizenzrahmen

+

Wie die Pläne gedacht sind

+
+
+
F
+
+

Free

+

Bis zu 10 aktive Mitglieder inklusive Mandanten-Einstellungen, PDF-Listen und Papier-Nacherfassung.

+
+
+
+
S
+
+

Starter & Team

+

Mehr Mitglieder für wachsende Standorte, weiterhin mit dem Drucklisten-Prozess als Kernfunktion.

+
+
+
+
B
+
+

Business & Enterprise

+

Zusätzliche Erweiterungen wie SSO, Benachrichtigungen, Auswertungen und individuelle Freischaltungen.

+
+
+
+
+
+ +
+
+
+

Portfolio

+

Vorhandene Mandanten

+
+ sichtbar +
+
+ + + + + + + + + + + + + + + + + + + + + 'Aktiv', + 'sandbox' => 'Sandbox', + default => 'Inaktiv', + }; + $tenantTone = match ($tenantStatus) { + 'active' => 'success', + 'sandbox' => 'warning', + default => 'neutral', + }; + ?> + + + + + + + + + + + + +
NameKeyStatusLizenzMitgliederAdminsSSOAktionen
Noch keine Mandanten vorhanden.
+ + + +
+ Bearbeiten +
+ + + + +
+
+
+
+
+ +
+
+

Stand der Anwendung

+

Aktueller Update-Status

+
+
+

Version

+
+

Bereitgestellter Stand der Anwendung.

+
+
+

Offene Updates

+
+

Warten auf Ausführung.

+
+
+
+ +
+

Ausführung

+

Updates direkt anstoßen

+

Updates laufen idempotent. Bereits erfolgreiche Updates werden übersprungen und bleiben im Protokoll sichtbar.

+
+ + + +
+
+ Web-Ausführung + Derselbe Prozess kann lokal weiterhin per php scripts/run-updates.php laufen. +
+
+ +
+

Betriebsmodell

+

Was dabei protokolliert wird

+
+
+

Quelle

+

Updates liegen versioniert unter saas-app/updates/.

+
+
+

Protokoll

+

Jede Ausführung wird in app_updates dokumentiert.

+
+
+

Verhalten

+

Erfolgreiche Einträge bleiben sichtbar und werden nicht erneut ausgeführt.

+
+
+
+
+ +
+
+
+

Protokoll

+

Update-Laufhistorie

+
+ Einträge +
+
+ + + + + + + + + + + + + + + + + + 'success', + 'failed' => 'error', + 'running' => 'warning', + default => 'neutral', + }; + $label = match ($status) { + 'pending' => 'Offen', + 'running' => 'Läuft', + 'failed' => 'Fehler', + default => ucfirst($status), + }; + ?> + + + + + + + + + +
UpdateStatusBeschreibungAusgeführtDurch
Aktuell liegen keine Update-Einträge vor.
+ + + + + + + +
+
+
+ +
+
+

Schema-Stand

+

Aktueller Migrationsstatus

+
+
+

Offene Migrationen

+
+

Noch nicht eingespielt.

+
+
+

Erfolgreich

+
+

Bereits protokolliert.

+
+
+
+ +
+

Ausführung

+

Migrationen direkt anstoßen

+

Vorhandene Tabellen werden automatisch als bestehender Stand übernommen. Neue Migrationen werden nur einmal ausgeführt und protokolliert.

+
+ + + +
+
+ Baseline inklusive + Bereits vorhandene Zieltabellen werden als Baseline protokolliert statt doppelt angelegt. +
+
+ +
+

Hinweise

+

Wie der Ablauf gedacht ist

+
+
+

Quelle

+

Migrationen liegen unter saas-app/database/migrations/.

+
+
+

Verhalten

+

Die Weboberfläche führt nur fehlende Migrationen aus.

+
+
+

Dokumentation

+

Baseline, Fehler und erfolgreiche Läufe bleiben in der Historie nachvollziehbar.

+
+
+
+
+ +
+
+
+

Protokoll

+

Migrations-Historie

+
+ Einträge +
+
+ + + + + + + + + + + + + + + + + + 'success', + 'baselined' => 'success', + 'failed' => 'error', + 'running' => 'warning', + default => 'neutral', + }; + $label = match ($status) { + 'pending' => 'Offen', + 'baselined' => 'Baseline', + 'running' => 'Läuft', + 'failed' => 'Fehler', + default => ucfirst($status), + }; + ?> + + + + + + + + + +
MigrationStatusZieltabellenAusgeführtDurch
Aktuell liegen keine Migrations-Einträge vor.
+ + + + + + + + +
+
+
+ +
+ + +