153 lines
7.2 KiB
JSON
153 lines
7.2 KiB
JSON
{
|
|
"$schemaVersion": "1.0",
|
|
"$kind": "poweron.workflow",
|
|
"$exportedAt": "2026-04-16T10:00:00Z",
|
|
"$gatewayVersion": "demo-2026-04",
|
|
"label": "PWG Pilot: Jahresmietzinsbestätigung",
|
|
"description": "Verarbeitet gescannte Rückantworten der Jahresmietzinsbestätigungen: OCR, Abgleich gegen Trustee-DB (Mieter + Mietzins-Buchungen), AI-Klassifikation pro Scan und Zustellung als CSV-Anhang im Outlook-Draft an die Sachbearbeitung. Pilot-Lieferung Sommer 2026.",
|
|
"tags": ["pwg", "pilot", "mietzins", "trustee", "ocr"],
|
|
"templateScope": "instance",
|
|
"sharedReadOnly": false,
|
|
"notifyOnFailure": true,
|
|
"graph": {
|
|
"nodes": [
|
|
{
|
|
"id": "n1",
|
|
"type": "trigger.manual",
|
|
"x": 50,
|
|
"y": 200,
|
|
"title": "Manueller Start",
|
|
"parameters": {}
|
|
},
|
|
{
|
|
"id": "n2",
|
|
"type": "sharepoint.listFiles",
|
|
"x": 320,
|
|
"y": 200,
|
|
"title": "Scan-Ordner auflisten",
|
|
"parameters": {
|
|
"connectionReference": "",
|
|
"pathQuery": "PWG/Mietzinsbestaetigungen/Scans-Eingang"
|
|
}
|
|
},
|
|
{
|
|
"id": "n3",
|
|
"type": "flow.loop",
|
|
"x": 590,
|
|
"y": 200,
|
|
"title": "Pro Scan-Dokument",
|
|
"parameters": {
|
|
"items": {"type": "ref", "nodeId": "n2", "path": ["files"]},
|
|
"level": "auto",
|
|
"concurrency": 1
|
|
}
|
|
},
|
|
{
|
|
"id": "n4",
|
|
"type": "sharepoint.downloadFile",
|
|
"x": 860,
|
|
"y": 200,
|
|
"title": "PDF/Bild laden",
|
|
"parameters": {
|
|
"connectionReference": "",
|
|
"pathQuery": "{{loop.item.path}}"
|
|
}
|
|
},
|
|
{
|
|
"id": "n5",
|
|
"type": "trustee.extractFromFiles",
|
|
"x": 1130,
|
|
"y": 200,
|
|
"title": "OCR & Felder extrahieren",
|
|
"parameters": {
|
|
"featureInstanceId": "",
|
|
"prompt": "Extrahiere die folgenden Felder aus dieser Jahresmietzinsbestätigung und antworte als JSON: tenantName (string), tenantAddress (string), objectAddress (string), confirmedRentAmount (number|null in CHF), currency ('CHF'), period (string z.B. '2026'), tenantNotes (string|null - alle handschriftlichen Anmerkungen oder Korrekturen), hasSignature (boolean - ist eine Unterschrift vorhanden?), documentDate (ISO date|null), ocrConfidence (number 0-1)."
|
|
}
|
|
},
|
|
{
|
|
"id": "n6",
|
|
"type": "trustee.queryData",
|
|
"x": 1400,
|
|
"y": 200,
|
|
"title": "Referenzdaten Trustee-DB",
|
|
"parameters": {
|
|
"featureInstanceId": "",
|
|
"mode": "lookup",
|
|
"entity": "tenantWithRent",
|
|
"tenantNameRef": "{{n5.output.tenantName}}",
|
|
"tenantAddressRef": "{{n5.output.tenantAddress}}",
|
|
"period": "{{n5.output.period}}",
|
|
"rentAccountPattern": "6000-6099"
|
|
}
|
|
},
|
|
{
|
|
"id": "n7",
|
|
"type": "ai.prompt",
|
|
"x": 1670,
|
|
"y": 200,
|
|
"title": "Prüfung & Klassifikation",
|
|
"parameters": {
|
|
"outputFormat": "json",
|
|
"simpleMode": false,
|
|
"documentList": "{{n5.output}}",
|
|
"context": "{{n6.output}}",
|
|
"aiPrompt": "Du bist ein Sachbearbeitungs-Assistent der Stiftung PWG. Deine Aufgabe ist es, eine eingescannte und OCR-extrahierte Jahresmietzinsbestätigung gegen die Stammdaten der Buchhaltung (Trustee-Feature) abzugleichen.\n\nEingaben:\n1. SCAN_DATEN (extrahiert per OCR aus dem Rückantwort-Dokument):\n{{scan}}\n\n2. REFERENZ_DATEN (aus Trustee-DB für diesen Mieter; ggf. leer wenn nicht eindeutig zuordenbar):\n{{reference}}\n\nVorgehen:\n1. Prüfe Identität: Stimmt SCAN_DATEN.tenantName + SCAN_DATEN.tenantAddress mit einem Datensatz in REFERENZ_DATEN.contacts überein? (Toleranz: kleine Tippfehler, Umlaute, Abkürzungen).\n2. Prüfe Mietzinsbetrag: Stimmt SCAN_DATEN.confirmedRentAmount mit dem aus REFERENZ_DATEN.expectedRentAmount erwarteten Mietzins überein? (Toleranz: ±1 CHF Rundung).\n3. Prüfe Unterschrift: hasSignature muss true sein.\n4. Prüfe OCR-Qualität: ocrConfidence < 0.6 -> 'unleserlich'.\n\nKlassifiziere in EXAKT EINEN Status:\n- 'bestaetigt': Identität stimmt, Betrag stimmt, Unterschrift vorhanden.\n- 'abweichung_betrag': Identität ok, Unterschrift ok, Betrag weicht ab.\n- 'abweichung_anmerkung': tenantNotes enthält substantielle Anmerkung (nicht leer, nicht reine Bestätigung).\n- 'keine_unterschrift': hasSignature == false.\n- 'unleserlich': OCR-Qualität ungenügend ODER Pflichtfelder fehlen.\n- 'kein_match': Mieter nicht in REFERENZ_DATEN auffindbar.\n\nBei Status != 'bestaetigt': Generiere einen kurzen, höflichen Antwortvorschlag (deutsch, Sie-Form, max. 5 Sätze, PWG-Stil) für die Sachbearbeitung. Bei 'bestaetigt': antwortVorschlag = null.\n\nAntworte AUSSCHLIESSLICH als JSON nach folgendem Schema:\n{\n \"tenantName\": string,\n \"objectAddress\": string,\n \"status\": \"bestaetigt\" | \"abweichung_betrag\" | \"abweichung_anmerkung\" | \"keine_unterschrift\" | \"unleserlich\" | \"kein_match\",\n \"scanRentAmount\": number | null,\n \"expectedRentAmount\": number | null,\n \"delta\": number | null,\n \"tenantNotes\": string | null,\n \"antwortVorschlag\": string | null,\n \"matchConfidence\": number,\n \"auditEvidence\": string\n}"
|
|
}
|
|
},
|
|
{
|
|
"id": "n8",
|
|
"type": "data.aggregate",
|
|
"x": 1940,
|
|
"y": 200,
|
|
"title": "Ergebnisse sammeln (im Loop)",
|
|
"parameters": {
|
|
"mode": "collect"
|
|
}
|
|
},
|
|
{
|
|
"id": "n9",
|
|
"type": "data.consolidate",
|
|
"x": 2210,
|
|
"y": 200,
|
|
"title": "CSV bauen (nach Loop)",
|
|
"parameters": {
|
|
"mode": "csvJoin",
|
|
"separator": "\n"
|
|
}
|
|
},
|
|
{
|
|
"id": "n10",
|
|
"type": "email.draftEmail",
|
|
"x": 2480,
|
|
"y": 200,
|
|
"title": "Draft an Sachbearbeitung",
|
|
"parameters": {
|
|
"connectionReference": "",
|
|
"to": "sachbearbeiter@pwg.ch",
|
|
"subject": "Mietzinsbestätigungen Auswertung {{currentDate}}",
|
|
"body": "Hallo,\n\nim Anhang die Auswertung der eingegangenen Jahresmietzinsbestätigungen.\nPro Scan eine Zeile mit Status, Betragsabgleich und (bei Abweichung) Antwortvorschlag.\n\nBitte die Zeilen mit Status != 'bestaetigt' manuell sichten.\n\nFreundliche Grüße,\nPWG Automation",
|
|
"emailStyle": "business",
|
|
"attachments": [
|
|
{
|
|
"name": "mietzinsbestaetigungen-auswertung",
|
|
"mimeType": "text/csv",
|
|
"csvFromVariable": "n9.output"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
],
|
|
"connections": [
|
|
{"source": "n1", "target": "n2", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n2", "target": "n3", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n3", "target": "n4", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n4", "target": "n5", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n5", "target": "n6", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n6", "target": "n7", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n7", "target": "n8", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n8", "target": "n9", "sourceOutput": 0, "targetInput": 0},
|
|
{"source": "n9", "target": "n10", "sourceOutput": 0, "targetInput": 0}
|
|
]
|
|
},
|
|
"invocations": []
|
|
}
|