6.2 KiB
Workflow Editor
n8n-inspirierter Editor zum Erstellen von Aufgabenlisten (Tasks) für die
stadtbote-App. Funktionsblöcke werden per Drag & Drop auf einem Canvas
angeordnet und verbunden; daraus wird das app-konforme tasks-JSON erzeugt.
Funktionen
- Funktionsblöcke für die stadtbote-Task-Typen (Ankunft, Unterschrift, Fotos, Quittungsgeber, Stationshinweis, Kommissionsnummer, Abhol-/Lieferstatus)
- 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
- Drawflow als Canvas-/Node-Editor
Konfiguration
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.
Optionale Einstellungen sind in .env.example beschrieben.
Start
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):
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:
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:
{
"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:
{
"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:
{
"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.