Tasks liste + liste_filtern; MCP: task_list, task_doc, task_search, workflow_lint
This commit is contained in:
@@ -1,5 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-07-08 (Listen-Tasks + MCP-Katalog)
|
||||
|
||||
- **Neu: Task `liste`** — Tabelle direkt im Editor pflegen (freie Spalten, z. B. name/mail/rolle).
|
||||
Ergebnis ist eine Liste aus Zeilen-Objekten: `{{var}}` (loop_foreach), `{{var}}_json`,
|
||||
`{{var}}_anzahl`, `{{var}}_leer` und je Spalte `{{var}}_<spalte>_liste` (fertiger Mail-Verteiler).
|
||||
Zellen dürfen Platzhalter enthalten.
|
||||
- **Neu: Task `liste_filtern`** — Zeilen nach Bedingungen auswählen (`ist`, `enthaelt`, `endet_auf`,
|
||||
`groesser`, `in`, … ; `und`/`oder`). Quelle ist jede Liste (Task `liste`, `person_pick`,
|
||||
`json_transform`, JSON-String oder Komma-Liste). Zusätzlich `{{var}}_entfernt`.
|
||||
- **Editor: neuer Feldtyp `table`** — echtes Zeilenraster, feste oder dynamische Spalten
|
||||
(`columnsFrom`); Kopfzeile zieht nach, wenn `spalten` geändert wird.
|
||||
- **MCP: vier neue Werkzeuge** (token-sparsam entworfen):
|
||||
- `task_list` — alle Task-Typen mit Einzeiler, optional Volltextfilter; `interaktiv=true` markiert
|
||||
Tasks, die `<assign_to>` brauchen.
|
||||
- `task_doc` — Doku zu MEHREREN Tasks in EINEM Aufruf; `format=xml|kurz|md` (≈1/10, 1/3, voll).
|
||||
- `task_search` — findet den passenden Task zu einer Aufgabenbeschreibung.
|
||||
- `workflow_lint` — statische Prüfung: unbekannte Task-Typen, doppelte ids, fehlende
|
||||
Pflichtparameter, interaktive Tasks ohne `<assign_to>`. Fängt ab, was sonst erst beim Start auffällt.
|
||||
|
||||
## 2026-07-08 (Bauakte-Vergabe: Stempelauswahl, Ordnerfilter, Docroot-Fix)
|
||||
|
||||
- **`pdf_stamp_interactive`: Stempelart zur Laufzeit wählbar.** Neue Parameter `stempel_auswahl`
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# `liste` — Tabelle im Editor pflegen
|
||||
|
||||
**Zweck:** Definiert eine feste Liste (Tabelle) direkt im Task-Editor — Spalten frei wählbar, z. B. `name`, `mail`, `rolle`. Das Ergebnis ist eine **Liste im Workflow-Sinn**: ein Array aus Zeilen-Objekten. Damit lässt sie sich ohne Umweg in `loop_foreach` durchlaufen (personalisierte Anrede), mit `liste_filtern` einschränken oder als fertiger Mail-Verteiler verwenden.
|
||||
|
||||
**Parameter**
|
||||
|
||||
| Name | Pflicht? | Default | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `spalten` | ja | — | Komma-Liste der Spaltennamen, z. B. `name,mail,rolle`. Nur Buchstaben, Ziffern, `_`. |
|
||||
| `zeilen` | nein | *(leer)* | Container mit `<zeile>`-Elementen; ein Attribut je Spalte. Zellen dürfen `{{variablen}}` enthalten. |
|
||||
| `output_var` | ja | `liste` | Präfix der Ergebnisvariablen. |
|
||||
|
||||
Zeilen, die in **allen** Spalten leer sind, werden verworfen. Fehlende Spalten einer Zeile werden als leerer String ergänzt, damit alle Zeilen dieselbe Form haben. Attribute, die nicht in `spalten` stehen, werden ignoriert.
|
||||
|
||||
**Eingangswerte:** beliebige Kontextvariablen in den Zellen.
|
||||
|
||||
**Ausgangswerte** (Präfix = `output_var`, hier `empfaenger`)
|
||||
|
||||
| Variable | Beschreibung |
|
||||
|---|---|
|
||||
| `{{empfaenger}}` | Array der Zeilen — direkt als `<items>` für `loop_foreach` |
|
||||
| `{{empfaenger_json}}` | dieselbe Liste als JSON-String |
|
||||
| `{{empfaenger_anzahl}}` | Anzahl der Zeilen |
|
||||
| `{{empfaenger_leer}}` | `1`, wenn die Liste leer ist (praktisch für `<task type="if">`) |
|
||||
| `{{empfaenger_<spalte>_liste}}` | Komma-Liste aller Werte dieser Spalte, z. B. `{{empfaenger_mail_liste}}` = fertiger Verteiler |
|
||||
|
||||
```xml
|
||||
<task type="liste" id="empfaenger">
|
||||
<config>
|
||||
<spalten>name,mail,rolle</spalten>
|
||||
<output_var>empfaenger</output_var>
|
||||
<zeilen>
|
||||
<zeile name="Max Mustermann" mail="max@vlnsachsen.de" rolle="Vorstand"/>
|
||||
<zeile name="Erika Muster" mail="erika@extern.de" rolle="Mitglied"/>
|
||||
</zeilen>
|
||||
</config>
|
||||
</task>
|
||||
```
|
||||
|
||||
**Personalisierte Anrede** — die Liste in `loop_foreach` durchlaufen; jedes Feld steht als `{{p.feld}}` und `{{p_feld}}` bereit:
|
||||
|
||||
```xml
|
||||
<task type="loop_foreach" id="anschreiben">
|
||||
<items>{{empfaenger}}</items>
|
||||
<as>p</as>
|
||||
<task type="email" id="brief">
|
||||
<config>
|
||||
<an>{{p.mail}}</an>
|
||||
<titel>Einladung</titel>
|
||||
<text>Sehr geehrte(r) {{p.name}},
|
||||
|
||||
als {{p.rolle}} laden wir Sie ein …</text>
|
||||
</config>
|
||||
</task>
|
||||
</task>
|
||||
```
|
||||
|
||||
**Sammel-Mail an alle** — ohne Schleife, über die Spalten-Komma-Liste:
|
||||
|
||||
```xml
|
||||
<task type="email" id="rundmail">
|
||||
<config>
|
||||
<an>{{empfaenger_mail_liste}}</an>
|
||||
<titel>Information</titel>
|
||||
<text>…</text>
|
||||
</config>
|
||||
</task>
|
||||
```
|
||||
|
||||
**Fallen / Hinweise**
|
||||
- Spaltennamen werden Teil von Variablennamen — daher nur `[A-Za-z_][A-Za-z0-9_]*`.
|
||||
- Im visuellen Editor erscheint die Tabelle als echtes Zeilenraster; die Kopfzeile zieht nach, sobald `spalten` geändert wird.
|
||||
- Für dynamische Listen (aus Auswahl-Tasks, Webhooks, JSON) ist der Task nicht nötig — `liste_filtern`, `loop_foreach` und `json_transform` arbeiten auf derselben Struktur.
|
||||
@@ -0,0 +1,57 @@
|
||||
# `liste_filtern` — Zeilen einer Liste auswählen
|
||||
|
||||
**Zweck:** Schränkt eine Liste anhand von Bedingungen ein, z. B. „nur Vorstände" oder „nur interne Mailadressen". Quelle ist jede Liste im Workflow-Sinn — aus `liste`, `person_pick`, `json_transform`, einem Webhook oder einer Komma-Liste. Das Ergebnis hat dieselbe Form wie die Quelle und lässt sich direkt weiterverwenden (`loop_foreach`, Mail-Verteiler, erneut filtern).
|
||||
|
||||
**Parameter**
|
||||
|
||||
| Name | Pflicht? | Default | Beschreibung |
|
||||
|---|---|---|---|
|
||||
| `liste` | ja | — | Quelle: `{{empfaenger}}`, JSON-String oder Komma-Liste. |
|
||||
| `bedingungen` | nein | *(keine)* | Container mit `<bedingung spalte="…" operator="…" wert="…"/>`. Ohne Bedingung bleibt die Liste unverändert. |
|
||||
| `verknuepfung` | nein | `und` | `und` = alle Bedingungen müssen zutreffen, `oder` = mindestens eine. |
|
||||
| `output_var` | ja | `gefiltert` | Präfix der Ergebnisvariablen. |
|
||||
|
||||
**Operatoren**
|
||||
|
||||
| Operator | Bedeutung |
|
||||
|---|---|
|
||||
| `ist`, `ist_nicht` | exakter Vergleich (case-insensitiv) |
|
||||
| `enthaelt`, `enthaelt_nicht` | Teilstring |
|
||||
| `beginnt_mit`, `endet_auf` | Präfix / Suffix — z. B. `endet_auf @vlnsachsen.de` |
|
||||
| `leer`, `nicht_leer` | Zelle ohne bzw. mit Inhalt (`wert` wird ignoriert) |
|
||||
| `groesser`, `kleiner`, `groesser_gleich`, `kleiner_gleich` | numerischer Vergleich; deutsches Format (`1.234,50`) wird verstanden |
|
||||
| `in`, `nicht_in` | `wert` ist eine Komma-Liste erlaubter Werte |
|
||||
|
||||
Ein unbekannter Operator ist ein Fehler (kein stilles Durchreichen). Vergleiche sind case-insensitiv.
|
||||
|
||||
**Eingangswerte:** die Liste unter `liste`; Platzhalter in `spalte` und `wert` werden gerendert.
|
||||
|
||||
**Ausgangswerte** (Präfix = `output_var`, hier `vorstand`)
|
||||
|
||||
| Variable | Beschreibung |
|
||||
|---|---|
|
||||
| `{{vorstand}}` | gefilterte Zeilen (Array) |
|
||||
| `{{vorstand_json}}` | dieselbe Liste als JSON |
|
||||
| `{{vorstand_anzahl}}` | Zeilen nach dem Filter |
|
||||
| `{{vorstand_entfernt}}` | Zahl der aussortierten Zeilen |
|
||||
| `{{vorstand_leer}}` | `1`, wenn nichts übrig blieb |
|
||||
| `{{vorstand_<spalte>_liste}}` | Komma-Liste je Spalte, z. B. `{{vorstand_mail_liste}}` |
|
||||
|
||||
```xml
|
||||
<task type="liste_filtern" id="nur_vorstand">
|
||||
<config>
|
||||
<liste>{{empfaenger}}</liste>
|
||||
<verknuepfung>und</verknuepfung>
|
||||
<output_var>vorstand</output_var>
|
||||
<bedingungen>
|
||||
<bedingung spalte="rolle" operator="ist" wert="Vorstand"/>
|
||||
<bedingung spalte="mail" operator="endet_auf" wert="@vlnsachsen.de"/>
|
||||
</bedingungen>
|
||||
</config>
|
||||
</task>
|
||||
```
|
||||
|
||||
**Fallen / Hinweise**
|
||||
- Eine Komma-Liste als Quelle (`a@x.de, b@y.de`) wird zu Zeilen mit der einen Spalte `wert`.
|
||||
- Verschachtelte Werte (Arrays/Objekte in einer Zelle) werden verworfen — Listen sind bewusst flach.
|
||||
- Leeres Ergebnis ist kein Fehler; mit `{{<var>_leer}}` in einem `if` abfangen, bevor eine Mail an niemanden geht.
|
||||
Reference in New Issue
Block a user