repair
This commit is contained in:
70
Umsetzung Neue UI/01_ZIELBILD_DESKTOP_UI.md
Normal file
70
Umsetzung Neue UI/01_ZIELBILD_DESKTOP_UI.md
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# Zielbild Desktop UI
|
||||||
|
|
||||||
|
## Produktidee
|
||||||
|
|
||||||
|
Die neue Oberfläche soll sich wie ein Desktop-System verhalten, nicht wie eine klassische Admin-Webseite.
|
||||||
|
|
||||||
|
Die Oberfläche besteht aus:
|
||||||
|
|
||||||
|
- Desktop-Fläche
|
||||||
|
- frei platzierbaren App-Icons
|
||||||
|
- Fenster-Manager
|
||||||
|
- Statusleiste oder Dock
|
||||||
|
- Startmenü oder Hauptmenü
|
||||||
|
- Mini-Widget-Bereich
|
||||||
|
- Skin-System
|
||||||
|
|
||||||
|
## Bedienmodell
|
||||||
|
|
||||||
|
- Root `/` ist immer die Desktop-Oberfläche
|
||||||
|
- Apps werden als Fenster geöffnet
|
||||||
|
- Widgets können auf dem Desktop oder in einer Leiste erscheinen
|
||||||
|
- persönliche Startseite ist immer das persönliche Desktop-Dashboard
|
||||||
|
- für nicht eingeloggte Nutzer kann ein öffentliches Desktop-Home angezeigt werden
|
||||||
|
|
||||||
|
## Skins
|
||||||
|
|
||||||
|
Es gibt zunächst drei Skins:
|
||||||
|
|
||||||
|
- `Windows`
|
||||||
|
- `Apple`
|
||||||
|
- `Linux`
|
||||||
|
|
||||||
|
Wichtig:
|
||||||
|
|
||||||
|
- Das sind Skins, keine drei getrennten Implementierungen
|
||||||
|
- Verhalten und Optik sollen sich an echten Desktop-Systemen orientieren
|
||||||
|
- die technische Basis bleibt aber eine gemeinsame `Desktop Shell`
|
||||||
|
|
||||||
|
## Kernbausteine
|
||||||
|
|
||||||
|
- `Desktop Shell`
|
||||||
|
- `Window Manager`
|
||||||
|
- `Dock oder Taskbar`
|
||||||
|
- `System Tray`
|
||||||
|
- `Widget Zones`
|
||||||
|
- `App Registry`
|
||||||
|
- `Theme and Skin Engine`
|
||||||
|
- `Desktop Settings`
|
||||||
|
|
||||||
|
## Öffentliche und persönliche Nutzung
|
||||||
|
|
||||||
|
- Admin kann ein globales öffentliches Desktop-Home-Dashboard anlegen
|
||||||
|
- eingeloggte Nutzer sehen ihren persönlichen Desktop
|
||||||
|
- Nutzer können mehrere persönliche Dashboards oder Workspaces haben
|
||||||
|
|
||||||
|
## Inhalte
|
||||||
|
|
||||||
|
Der Desktop soll langfristig enthalten können:
|
||||||
|
|
||||||
|
- klassische Nexus-Module
|
||||||
|
- Links
|
||||||
|
- eingebettete Webseiten
|
||||||
|
- Apps
|
||||||
|
- globale Widgets
|
||||||
|
- persönliche Linklisten
|
||||||
|
- spätere Integrationsdaten per API
|
||||||
|
|
||||||
|
## Technische Leitidee
|
||||||
|
|
||||||
|
Nicht das alte Nexus-Layout erweitern, sondern eine neue Frontend- und UX-Schicht bauen, die bestehende Kernlogik später konsumiert.
|
||||||
87
Umsetzung Neue UI/02_ORDNERSTRUKTUR_UND_GRUNDREGELN.md
Normal file
87
Umsetzung Neue UI/02_ORDNERSTRUKTUR_UND_GRUNDREGELN.md
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
# Ordnerstruktur und Grundregeln
|
||||||
|
|
||||||
|
## Grundsatz
|
||||||
|
|
||||||
|
Die Ordnerstruktur soll sich so nah wie sinnvoll an der bestehenden Nexus-Struktur orientieren.
|
||||||
|
|
||||||
|
## Beibehaltene Strukturidee
|
||||||
|
|
||||||
|
- `/public/` -> Web Root, globale Assets und Einstieg
|
||||||
|
- `/api/` -> Backend- und API-Endpunkte
|
||||||
|
- `/src/` -> Kernlogik, Services, Utilities
|
||||||
|
- `/config/` -> Umgebungs-Configs
|
||||||
|
- `/modules/<modul>/` -> klassische Module
|
||||||
|
- `/partials/structure/` -> globale Layout-Bausteine
|
||||||
|
- `/partials/landingpages/` -> Seiten oder Views
|
||||||
|
- `/tools/` -> Worker, CLI, Hilfstools
|
||||||
|
- `/debug/` -> Debug-Ausgaben
|
||||||
|
|
||||||
|
## Neue zusätzliche Bereiche für die Desktop-UI
|
||||||
|
|
||||||
|
Empfohlene Ergänzungen:
|
||||||
|
|
||||||
|
- `/src/Desktop/`
|
||||||
|
- Window Manager
|
||||||
|
- Desktop Registry
|
||||||
|
- Skin Resolver
|
||||||
|
- Widget Layout Engine
|
||||||
|
- `/public/assets/desktop/`
|
||||||
|
- globale Desktop-CSS
|
||||||
|
- JavaScript für Fenster, Dock, Tray, Desktop-Interaktion
|
||||||
|
- `/partials/desktop/`
|
||||||
|
- Desktop Shell
|
||||||
|
- Window Templates
|
||||||
|
- Dock
|
||||||
|
- Tray
|
||||||
|
- Menu
|
||||||
|
|
||||||
|
Optional für die Übergangsphase:
|
||||||
|
|
||||||
|
- `/Old-Nexus/`
|
||||||
|
- komplette Altbasis zur Sichtprüfung und als Entwicklungserinnerung
|
||||||
|
- nur temporär
|
||||||
|
|
||||||
|
## Wichtige Regel
|
||||||
|
|
||||||
|
Die klassische Modulstruktur bleibt erhalten.
|
||||||
|
|
||||||
|
Das bedeutet:
|
||||||
|
|
||||||
|
- Module bleiben unter `/modules/<modul>/`
|
||||||
|
- der neue Desktop-Layer ist nur die neue Oberfläche
|
||||||
|
- Module dürfen nicht ungeordnet in den Desktop-Core verschoben werden
|
||||||
|
- gemeinsame Desktop-Mechaniken liegen nicht in Modulen, sondern im globalen Kern
|
||||||
|
|
||||||
|
## Trennung
|
||||||
|
|
||||||
|
Es gibt drei Ebenen:
|
||||||
|
|
||||||
|
1. globales System
|
||||||
|
2. Desktop-UI-Schicht
|
||||||
|
3. klassische Module
|
||||||
|
|
||||||
|
## Was nicht passieren soll
|
||||||
|
|
||||||
|
- keine Vermischung von Fenster-Manager-Code mit Modulbusinesslogik
|
||||||
|
- keine Skin-spezifischen Sonderlösungen in einzelnen Modulen
|
||||||
|
- keine harte Kopplung zwischen alter Seitenstruktur und neuem Desktop-Verhalten
|
||||||
|
- keine technische Abhängigkeit zu `Old-Nexus/`
|
||||||
|
- keine Includes, Imports, Autoloading-Pfade oder Assets aus `Old-Nexus/`
|
||||||
|
|
||||||
|
## Architekturregel
|
||||||
|
|
||||||
|
Die neue Oberfläche muss so gebaut sein, dass:
|
||||||
|
|
||||||
|
- Module später als Fenster gerendert werden können
|
||||||
|
- Apps, Widgets und Seitenmodule aus einer gemeinsamen Registry kommen
|
||||||
|
- Skins ausschließlich Layout, Stil und Interaktionsdetails definieren
|
||||||
|
|
||||||
|
## Sonderregel für `Old-Nexus/`
|
||||||
|
|
||||||
|
Wenn `Old-Nexus/` im neuen Projekt vorhanden ist, dann gilt verbindlich:
|
||||||
|
|
||||||
|
- nur lesen und vergleichen
|
||||||
|
- niemals direkt einbinden
|
||||||
|
- niemals als Referenzpfad im Produktivcode verwenden
|
||||||
|
- niemals als Dauerbestandteil der neuen Architektur einplanen
|
||||||
|
- nach Abschluss der Umsetzung wieder entfernen
|
||||||
81
Umsetzung Neue UI/03_MIGRATION_BESTEHENDE_MODULE.md
Normal file
81
Umsetzung Neue UI/03_MIGRATION_BESTEHENDE_MODULE.md
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# Migration bestehende Module
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
Die bestehenden Module aus dem alten Nexus sollen als Basis in `desktop.kusche.berlin` verfügbar sein, damit sie dort später in die neue Oberfläche überführt werden können.
|
||||||
|
|
||||||
|
## Wichtige Regel
|
||||||
|
|
||||||
|
Die Übernahme erfolgt zweistufig:
|
||||||
|
|
||||||
|
1. Rohkopie als Referenzbasis
|
||||||
|
2. anschließende separate Anpassung im neuen Projekt
|
||||||
|
|
||||||
|
## Empfohlener Zielordner im neuen Projekt
|
||||||
|
|
||||||
|
- `temp/nexus-module-import/`
|
||||||
|
|
||||||
|
## Was kopiert werden soll
|
||||||
|
|
||||||
|
Mindestens:
|
||||||
|
|
||||||
|
- `/modules/`
|
||||||
|
- relevante globale Dokumentationsdateien
|
||||||
|
- gegebenenfalls Referenzdateien aus `/src/`, wenn Modul-Helfer benötigt werden
|
||||||
|
|
||||||
|
Zusätzlich möglich:
|
||||||
|
|
||||||
|
- kompletter Altstand unter `Old-Nexus/`
|
||||||
|
|
||||||
|
## Was zunächst nicht aktiv umgebaut werden soll
|
||||||
|
|
||||||
|
- keine direkten Eingriffe in das alte Nexus-Projekt
|
||||||
|
- keine halb fertige Mischform aus alter UI und neuer Desktop-UI
|
||||||
|
- keine automatische Massenmigration ohne Sichtprüfung pro Modul
|
||||||
|
- keine technische Nutzung von `Old-Nexus/` im neuen Produktivcode
|
||||||
|
|
||||||
|
## Ziel nach dem Kopieren
|
||||||
|
|
||||||
|
Im neuen Projekt gibt es:
|
||||||
|
|
||||||
|
- die neue Desktop-Shell
|
||||||
|
- die importierten Module als Rohbasis
|
||||||
|
- optional `Old-Nexus/` als reine Sicht- und Erinnerungsbasis
|
||||||
|
- eine schrittweise Anbindung pro Modul an das neue Fenstersystem
|
||||||
|
|
||||||
|
## Empfohlener Migrationsablauf je Modul
|
||||||
|
|
||||||
|
1. Modul aus Import-Basis prüfen
|
||||||
|
2. benötigte Assets und Seiten identifizieren
|
||||||
|
3. Modul in neue App-Registry eintragen
|
||||||
|
4. Modul als Desktop-App definieren
|
||||||
|
5. Modulansichten in Fensterlogik integrieren
|
||||||
|
6. Skin-Verhalten testen
|
||||||
|
|
||||||
|
## Wichtig für spätere Umsetzung
|
||||||
|
|
||||||
|
Module werden nicht einfach als alte Seite verlinkt, sondern:
|
||||||
|
|
||||||
|
- als App registriert
|
||||||
|
- im Desktop geöffnet
|
||||||
|
- mit Fenstertitel, Icon, Startverhalten und optionalen Widget-Anknüpfungen beschrieben
|
||||||
|
|
||||||
|
Wenn `Old-Nexus/` vorhanden ist:
|
||||||
|
|
||||||
|
- nur zum Nachschlagen alter Lösungswege verwenden
|
||||||
|
- keine Pfadabhängigkeit darauf erzeugen
|
||||||
|
- nichts daraus zur Laufzeit laden
|
||||||
|
- nichts daraus direkt includen oder importieren
|
||||||
|
|
||||||
|
## Mögliche App-Metadaten je Modul
|
||||||
|
|
||||||
|
- `app_id`
|
||||||
|
- `title`
|
||||||
|
- `icon`
|
||||||
|
- `entry_route`
|
||||||
|
- `window_mode`
|
||||||
|
- `default_width`
|
||||||
|
- `default_height`
|
||||||
|
- `supports_widget`
|
||||||
|
- `supports_tray`
|
||||||
|
- `module_name`
|
||||||
75
Umsetzung Neue UI/04_UMSETZUNGSPLAN_V1.md
Normal file
75
Umsetzung Neue UI/04_UMSETZUNGSPLAN_V1.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Umsetzungsplan V1
|
||||||
|
|
||||||
|
## Phase 1: Fundament
|
||||||
|
|
||||||
|
- neues Projekt technisch vorbereiten
|
||||||
|
- bestehende Ordnerstruktur anlegen
|
||||||
|
- Desktop Shell als Root-Oberfläche bauen
|
||||||
|
- Skin-System mit `Windows`, `Apple`, `Linux` vorbereiten
|
||||||
|
- Keycloak-Anbindung einhängen
|
||||||
|
|
||||||
|
## Phase 2: Desktop-Grundfunktionen
|
||||||
|
|
||||||
|
- Desktop-Hintergrund
|
||||||
|
- App-Icons
|
||||||
|
- frei verschiebbare Icons
|
||||||
|
- Dock oder Taskbar
|
||||||
|
- Statusbereich
|
||||||
|
- Uhr
|
||||||
|
- erstes Hauptmenü
|
||||||
|
|
||||||
|
## Phase 3: Fenster-Manager
|
||||||
|
|
||||||
|
- Fenster öffnen und schließen
|
||||||
|
- Fenster fokussieren
|
||||||
|
- Fenster minimieren
|
||||||
|
- Fenster maximieren
|
||||||
|
- z-index-Verwaltung
|
||||||
|
- Position und Größe merken
|
||||||
|
|
||||||
|
## Phase 4: Inhaltssystem
|
||||||
|
|
||||||
|
- App Registry
|
||||||
|
- Widget Registry
|
||||||
|
- Seitenmodule
|
||||||
|
- persönliche Linklisten
|
||||||
|
- öffentliches Home-Dashboard
|
||||||
|
- persönliche Workspaces
|
||||||
|
|
||||||
|
## Phase 5: Admin-Bereiche
|
||||||
|
|
||||||
|
- globale Einstellungen
|
||||||
|
- Widget-Verwaltung
|
||||||
|
- Integrationen
|
||||||
|
- Suchmaschinen
|
||||||
|
- Apps
|
||||||
|
- öffentliches Home-Dashboard
|
||||||
|
|
||||||
|
## Phase 6: Modul-Anbindung
|
||||||
|
|
||||||
|
- importierte Nexus-Module sichten
|
||||||
|
- erste Module als Apps in der Desktop-Shell öffnen
|
||||||
|
- Fenstertauglichkeit je Modul prüfen
|
||||||
|
- langfristig modulweise an neues UX-Modell anpassen
|
||||||
|
|
||||||
|
## V1-Minimalziel
|
||||||
|
|
||||||
|
V1 ist erreicht, wenn:
|
||||||
|
|
||||||
|
- Root die Desktop-Oberfläche ist
|
||||||
|
- Login vorhanden ist
|
||||||
|
- Desktop-Skins umschaltbar sind
|
||||||
|
- Apps als Fenster geöffnet werden können
|
||||||
|
- Admin globale Apps, Widgets, Integrationen und Suchmaschinen verwalten kann
|
||||||
|
- mindestens ein persönlicher Desktop pro Nutzer funktioniert
|
||||||
|
- ein öffentliches Home-Dashboard existiert
|
||||||
|
|
||||||
|
## Spätere Ausbaustufen
|
||||||
|
|
||||||
|
- echte API-Datenquellen für Widgets
|
||||||
|
- Benachrichtigungen
|
||||||
|
- Kontextmenüs
|
||||||
|
- Multi-Workspace
|
||||||
|
- Drag-and-drop Widget-Layout
|
||||||
|
- Desktop-Shortcuts
|
||||||
|
- Datei- oder Objektverwaltung
|
||||||
48
Umsetzung Neue UI/05_KEYCLOAK_LOGIN_UND_DESKTOP_LOGIN.md
Normal file
48
Umsetzung Neue UI/05_KEYCLOAK_LOGIN_UND_DESKTOP_LOGIN.md
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Keycloak Login und Desktop Login
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
Nexus beziehungsweise `desktop.kusche.berlin` soll einen eigenen Login-Screen erhalten, der optisch wie ein Desktop-Login wirkt.
|
||||||
|
|
||||||
|
## Technische Grundlage
|
||||||
|
|
||||||
|
Keycloak bleibt weiterhin das Auth-System.
|
||||||
|
|
||||||
|
Für `desktop.kusche.berlin` soll aber ein eigenes Keycloak-Theme verwendet werden.
|
||||||
|
|
||||||
|
## Wichtige Leitlinie
|
||||||
|
|
||||||
|
- technisch bleibt der Login ein Keycloak-Login
|
||||||
|
- optisch wird er als eigenständiger Desktop-Login gebrandet
|
||||||
|
- das Theme soll nur für diese Anwendung gelten
|
||||||
|
|
||||||
|
## Zieloptik
|
||||||
|
|
||||||
|
Der Login darf sich an Desktop-Systemen orientieren:
|
||||||
|
|
||||||
|
- Hintergrundbild oder Wallpaper
|
||||||
|
- zentrierte Login-Kachel
|
||||||
|
- Benutzerwahl oder Benutzeranzeige
|
||||||
|
- große Uhr oder Statusanzeige
|
||||||
|
- Desktop-artige Übergänge
|
||||||
|
|
||||||
|
## Was im neuen Projekt vorbereitet werden soll
|
||||||
|
|
||||||
|
- Branding-Farben
|
||||||
|
- Logos
|
||||||
|
- Desktop-Login-Konzept
|
||||||
|
- Übergabepunkte für Keycloak-Theme
|
||||||
|
- Beschreibung der gewünschten UX
|
||||||
|
|
||||||
|
## Was später am Keycloak-System zu tun ist
|
||||||
|
|
||||||
|
- eigenes Login-Theme anlegen
|
||||||
|
- Theme dem Nexus-Client oder Realm zuordnen
|
||||||
|
- Templates, CSS und Assets anpassen
|
||||||
|
- Desktop-Login visuell mit der Shell abstimmen
|
||||||
|
|
||||||
|
## Wichtig
|
||||||
|
|
||||||
|
Das Login-Theme gehört technisch nicht in die normale Desktop-Shell, sondern in das Keycloak-Theme-System.
|
||||||
|
|
||||||
|
Trotzdem soll es gestalterisch so wirken, als gehöre es direkt zu `desktop.kusche.berlin`.
|
||||||
44
Umsetzung Neue UI/06_STARTPROMPT_NEUE_SESSION.md
Normal file
44
Umsetzung Neue UI/06_STARTPROMPT_NEUE_SESSION.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Startprompt für neue Session
|
||||||
|
|
||||||
|
Nutze den folgenden Prompt in der neuen Session im Projekt `desktop.kusche.berlin`.
|
||||||
|
|
||||||
|
```text
|
||||||
|
Bitte arbeite ausschließlich im neuen Projekt `desktop.kusche.berlin`.
|
||||||
|
|
||||||
|
Wichtige Einstiegsdatei:
|
||||||
|
- `START_HIER.md`
|
||||||
|
|
||||||
|
Lies danach in dieser Reihenfolge:
|
||||||
|
- `01_ZIELBILD_DESKTOP_UI.md`
|
||||||
|
- `02_ORDNERSTRUKTUR_UND_GRUNDREGELN.md`
|
||||||
|
- `03_MIGRATION_BESTEHENDE_MODULE.md`
|
||||||
|
- `04_UMSETZUNGSPLAN_V1.md`
|
||||||
|
- `05_KEYCLOAK_LOGIN_UND_DESKTOP_LOGIN.md`
|
||||||
|
|
||||||
|
Rahmenbedingungen:
|
||||||
|
- Die bestehende Ordnerstruktur soll sich an Nexus orientieren.
|
||||||
|
- Die neuen Dateien im Projekt beschreiben das Zielbild verbindlich.
|
||||||
|
- Die Umsetzung erfolgt ausschließlich im neuen Projekt.
|
||||||
|
- Die bestehenden Nexus-Module sollen als Basis aus einer Import-Struktur verfügbar gemacht werden.
|
||||||
|
- Falls ein Ordner `Old-Nexus/` vorhanden ist, dient er ausschließlich als menschliche Referenz und Erinnerung an das alte System.
|
||||||
|
- `Old-Nexus/` darf niemals technisch eingebunden, importiert, included oder als Asset-/Code-Referenz verwendet werden.
|
||||||
|
- Die eigentliche Anpassung der Module erfolgt danach separat im neuen Projekt.
|
||||||
|
- Die neue Oberfläche ist eine Desktop-Shell, keine klassische Website.
|
||||||
|
- Root `/` soll die Desktop-Oberfläche sein.
|
||||||
|
- Skins sollen als `Windows`, `Apple`, `Linux` angelegt werden, technisch aber auf einer gemeinsamen Shell beruhen.
|
||||||
|
- Spätere Modul-Anbindung muss vorbereitet werden, aber die Shell ist zuerst zu bauen.
|
||||||
|
|
||||||
|
Erste Aufgabe:
|
||||||
|
1. Projektstruktur im neuen Projekt prüfen.
|
||||||
|
2. Falls nötig die Zielstruktur anlegen.
|
||||||
|
3. Eine V1-Desktop-Shell scaffolden.
|
||||||
|
4. Skin-System vorbereiten.
|
||||||
|
5. Fenster-Manager, Dock oder Taskbar und Desktop-Icons als Kern aufsetzen.
|
||||||
|
6. Danach die Import-Basis der alten Module in `temp/nexus-module-import/` vorbereiten.
|
||||||
|
|
||||||
|
Wichtig:
|
||||||
|
- keine Arbeiten mehr im alten Nexus durchführen
|
||||||
|
- keine Modulmigration im Blindflug
|
||||||
|
- keine Vermischung von alter Website-Navigation und neuer Desktop-Interaktion
|
||||||
|
- `Old-Nexus/` nur lesen, nie technisch verwenden
|
||||||
|
```
|
||||||
62
Umsetzung Neue UI/START_HIER.md
Normal file
62
Umsetzung Neue UI/START_HIER.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Start Hier
|
||||||
|
|
||||||
|
Diese Datei ist der Einstieg für die Umsetzung der neuen Desktop-Oberfläche in `desktop.kusche.berlin`.
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
Nexus soll als neue Oberfläche nicht mehr wie eine klassische Website aufgebaut sein, sondern wie ein Desktop-System:
|
||||||
|
|
||||||
|
- Desktop-Shell als Hauptoberfläche
|
||||||
|
- Fenster für Apps und Widgets
|
||||||
|
- Skin-System für `Windows`, `Apple`, `Linux`
|
||||||
|
- persönliche Dashboards
|
||||||
|
- öffentliches Home-Dashboard für nicht eingeloggte Nutzer
|
||||||
|
- globale Verwaltung für Widgets, Integrationen, Suchmaschinen und Apps
|
||||||
|
|
||||||
|
Die bestehenden klassischen Module aus Nexus sollen später in diese neue Oberfläche überführt werden, aber die Umsetzung erfolgt ausschließlich im neuen Projekt.
|
||||||
|
|
||||||
|
## Reihenfolge der Dokumente
|
||||||
|
|
||||||
|
Bitte diese Dateien in genau dieser Reihenfolge lesen:
|
||||||
|
|
||||||
|
1. `START_HIER.md`
|
||||||
|
2. `01_ZIELBILD_DESKTOP_UI.md`
|
||||||
|
3. `02_ORDNERSTRUKTUR_UND_GRUNDREGELN.md`
|
||||||
|
4. `03_MIGRATION_BESTEHENDE_MODULE.md`
|
||||||
|
5. `04_UMSETZUNGSPLAN_V1.md`
|
||||||
|
6. `05_KEYCLOAK_LOGIN_UND_DESKTOP_LOGIN.md`
|
||||||
|
7. `06_STARTPROMPT_NEUE_SESSION.md`
|
||||||
|
|
||||||
|
## Wichtig
|
||||||
|
|
||||||
|
- Die bestehende Ordnerlogik aus Nexus soll grundsätzlich beibehalten werden.
|
||||||
|
- Die Umsetzung erfolgt **nicht** mehr im alten Nexus-Projekt.
|
||||||
|
- Die bestehenden Module aus Nexus dienen als Basis und Referenz, sollen aber in `desktop.kusche.berlin` separat weiterentwickelt werden.
|
||||||
|
- Der neue UI-Layer ist eine neue Anwendungsschicht, kein Theme-Umbau des alten Systems.
|
||||||
|
|
||||||
|
## Erwartetes Vorgehen im neuen Projekt
|
||||||
|
|
||||||
|
- zuerst Architektur und Shell anlegen
|
||||||
|
- dann Desktop-Grundsystem bauen
|
||||||
|
- dann globale Verwaltungsseiten
|
||||||
|
- dann klassische Module schrittweise in die neue Shell einhängen
|
||||||
|
|
||||||
|
## Basisübernahme aus Nexus
|
||||||
|
|
||||||
|
Im neuen Projekt sollte ein temporärer Import-Ordner angelegt werden, zum Beispiel:
|
||||||
|
|
||||||
|
- `temp/nexus-module-import/`
|
||||||
|
|
||||||
|
Dorthin werden die bestehenden Module aus Nexus zunächst nur kopiert, damit die Basis verfügbar ist. Die eigentliche Anpassung erfolgt danach separat im neuen Projekt.
|
||||||
|
|
||||||
|
## Old-Nexus
|
||||||
|
|
||||||
|
Zusätzlich kann im neuen Projekt ein Ordner `Old-Nexus/` liegen, in dem das alte System vollständig enthalten ist.
|
||||||
|
|
||||||
|
Wichtige Regel:
|
||||||
|
|
||||||
|
- `Old-Nexus/` dient ausschließlich als menschliche Referenz und Erinnerung an die alte Entwicklung
|
||||||
|
- dort dürfen Beispiele, frühere Funktionen, Strukturen oder Hilfslogik nachgesehen werden
|
||||||
|
- `Old-Nexus/` darf aber niemals als technische Laufzeit- oder Build-Abhängigkeit verwendet werden
|
||||||
|
- es dürfen keine Includes, keine Imports, keine Asset-Referenzen, keine Pfadverweise und keine direkte Code-Nutzung auf `Old-Nexus/` zeigen
|
||||||
|
- der Ordner ist nur temporär und wird nach der Umsetzung wieder gelöscht
|
||||||
@@ -259,8 +259,8 @@
|
|||||||
const requestOptions = options && typeof options === 'object' ? { ...options } : {};
|
const requestOptions = options && typeof options === 'object' ? { ...options } : {};
|
||||||
const debugEnabled = !!debugBus.enabled;
|
const debugEnabled = !!debugBus.enabled;
|
||||||
const timeoutMs = typeof requestOptions.timeoutMs === 'number'
|
const timeoutMs = typeof requestOptions.timeoutMs === 'number'
|
||||||
? (debugEnabled ? Math.max(requestOptions.timeoutMs, 20000) : requestOptions.timeoutMs)
|
? (debugEnabled ? Math.max(requestOptions.timeoutMs, 30000) : requestOptions.timeoutMs)
|
||||||
: (debugEnabled ? 20000 : 8000);
|
: (debugEnabled ? 30000 : 20000);
|
||||||
delete requestOptions.timeoutMs;
|
delete requestOptions.timeoutMs;
|
||||||
|
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
@@ -1203,7 +1203,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadBootstrap(key) {
|
async function loadBootstrap(key, options) {
|
||||||
|
const suppressError = !!(options && options.suppressError);
|
||||||
const cacheKey = `${key}:${activeTab || 'overview'}`;
|
const cacheKey = `${key}:${activeTab || 'overview'}`;
|
||||||
const cachedPayload = bootstrapCacheRef.current.get(cacheKey) || null;
|
const cachedPayload = bootstrapCacheRef.current.get(cacheKey) || null;
|
||||||
|
|
||||||
@@ -1219,18 +1220,20 @@
|
|||||||
loadGuardTriggered = true;
|
loadGuardTriggered = true;
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setPayload((previous) => previous || cachedPayload || normalizeBootstrap(null, key));
|
setPayload((previous) => previous || cachedPayload || normalizeBootstrap(null, key));
|
||||||
setError((previous) => previous || 'Bootstrap-Request haengt oder braucht zu lange.');
|
if (!suppressError) {
|
||||||
}, 12000);
|
setError((previous) => previous || 'Bootstrap-Request haengt oder braucht zu lange.');
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (schemaStatus.missing_count > 0 || schemaStatus.pending_upgrade_count > 0) {
|
if (schemaStatus.missing_count > 0 || schemaStatus.pending_upgrade_count > 0) {
|
||||||
setPayload(normalizeBootstrap(null, key));
|
setPayload(normalizeBootstrap(null, key));
|
||||||
setError('Mining-Checker Schema ist noch nicht initialisiert. Bitte im Tab Settings die Datenbank initialisieren.');
|
setError('Mining-Checker Schema ist noch nicht initialisiert. Bitte im Tab Settings die Datenbank initialisieren.');
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const params = new URLSearchParams({ view: activeTab || 'overview' });
|
const params = new URLSearchParams({ view: activeTab || 'overview' });
|
||||||
const data = await request(`${apiBase}/projects/${encodeURIComponent(key)}/bootstrap?${params.toString()}`, { timeoutMs: 10000 });
|
const data = await request(`${apiBase}/projects/${encodeURIComponent(key)}/bootstrap?${params.toString()}`, { timeoutMs: 25000 });
|
||||||
const normalized = normalizeBootstrap(data, key);
|
const normalized = normalizeBootstrap(data, key);
|
||||||
bootstrapCacheRef.current.set(cacheKey, normalized);
|
bootstrapCacheRef.current.set(cacheKey, normalized);
|
||||||
setPayload(normalized);
|
setPayload(normalized);
|
||||||
@@ -1251,9 +1254,13 @@
|
|||||||
...previous,
|
...previous,
|
||||||
currency: normalized.settings.currencies?.[0]?.code || previous.currency || 'EUR',
|
currency: normalized.settings.currencies?.[0]?.code || previous.currency || 'EUR',
|
||||||
}));
|
}));
|
||||||
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
if (!suppressError) {
|
||||||
|
setError(err.message);
|
||||||
|
}
|
||||||
setPayload(normalizeBootstrap(null, key));
|
setPayload(normalizeBootstrap(null, key));
|
||||||
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
window.clearTimeout(loadGuard);
|
window.clearTimeout(loadGuard);
|
||||||
if (!loadGuardTriggered) {
|
if (!loadGuardTriggered) {
|
||||||
@@ -1262,6 +1269,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function reloadBootstrapAfterMutation(successMessage) {
|
||||||
|
const refreshed = await loadBootstrap(projectKey, { suppressError: true });
|
||||||
|
if (!refreshed) {
|
||||||
|
setError('Speichern war erfolgreich, aber die Ansicht konnte nicht automatisch aktualisiert werden.');
|
||||||
|
if (successMessage) {
|
||||||
|
setMessage(successMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return refreshed;
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadBootstrap(projectKey);
|
loadBootstrap(projectKey);
|
||||||
}, [projectKey, activeTab]);
|
}, [projectKey, activeTab]);
|
||||||
@@ -1415,7 +1433,7 @@
|
|||||||
source: 'manual',
|
source: 'manual',
|
||||||
});
|
});
|
||||||
setOcrPreview(null);
|
setOcrPreview(null);
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation(fromPreview ? 'OCR-Vorschlag bestaetigt und gespeichert.' : 'Messpunkt gespeichert.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1444,7 +1462,7 @@
|
|||||||
});
|
});
|
||||||
setMessage('Wallet-Snapshot gespeichert.');
|
setMessage('Wallet-Snapshot gespeichert.');
|
||||||
setOcrPreview(null);
|
setOcrPreview(null);
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Wallet-Snapshot gespeichert.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1469,7 +1487,7 @@
|
|||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
setMessage('Messpunkt geloescht.');
|
setMessage('Messpunkt geloescht.');
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Messpunkt geloescht.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1500,7 +1518,7 @@
|
|||||||
if (!result.error_count) {
|
if (!result.error_count) {
|
||||||
setImportForm((previous) => ({ ...previous, rows_text: '' }));
|
setImportForm((previous) => ({ ...previous, rows_text: '' }));
|
||||||
}
|
}
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation(`Import abgeschlossen: ${summary}.`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1561,7 +1579,7 @@
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
setMessage('Dashboard gespeichert.');
|
setMessage('Dashboard gespeichert.');
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Dashboard gespeichert.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1590,7 +1608,7 @@
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
setMessage('Settings gespeichert.');
|
setMessage('Settings gespeichert.');
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Settings gespeichert.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1647,7 +1665,7 @@
|
|||||||
setMessage('Ziel gespeichert.');
|
setMessage('Ziel gespeichert.');
|
||||||
setTargetForm({ label: '', target_amount_fiat: '', currency: currencies[0]?.code || 'EUR', miner_offer_id: '', is_active: true, sort_order: 0 });
|
setTargetForm({ label: '', target_amount_fiat: '', currency: currencies[0]?.code || 'EUR', miner_offer_id: '', is_active: true, sort_order: 0 });
|
||||||
setTargetModalOpen(false);
|
setTargetModalOpen(false);
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Ziel gespeichert.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1668,7 +1686,7 @@
|
|||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
setMessage('Ziel geloescht.');
|
setMessage('Ziel geloescht.');
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Ziel geloescht.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1690,7 +1708,7 @@
|
|||||||
body: JSON.stringify({ auto_renew: !row.auto_renew }),
|
body: JSON.stringify({ auto_renew: !row.auto_renew }),
|
||||||
});
|
});
|
||||||
setMessage(`Automatische Verlängerung ${row.auto_renew ? 'deaktiviert' : 'aktiviert'}.`);
|
setMessage(`Automatische Verlängerung ${row.auto_renew ? 'deaktiviert' : 'aktiviert'}.`);
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation(`Automatische Verlaengerung ${row.auto_renew ? 'deaktiviert' : 'aktiviert'}.`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1725,7 +1743,7 @@
|
|||||||
is_active: true,
|
is_active: true,
|
||||||
});
|
});
|
||||||
setCostPlanModalOpen(false);
|
setCostPlanModalOpen(false);
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Miner gespeichert.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1746,7 +1764,7 @@
|
|||||||
setMessage('Auszahlung gespeichert.');
|
setMessage('Auszahlung gespeichert.');
|
||||||
setPayoutForm({ payout_at: '', coins_amount: '', payout_currency: currentSettings.crypto_currency || 'DOGE', note: '' });
|
setPayoutForm({ payout_at: '', coins_amount: '', payout_currency: currentSettings.crypto_currency || 'DOGE', note: '' });
|
||||||
setPayoutModalOpen(false);
|
setPayoutModalOpen(false);
|
||||||
await loadBootstrap(projectKey);
|
await reloadBootstrapAfterMutation('Auszahlung gespeichert.');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message);
|
setError(err.message);
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ final class Router
|
|||||||
{
|
{
|
||||||
private const BOOTSTRAP_MEASUREMENT_LIMIT = 150;
|
private const BOOTSTRAP_MEASUREMENT_LIMIT = 150;
|
||||||
private const BOOTSTRAP_SNAPSHOT_LIMIT = 40;
|
private const BOOTSTRAP_SNAPSHOT_LIMIT = 40;
|
||||||
private const LONG_REQUEST_BUDGET_SECONDS = 8.0;
|
private const LONG_REQUEST_BUDGET_SECONDS = 20.0;
|
||||||
private const OVERVIEW_WINDOW_DAYS = 15;
|
private const OVERVIEW_WINDOW_DAYS = 15;
|
||||||
private const FX_FETCH_MAX_AGE_HOURS = 3.0;
|
private const FX_FETCH_MAX_AGE_HOURS = 3.0;
|
||||||
private const BASE_OFFER_SPEEDS = [
|
private const BASE_OFFER_SPEEDS = [
|
||||||
|
|||||||
Reference in New Issue
Block a user