| @@ -0,0 +1,319 @@ | |||
| # Leadharvester-Integration mit QC Text Builder | |||
| Dieses Dokument beschreibt den minimalen, aber vollstaendigen Integrations-Workflow zwischen **Leadharvester** und **QC Text Builder**. | |||
| Ziel: | |||
| - Leadharvester holt zuerst die verfuegbaren Templates aus QC Text Builder. | |||
| - Leadharvester zeigt Template-Name, Thumbnail und Vollansicht/Preview an. | |||
| - Danach waehlt der User oder Upstream-Prozess ein Template. | |||
| - Anschliessend uebergibt Leadharvester die gesammelten Stammdaten und Kontextdaten per Intake an QC Text Builder. | |||
| - QC Text Builder erzeugt oder aktualisiert daraus einen Draft. | |||
| --- | |||
| ## 1) Basisdaten | |||
| - QC Text Builder Base URL lokal: `http://localhost:8080` | |||
| - Template-Liste: `GET /api/templates` | |||
| - Template-Detail: `GET /api/templates/{id}` | |||
| - Draft-Intake: `POST /api/drafts/intake` | |||
| --- | |||
| ## 2) Gesamt-Workflow | |||
| ### Schritt 1: Templates aus QC Text Builder abrufen | |||
| Leadharvester ruft zuerst die verfuegbaren Templates ab: | |||
| **Request** | |||
| ```http | |||
| GET /api/templates | |||
| ``` | |||
| **Beispiel lokal** | |||
| ```text | |||
| http://localhost:8080/api/templates | |||
| ``` | |||
| **Response-Struktur** | |||
| ```json | |||
| { | |||
| "count": 1, | |||
| "templates": [ | |||
| { | |||
| "id": 1408367, | |||
| "name": "Mono QC 1- DE", | |||
| "description": "", | |||
| "locale": "DE", | |||
| "thumbnailUrl": "https://rai.monosolutions.com//thumbnails/01408367/1408367.jpeg", | |||
| "templatePreviewUrl": "https://u1408367.tool-apdialog.at", | |||
| "type": "ai", | |||
| "paletteReady": true, | |||
| "rawTemplateJson": {}, | |||
| "isAiTemplate": true, | |||
| "isOnboarded": true, | |||
| "manifestStatus": "reviewed", | |||
| "lastDiscoveredAt": "2026-03-27T10:00:00Z" | |||
| } | |||
| ] | |||
| } | |||
| ``` | |||
| ### Felder, die Leadharvester mindestens verwenden sollte | |||
| - `id` | |||
| - `name` | |||
| - `thumbnailUrl` | |||
| - `templatePreviewUrl` | |||
| ### Bedeutung | |||
| - `thumbnailUrl`: kleine Vorschau fuer Template-Karten | |||
| - `templatePreviewUrl`: Vollansicht / Live-Preview des Templates | |||
| - `id`: wird spaeter als `templateId` an den Draft-Intake uebergeben | |||
| --- | |||
| ## 3) Templates in Leadharvester anzeigen | |||
| Leadharvester sollte die Template-Auswahl mindestens so darstellen: | |||
| ```json | |||
| { | |||
| "templateId": 1408367, | |||
| "label": "Mono QC 1- DE", | |||
| "thumbnail": "https://rai.monosolutions.com//thumbnails/01408367/1408367.jpeg", | |||
| "previewUrl": "https://u1408367.tool-apdialog.at" | |||
| } | |||
| ``` | |||
| Nach der Auswahl muss Leadharvester mindestens diese Werte intern weitertragen: | |||
| ```json | |||
| { | |||
| "selectedTemplateId": 1408367, | |||
| "selectedTemplateName": "Mono QC 1- DE" | |||
| } | |||
| ``` | |||
| --- | |||
| ## 4) Stammdaten und Kontext in Leadharvester sammeln | |||
| Leadharvester sammelt anschliessend die Nutzdaten fuer den Draft. | |||
| ### Empfohlene Stammdaten (`globalData`) | |||
| ```json | |||
| { | |||
| "companyName": "Dönerbude", | |||
| "username": "jansvabenik", | |||
| "email": "jan.svabenik@apdialog.com", | |||
| "phone": "+41 79 123 45 67", | |||
| "businessType": "Imbiss", | |||
| "descriptionShort": "Frische Döner und schnelle Mittagsgerichte.", | |||
| "descriptionLong": "Dönerbude bietet frisch zubereitete Spezialitäten, schnelle Bedienung und unkomplizierten Genuss für den Alltag.", | |||
| "mission": "Frisches, gutes Essen schnell und unkompliziert anbieten.", | |||
| "addressLine1": "Bahnhofstrasse 12", | |||
| "addressCity": "Zürich", | |||
| "addressZIP": "8001", | |||
| "addressCountry": "Schweiz" | |||
| } | |||
| ``` | |||
| ### Empfohlener Kontext fuer Textvorschlaege | |||
| ```json | |||
| { | |||
| "websiteUrl": "https://example.com", | |||
| "websiteSummary": "Frische Döner und schnelle Mittagsgerichte für Kundschaft in der Schweiz.", | |||
| "businessType": "Imbiss", | |||
| "localeStyle": "de-CH", | |||
| "marketStyle": "Schweiz", | |||
| "addressMode": "du", | |||
| "contentTone": "locker", | |||
| "promptInstructions": "Kurz, appetitlich und glaubwürdig formulieren." | |||
| } | |||
| ``` | |||
| --- | |||
| ## 5) Rueckuebergabe von Leadharvester an QC Text Builder | |||
| Wenn Template + Stammdaten + Kontext feststehen, gibt Leadharvester die Daten per Intake zurueck an QC Text Builder. | |||
| ### Endpoint | |||
| ```http | |||
| POST /api/drafts/intake | |||
| Content-Type: application/json | |||
| ``` | |||
| ### Exakter Intake-Contract | |||
| ```json | |||
| { | |||
| "draftId": "string, optional", | |||
| "source": "string, required", | |||
| "requestName": "string, required", | |||
| "templateId": 0, | |||
| "globalData": {}, | |||
| "notes": "string, optional", | |||
| "websiteUrl": "string, optional", | |||
| "websiteSummary": "string, optional", | |||
| "businessType": "string, optional", | |||
| "localeStyle": "string, optional", | |||
| "marketStyle": "string, optional", | |||
| "addressMode": "string, optional", | |||
| "contentTone": "string, optional", | |||
| "promptInstructions": "string, optional", | |||
| "styleProfile": { | |||
| "localeStyle": "string, optional", | |||
| "marketStyle": "string, optional", | |||
| "addressMode": "string, optional", | |||
| "contentTone": "string, optional", | |||
| "promptInstructions": "string, optional" | |||
| } | |||
| } | |||
| ``` | |||
| ### Empfohlenes Request-Beispiel | |||
| ```json | |||
| { | |||
| "source": "leadharvester", | |||
| "requestName": "Dönerbude Intake 2026-03-27", | |||
| "templateId": 1408367, | |||
| "globalData": { | |||
| "companyName": "Dönerbude", | |||
| "username": "jansvabenik", | |||
| "email": "jan.svabenik@apdialog.com", | |||
| "phone": "+41 79 123 45 67", | |||
| "businessType": "Imbiss", | |||
| "descriptionShort": "Frische Döner und schnelle Mittagsgerichte.", | |||
| "descriptionLong": "Dönerbude bietet frisch zubereitete Spezialitäten, schnelle Bedienung und unkomplizierten Genuss für den Alltag.", | |||
| "mission": "Frisches, gutes Essen schnell und unkompliziert anbieten.", | |||
| "addressLine1": "Bahnhofstrasse 12", | |||
| "addressCity": "Zürich", | |||
| "addressZIP": "8001", | |||
| "addressCountry": "Schweiz" | |||
| }, | |||
| "notes": "Import aus Leadharvester", | |||
| "websiteUrl": "https://example.com", | |||
| "websiteSummary": "Frische Döner und schnelle Mittagsgerichte für Kundschaft in der Schweiz.", | |||
| "businessType": "Imbiss", | |||
| "localeStyle": "de-CH", | |||
| "marketStyle": "Schweiz", | |||
| "addressMode": "du", | |||
| "contentTone": "locker", | |||
| "promptInstructions": "Kurz, appetitlich und glaubwürdig formulieren.", | |||
| "styleProfile": { | |||
| "localeStyle": "de-CH", | |||
| "marketStyle": "Schweiz", | |||
| "addressMode": "du", | |||
| "contentTone": "locker", | |||
| "promptInstructions": "Kurz, appetitlich und glaubwürdig formulieren." | |||
| } | |||
| } | |||
| ``` | |||
| --- | |||
| ## 6) Backend-Verhalten beim Intake | |||
| QC Text Builder macht beim Intake aktuell Folgendes: | |||
| - Wenn `draftId` fehlt oder leer ist, wird ein **neuer Draft** erzeugt. | |||
| - Wenn `draftId` gesetzt ist, wird ein bestehender Draft **aktualisiert**. | |||
| - Der Draft wird mit Status **`draft`** gespeichert. | |||
| - `fieldValues` werden beim Intake leer initialisiert. | |||
| - Wenn `globalData` fehlt, wird automatisch `{}` verwendet. | |||
| - Wenn top-level `businessType` gesetzt ist und `globalData.businessType` leer ist, wird `businessType` in `globalData` gespiegelt. | |||
| - Wenn `styleProfile` gesetzt ist, wird dieses bevorzugt; fehlende Felder darin werden aus den flachen Stilfeldern ergaenzt. | |||
| --- | |||
| ## 7) Rueckgabe aus QC Text Builder an Leadharvester | |||
| Der Draft-Intake liefert den gespeicherten Draft zurueck. | |||
| ### Erwartung | |||
| - **201 Created**, wenn ein neuer Draft erstellt wurde | |||
| - **200 OK**, wenn ein bestehender Draft aktualisiert wurde | |||
| ### Wichtige Rueckgabefelder | |||
| ```json | |||
| { | |||
| "id": "1774540501012861000", | |||
| "templateId": 1408367, | |||
| "source": "leadharvester", | |||
| "requestName": "Dönerbude Intake 2026-03-27", | |||
| "status": "draft", | |||
| "createdAt": "2026-03-27T12:00:00Z", | |||
| "updatedAt": "2026-03-27T12:00:00Z" | |||
| } | |||
| ``` | |||
| ### Was Leadharvester speichern sollte | |||
| Mindestens: | |||
| ```json | |||
| { | |||
| "qcDraftId": "1774540501012861000", | |||
| "qcTemplateId": 1408367, | |||
| "qcDraftStatus": "draft" | |||
| } | |||
| ``` | |||
| Diese `qcDraftId` ist wichtig, damit Leadharvester denselben Draft spaeter erneut aktualisieren oder weiterverfolgen kann. | |||
| --- | |||
| ## 8) Minimaler Integrationsablauf fuer Coder | |||
| ```json | |||
| { | |||
| "steps": [ | |||
| "GET /api/templates", | |||
| "Template in Leadharvester anzeigen (name + thumbnailUrl + templatePreviewUrl)", | |||
| "templateId aus der Auswahl merken", | |||
| "Lead-/Stammdaten in Leadharvester sammeln", | |||
| "POST /api/drafts/intake mit templateId + globalData + Kontext", | |||
| "draft id aus der Response speichern" | |||
| ] | |||
| } | |||
| ``` | |||
| --- | |||
| ## 9) Wichtige Regeln | |||
| - Leadharvester muss **vor** dem Intake die Templates abrufen. | |||
| - Leadharvester sollte die `templateId` immer aus der aktuellen Template-Liste verwenden. | |||
| - `thumbnailUrl` ist fuer kleine Vorschauen gedacht. | |||
| - `templatePreviewUrl` ist fuer die Vollansicht / Preview gedacht. | |||
| - Leadharvester sollte die vom Intake zurueckgegebene `draftId` speichern. | |||
| - Diese `draftId` sollte bei spaeteren Updates wiederverwendet werden. | |||
| --- | |||
| ## 10) Kurzfassung | |||
| **Templates holen** | |||
| - `GET /api/templates` | |||
| **Draft anlegen/aktualisieren** | |||
| - `POST /api/drafts/intake` | |||
| **Pflicht fuer Leadharvester** | |||
| - Template waehlen | |||
| - `templateId` speichern | |||
| - Stammdaten/Kontext senden | |||
| - `draftId` aus Response speichern | |||