feat: Editor-Aufruf mit Task- und Typenrückgabe statt MongoDB
Tasks, eigene Typen und Metadaten pro Editor-Aufruf laden und an den Aufrufer zurückgeben. MongoDB-Persistenz entfernen und Header auf Rückgängig, Abbrechen und Fertig umstellen. Python-Testserver und Regressionstests ergänzen; Verbindungslinien nach Import und Layoutänderungen neu berechnen.
This commit is contained in:
1 parent
93ba40c476
commit
f979c797ba
39 files changed
+1980
-1140
No files matched your search
@@ -8,27 +8,23 @@ angeordnet und verbunden; daraus wird das app-konforme `tasks`-JSON erzeugt.
|
||||
|
||||
- Funktionsblöcke für die stadtbote-Task-Typen (Ankunft, Unterschrift, Fotos,
|
||||
Quittungsgeber, Stationshinweis, Kommissionsnummer, Abhol-/Lieferstatus)
|
||||
- Erzeugen des app-konformen Task-JSON und Speichern in MongoDB
|
||||
- Speichern und Wiederherstellen des Canvas-Standes in MongoDB
|
||||
- Aufruf per Deep-Link mit Übergabe von Task-Daten als JSON-Body
|
||||
- Erzeugen des app-konformen Task-JSON
|
||||
- Eigene Typen mit konfigurierbaren Vorgaben
|
||||
- Aufruf per Deep-Link mit Übergabe von Tasks, eigenen Typen und Metadaten als JSON-Body
|
||||
- Rückgabe der bearbeiteten Tasks und des vollständigen eigenen Typkatalogs an den Aufrufer
|
||||
|
||||
## Technik
|
||||
|
||||
- Java 21, Spring Boot 3, Vaadin 24
|
||||
- MongoDB (Spring Data) zur Persistenz
|
||||
- Drawflow als Canvas-/Node-Editor
|
||||
|
||||
## Konfiguration
|
||||
|
||||
Zugangsdaten und Collections werden über eine `.env`-Datei gesetzt
|
||||
(Vorlage: `.env.example`):
|
||||
Für den Editor ist keine Datenbank erforderlich. Tasks und eigene Typen werden
|
||||
beim Aufruf übergeben und bei **Fertig** an den Aufrufer zurückgegeben. Der
|
||||
Aufrufer ist für deren dauerhafte Speicherung verantwortlich.
|
||||
|
||||
```
|
||||
MONGODB_URI=mongodb://localhost:27017
|
||||
MONGODB_DATABASE=tasklist_editor
|
||||
MONGODB_COLLECTION=tasks_json
|
||||
MONGODB_CANVAS_COLLECTION=canvas_layouts
|
||||
```
|
||||
Optionale Einstellungen sind in `.env.example` beschrieben.
|
||||
|
||||
## Start
|
||||
|
||||
@@ -37,3 +33,126 @@ mvn spring-boot:run
|
||||
```
|
||||
|
||||
Die Anwendung läuft anschließend unter http://localhost:8080/.
|
||||
|
||||
## Aufruf und Rückgabe mit dem Python-Testserver
|
||||
|
||||
Die Webapp muss mit dem aktuellen Code auf Port 8080 laufen. In einem zweiten
|
||||
Terminal den Testserver starten (Python 3, keine zusätzlichen Pakete):
|
||||
|
||||
```bash
|
||||
python3 tools/editor_test_server.py
|
||||
```
|
||||
|
||||
Der Testserver öffnet seine Aufruferseite unter `http://127.0.0.1:8090`.
|
||||
Dort das Beispiel bearbeiten oder eigenes JSON einfügen und den Editor öffnen.
|
||||
Der Editor erscheint eingebettet in der Seite. **Fertig** gibt die validierten
|
||||
Tasks und den vollständigen Katalog eigener Typen zurück; **Abbrechen** meldet
|
||||
den Abbruch ohne bearbeitete Tasks oder Typen.
|
||||
Beide Ergebnisse werden im Python-Terminal als JSON ausgegeben und auf der
|
||||
Testseite angezeigt. Nach **Fertig** enthält das JSON-Eingabefeld die Rückgabe
|
||||
für den nächsten Editor-Aufruf. **Neue Liste** leert die Tasks und behält den
|
||||
aktuellen eigenen Typkatalog. Nach **Abbrechen** bleibt die Eingabe unverändert.
|
||||
Die Testseite hält diese Daten nur bis zum Neuladen; die Konsolenausgabe bleibt
|
||||
im Terminal verfügbar.
|
||||
|
||||
Eine Datei vorgeben oder andere Ports verwenden:
|
||||
|
||||
```bash
|
||||
python3 tools/editor_test_server.py --json tools/example_tasks.json
|
||||
python3 tools/editor_test_server.py --editor-url http://127.0.0.1:8080 --port 8090 --no-browser
|
||||
```
|
||||
|
||||
Als Eingabe ist ein Task-Array oder ein Objekt erlaubt:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Testauftrag",
|
||||
"tasks": [{ "type": 3, "topic": "Ankunft melden", "track": true }],
|
||||
"customTypes": [],
|
||||
"metadata": { "auftragId": "TEST-4711", "revision": 2 }
|
||||
}
|
||||
```
|
||||
|
||||
Für eine neue Liste `tasks` weglassen oder `[]` übergeben. Die Metadaten werden
|
||||
unverändert zurückgegeben. Zum Abschließen eines neu aufgebauten Workflows
|
||||
müssen Start, Aufgaben und Abschluss vollständig verbunden sein. Beim Import
|
||||
vorhandener Tasks ergänzt der Editor die internen Start-/Abschlussmarkierungen;
|
||||
sie sind nicht Teil des zurückgegebenen Task-Arrays.
|
||||
|
||||
### Eigene Typen
|
||||
|
||||
`customTypes` enthält den vollständigen Katalog für diesen Editor-Aufruf.
|
||||
Ohne dieses Feld oder mit `[]` stehen nur die eingebauten Typen zur Verfügung.
|
||||
Eigene Typen werden vor den Tasks geladen. Ein Task verweist mit `type` auf die
|
||||
`taskType`-Nummer seines eigenen Typs (ab 1000), beispielsweise:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Zustellnachweis",
|
||||
"tasks": [{ "type": 1000, "topic": "Zustellung fotografieren", "min": 1, "max": 3 }],
|
||||
"customTypes": [{
|
||||
"typeId": "custom-1000",
|
||||
"taskType": 1000,
|
||||
"baseTypeId": "fotos-aufnehmen",
|
||||
"label": "Zustellnachweis",
|
||||
"description": "Fotos zur Dokumentation einer Zustellung.",
|
||||
"icon": "vaadin:camera",
|
||||
"color": "#059669",
|
||||
"inputs": 1,
|
||||
"outputs": 1,
|
||||
"properties": [
|
||||
{ "id": "min", "label": "Mindestanzahl Fotos", "type": "NUMBER", "defaultValue": 1 },
|
||||
{ "id": "max", "label": "Maximale Anzahl Fotos", "type": "NUMBER", "defaultValue": 3 },
|
||||
{ "id": "opt", "label": "Optionale Aufgabe", "type": "BOOLEAN", "defaultValue": false },
|
||||
{ "id": "reenter", "label": "Erneut bearbeitbar", "type": "BOOLEAN", "defaultValue": true }
|
||||
]
|
||||
}],
|
||||
"metadata": { "auftragId": "TEST-4711" }
|
||||
}
|
||||
```
|
||||
|
||||
`properties` beschreibt die Eigenschaften samt Vorgabewerten; `type` ist dabei
|
||||
einer der Werte `TEXT`, `TEXTAREA`, `NUMBER`, `BOOLEAN`, `FIELD_LIST`, `NAME_LIST`
|
||||
oder `CHOICE_LIST`. Das mitgelieferte Beispiel `tools/example_tasks.json`
|
||||
enthält einen eigenen Foto-Typ und einen zugehörigen Task.
|
||||
|
||||
Bei **Fertig** wird `customTypes` immer vollständig zurückgegeben, einschließlich
|
||||
unveränderter und neu angelegter Typen. Der Aufrufer ersetzt seinen bisherigen
|
||||
Katalog durch dieses Array, damit auch gelöschte Typen berücksichtigt werden.
|
||||
`[]` bedeutet, dass keine eigenen Typen mehr vorhanden sind. Bei **Abbrechen**
|
||||
übernimmt der Aufrufer keine Änderungen.
|
||||
|
||||
### Übergabeprotokoll
|
||||
|
||||
Die Python-Seite ruft serverseitig `POST /api/editor/import` auf und ergänzt
|
||||
`returnOrigin`, z. B. `http://127.0.0.1:8090`. Die Antwort enthält `token` und
|
||||
`deepLink`. Der Aufrufer öffnet den Deep-Link in einem iframe oder Popup.
|
||||
Der Import bleibt für 30 Minuten im Speicher der Webapp verfügbar, sodass ein
|
||||
Neuladen während dieser Zeit möglich ist.
|
||||
|
||||
Der Editor sendet das Ergebnis per `postMessage` ausschließlich an diese Origin:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "tasklist-editor:result",
|
||||
"token": "<Token aus der Importantwort>",
|
||||
"status": "completed",
|
||||
"name": "Testauftrag",
|
||||
"metadata": { "auftragId": "TEST-4711", "revision": 2 },
|
||||
"tasks": [{ "s_id": 1, "type": 3, "topic": "Ankunft melden", "track": true }],
|
||||
"customTypes": []
|
||||
}
|
||||
```
|
||||
|
||||
Bei Abbruch ist `status` gleich `cancelled`; die Felder `tasks` und `customTypes`
|
||||
entfallen.
|
||||
Die Testseite prüft Absender-Origin, Fenster und Token und leitet das Ergebnis
|
||||
an `POST /api/result` des Python-Servers weiter. Erst nach dessen Bestätigung
|
||||
wird der iframe geschlossen. Ohne `returnOrigin` zeigt der Editor einen
|
||||
schreibgeschützten JSON-Dialog zum Kopieren mit `name`, `metadata`, `tasks`
|
||||
und `customTypes`.
|
||||
|
||||
Der Testserver ist ein lokales Entwicklungswerkzeug und bindet an `127.0.0.1`.
|
||||
Er übernimmt bekannte Task-Felder des Editors; unbekannte Task-Typen werden vom
|
||||
bestehenden Importer übersprungen. Beliebige zusätzliche Daten daher in
|
||||
`metadata` übergeben.
|
||||
Reference in new issue
Block a user