Files
Brancheneinstufung2/SUPEROFFICE_INTEGRATION_PLAN.md
Floke 198eaef2b2 feat: Implement unsubscribe link for marketing automation [31188f42]
This commit introduces a new unsubscribe feature to allow contacts to opt-out
from marketing automation.

Key changes include:
- Database schema migration: Added  (UUID) to the  model.
- Data population: Implemented a script to assign unique tokens to existing contacts.
- API endpoint: Created a public GET  endpoint to handle opt-out requests.
- Automation: New contacts automatically receive an unsubscribe token upon creation.
- Integration: The full unsubscribe link is now returned via the provisioning API
  for storage in SuperOffice UDFs (ProgID: SuperOffice:9).
- Documentation: Updated  and
  to reflect the new feature and its integration requirements.
- Added  for quick overview and next steps.
2026-02-24 12:18:13 +00:00

11 KiB
Raw Blame History

Technisches Konzept: SuperOffice CRM Integration

Dieses Dokument beschreibt die Integrationsstrategie zwischen SuperOffice CRM (führendes System für Stammdaten) und dem Company Explorer (KI-gestützte Anreicherungs-Engine).

Zielsetzung

Automatisierte Anreicherung von B2B-Firmendaten im CRM mit KI-generierten Insights (z.B. Robotik-Affinität, Branchen-Einstufung), ohne die Hoheit über die Stammdaten zu gefährden.


1. Architektur: "Event-Driven Messaging" (v2.0)

Wir haben die Architektur von einem Polling-Modell auf ein Event-gesteuertes Webhook-Modell umgestellt. Dies entspricht modernen Best Practices und ist Voraussetzung für eine Skalierung auf 16.000+ Firmen.

Das Prinzip: "Gehirn & Muskel"

  • Das Gehirn (Company Explorer): Hier liegt die gesamte Intelligenz. Die Datenbank speichert die Firmendaten, die Signale und die Marketing-Matrix (Textbausteine). Er entscheidet, welcher Text für welchen Kontakt generiert wird.
  • Der Muskel (Connector): Er ist ein "dummer" Bote. Er nimmt Events entgegen, fragt das Gehirn nach Anweisungen und führt diese in SuperOffice aus.
graph TD
    subgraph "SuperOffice CRM"
        SO_Contact["👤 Contact / Person"]
        SO_Webhook["🚀 Webhook<br/>(contact.changed)"]
    end

    subgraph "Connector (Docker)"
        WebhookApp["📥 Webhook Receiver<br/>(FastAPI :8002)"]
        Queue[("📦 Job Queue<br/>(SQLite/Redis)")]
        Worker["👷‍♂️ Worker Process"]
    end

    subgraph "Company Explorer (Docker)"
        CE_API["🧠 Provisioning API<br/>(:8000)"]
        MatrixDB[("📚 Marketing Matrix<br/>(SQLite)")]
    end

    SO_Contact -->|1. Änderung| SO_Webhook
    SO_Webhook -->|2. POST Event| WebhookApp
    WebhookApp -->|3. Enqueue Job| Queue
    Worker -->|4. Fetch Job| Queue
    Worker -->|5. Request: 'Provision Me'| CE_API
    CE_API -->|6. Lookup Logic| MatrixDB
    CE_API -->|7. Return: Final Texts| Worker
    Worker -->|8. Write-Back UDFs| SO_Contact

Technische Kommunikation: Da beide Services (connector-superoffice und company-explorer) im selben Docker-Netzwerk laufen, erfolgt die Kommunikation direkt und latenzfrei über den internen Docker-DNS (http://company-explorer:8000). Es gibt keinen Umweg über das öffentliche Internet.

2. Datenmodell & Erweiterung

2. Datenmodell & Erweiterung

Um die CRM-Daten sauber zu halten, schreiben wir niemals in Standardfelder (wie Name, Department), sondern ausschließlich in dedizierte, benutzerdefinierte Felder (User Defined Fields - UDFs).

Benötigte Felder in SuperOffice (Anforderung an IT/Admin)

Folgende Felder sollten am Objekt Company (bzw. Contact in SuperOffice-Terminologie) angelegt werden:

Feldname (Label) Typ Zweck
AI Robotics Potential List/Select High / Medium / Low / None
AI Industry Text (Short) KI-ermittelte Branche (z.B. "Logistik - Intralogistik")
AI Summary Text (Long/Memo) Kurze Zusammenfassung der Analyse
AI Last Update Date Zeitstempel der letzten Anreicherung
AI Status List/Select Pending / Enriched / Error
Unsubscribe-Link Text/Link NEU: Speichert den personalisierten Link zur Abmeldung von der Marketing-Automation. (ProgID: SuperOffice:9)

Benötigtes Feld im Company Explorer

Feldname Typ Zweck
external_crm_id String/Int Speichert die ContactId aus SuperOffice zur eindeutigen Zuordnung (Primary Key Mapping).

2.2. Data Integrity: "The Double Truth"

Um die Datenqualität zu sichern, pflegen wir für Stammdaten (Name, Website) zwei Wahrheiten:

  1. CRM Truth: Was aktuell in SuperOffice steht (oft manuell gepflegt, potenziell veraltet).
  2. Explorer Truth: Was der Company Explorer im Web gefunden hat.

Synchronisation:

  • Bei jedem Webhook-Event sendet der Connector die aktuellen CRM-Werte (crm_name, crm_website) an den Company Explorer.
  • Der Company Explorer speichert diese und berechnet einen data_mismatch_score (0.0 = Match, 1.0 = Mismatch).
  • UI: Im Frontend wird dieser Score visualisiert, sodass Abweichungen sofort erkennbar sind.

2.1. Mapping of CRM Concepts (SuperOffice vs. D365)

Um die Integration effizient zu gestalten, wurde eine strategische Entscheidung bezüglich der Abbildung von Kern-CRM-Konzepten getroffen:

D365 Konzept SuperOffice Entität Zweck & Begründung
Opportunity Sale Die Sale-Entität in SuperOffice ist das direkte Äquivalent zu einer Opportunity. Hier werden potenzielle Umsätze, Vertriebsphasen und Wahrscheinlichkeiten erfasst. Dies ist das primäre Zielobjekt, sobald eine konkrete Verkaufschance durch den Company Explorer identifiziert wird.
Campaign Project Für Marketing-Automatisierung und die Bündelung von Kontakten für Kampagnen dient die Project-Entität als idealer Container. Sie ermöglicht es, Kampagnen-Teilnehmer zu gruppieren, Aktivitäten zuzuordnen und den ROI durch Verknüpfung mit Sale-Objekten zu messen.

3. Phasenplan

Phase 1: Initial Load (Snapshot)

Ziel: Bestandskunden und aktive Leads einmalig bewerten.

  1. Filter: Der Connector lädt alle Firmen mit Status "Kunde" oder "Prospect".
  2. Import: Daten werden via POST /api/companies/bulk an den Explorer gesendet. Die ContactId wird mitgegeben.
  3. Verarbeitung: Der Explorer arbeitet die Queue ab (Web-Scraping -> Klassifizierung).

Phase 2: Write-Back (Ergebnisse speichern)

Ziel: Ergebnisse im CRM sichtbar machen.

  1. Der Connector prüft regelmäßig (GET /api/companies?status=ENRICHED) auf fertige Analysen.
  2. Für jeden Treffer sendet er ein Update an die SuperOffice API (PUT /Contact/{id}).
  3. Es werden nur die oben definierten UDFs aktualisiert.

Phase 3: Continuous Sync (Event-Driven)

Ziel: Skalierbare, echtzeitnahe Verarbeitung.

  1. Auslöser: Ein contact.changed oder person.changed Event in SuperOffice (z.B. User setzt Status auf Init).
  2. Transport: SuperOffice Webhook -> Connector POST /webhook -> Queue.
  3. Verarbeitung: Der Worker holt den Job, ruft die Provisioning API des Company Explorer auf.
  4. Vorteil:
    • Kein unnötiger Traffic: Wir verarbeiten nur Kontakte, bei denen wirklich etwas passiert.
    • Echtzeit: Änderungen sind sofort wirksam.
    • SO-Konformität: Wir nutzen den offiziellen, effizienten Weg für Integrationen.

4. Sicherheit & Authentifizierung

  • Authentifizierung: Nutzung eines System User Tokens (Machine-to-Machine). Dies verhindert, dass Passwörter von persönlichen Accounts im Code hinterlegt werden müssen.
  • Scope: Der API-User benötigt Lesezugriff auf Contact und Schreibzugriff auf die UDFs.
  • Datenschutz: Es werden nur Firmendaten (Name, Webseite, Stadt) übertragen. Personenbezogene Ansprechpartner bleiben im CRM und werden nicht an die KI gesendet.

4.1. POC Ergebnisse & Finale Authentifizierungs-Strategie (Feb 2026)

Der Proof of Concept (POC) wurde erfolgreich abgeschlossen. Dabei wurde die Authentifizierungs-Strategie für maximale Stabilität und Einfachheit angepasst.

Ergebnis:

  • Erfolg: Die Verbindung zum SOD-Tenant (Cust55774) steht. Der Connector kann Daten lesen und ist bereit zum Schreiben.
  • Strategiewechsel: Statt des komplexen RSA-S2S-Flows wird der OAuth 2.0 Refresh Token Flow genutzt. Dies umgeht Lizenz- und UI-Einschränkungen in der SOD-Umgebung und bietet dieselbe Automatisierungsqualität für den Docker-Service.
  • Subdomain-Handling: Es wurde festgestellt, dass SuperOffice Online (SOD) mandantenabhängige Subdomains nutzt. Für den Test-Tenant wurde https://app-sod.superoffice.com als valide API-Basis identifiziert.

Technische Umsetzung:

  1. Einmalige Autorisierung: Ein langlebiger refresh_token wurde über einen manuellen Consent-Step generiert.
  2. Automatisierung: Der AuthHandler tauscht diesen Token vollautomatisch gegen kurzlebige access_tokens (Bearer) aus.
  3. Caching: Tokens werden lokal in token_cache.json gespeichert, um API-Limits zu schonen.

Aktueller Status & Nächste Schritte:

  • Blocker gelöst: Die Authentifizierung und das URL-Routing sind stabil.
  • Nächster Schritt: Manuelle Anlage der UDF-Felder (siehe Abschnitt 2) in der SuperOffice Administration durch den Admin. Erst danach kann der "Write-Back" (Phase 2) im Code final gemappt werden.

5. Vorbereitung für die IT

Um den Connector in Betrieb zu nehmen, benötigen wir:

  1. API Zugangsdaten: Client ID, Client Secret, Customer ID (Tenant) und einen System User Token.
  2. UDF Definitionen: Die ProgId (technischen Namen) der neu angelegten Felder (z.B. userdef_id_123).

6. Fragen an Manuel

  1. Die "Lizenz-Gretchenfrage" (Development Tools) Frage: "Manuel, du sagtest, bei Wackler sind die 'Development Tools' aktiv. Weißt du, ob das eine globale Konzern-Lizenz ist oder ob wir für den RoboPlanet-Mandanten eine eigene Subskription brauchen? Mein Dev-Portal blockiert S2S aktuell mit dem Hinweis auf fehlende Lizenzen in Production." Ziel: Klären, ob es nur ein "Klick" im Admin-Panel ist oder ob Webkom (oder ein anderer Partner) eine neue Rechnung schreiben muss.

  2. Der App-Registrierungs-Pfad Frage: "Hast du eure App als 'Custom Application' (privat für Wackler) oder als 'Standard Application' (über einen Partner-Account) registriert? Falls ihr einen Partner-Account nutzt: Könnten wir unsere GTM-Engine darüber mitlaufen lassen, um die Lizenz-Hürde zu umgehen?" Ziel: Prüfen, ob Manuel über ein Partner-Portal arbeitet. Partner-Apps brauchen manchmal keine Dev-Tools beim Kunden, weil der Partner die Validierung übernimmt.

  3. Identifikation des "Gatekeepers" Frage: "Wer hat bei euch den Tenant technisch aufgesetzt? War das die Webkom? Ich muss herausfinden, wer die administrative Hoheit hat, um den 'System User' für S2S freizuschalten." Ziel: Den Namen des Ansprechpartners bei der Webkom oder intern bei Wackler-IT herausfinden.

  4. Authentifizierungs-Deep-Dive (RSA vs. Token) Frage: "Nutzt ihr für eure S2S-App den RSA-Key-Flow (JWT) oder arbeitet ihr mit einem statischen System-User-Token? Ich bereite gerade den RSA-Handshake vor und wollte wissen, was in der SuperOffice Cloud stabiler läuft." Ziel: Fachsimpelei, um Manuel zu zeigen, dass du auf seinem Level spielst. Das öffnet Türen für Code-Sharing oder Tipps.

  5. Das "Y-Tabellen" Problem Frage: "Nutzt ihr für eure Verkaufs-App auch Zusatztabellen (Y-Tabellen) oder schreibt ihr nur in Standardfelder? Ich plane eine Tabelle für dynamische Marketing-Texte (Rolle x Branche) gab es bei euch Probleme mit dem Cache nach Strukturänderungen?" Ziel: Bestätigung einholen, dass Y-Tabellen mit ihrer Lizenz funktionieren. Das ist dein Beweis, dass du die Dev-Tools zwingend brauchst.

  6. Authentifizierung beim S2S Call Wie authentifiziert ihr euch beim S2S-Call? Nutzt ihr den RSA-Flow mit Zertifikaten oder habt ihr einen Partner-Proxy dazwischen?" (Wenn er "Partner-Proxy" sagt, arbeitet er über Webkom-Infrastruktur).

  7. Nutzung System User Wo habt ihr den 'System User' im CRM autorisiert?" (Er soll dir den Pfad in Einstellungen & Verwaltung zeigen).

  8. Header API-Call Könntest du mir den Header eines eurer API-Calls zeigen (natürlich ohne den echten Token)?" (Daran sehen wir sofort, ob sie die v1 REST API oder die alte SOAP-Schnittstelle nutzen).