From 6b6fe4db1fc461b84bcd48d44c3ad7431128ad2f Mon Sep 17 00:00:00 2001 From: Moltbot-Jarvis Date: Wed, 18 Feb 2026 19:50:39 +0000 Subject: [PATCH] fix: Emergency restoration of complete MIGRATION_PLAN --- MIGRATION_PLAN.md | 180 +++++++++++++++++++++++------ company-explorer/MIGRATION_PLAN.md | 180 +++++++++++++++++++++++------ 2 files changed, 294 insertions(+), 66 deletions(-) diff --git a/MIGRATION_PLAN.md b/MIGRATION_PLAN.md index 2e0b9361..a985d8b9 100644 --- a/MIGRATION_PLAN.md +++ b/MIGRATION_PLAN.md @@ -1,47 +1,161 @@ # Migrations-Plan: Legacy GSheets -> Company Explorer (Robotics Edition v0.8.5) -**Kontext:** Strategische Neuausrichtung der Lead-Analyse für RoboPlanet. -**Zentrale Philosophie:** Trennung von CRM-Historie ("Was wir wissen") und KI-Recherche ("Was aktuell wahr ist"). +**Kontext:** Neuanfang für die Branche **Robotik & Facility Management**. +**Ziel:** Ablösung von Google Sheets/CLI durch eine Web-App ("Company Explorer") mit SQLite-Backend. -## 14. Detaillierte Logik der neuen Datenfelder (v2.0) +## 1. Strategische Neuausrichtung -... (Kapitel 14 bleibt unverändert) ... +| Bereich | Alt (Legacy) | Neu (Robotics Edition) | +| :--- | :--- | :--- | +| **Daten-Basis** | Google Sheets | **SQLite** (Lokal, performant, filterbar). | +| **Ziel-Daten** | Allgemein / Kundenservice | **Quantifizierbares Potenzial** (z.B. 4500m² Fläche, 120 Betten). | +| **Branchen** | KI-Vorschlag (Freitext) | **Strict Mode:** Mapping auf definierte Notion-Liste (z.B. "Hotellerie", "Automotive"). | +| **Bewertung** | 0-100 Score (Vage) | **Data-Driven:** Rohwert (Scraper/Search) -> Standardisierung (Formel) -> Potenzial. | +| **Analytics** | Techniker-ML-Modell | **Deaktiviert**. Fokus auf harte Fakten. | +| **Operations** | D365 Sync (Broken) | **Excel-Import & Deduplizierung**. Fokus auf Matching externer Listen gegen Bestand. | + +## 2. Architektur & Komponenten-Mapping + +Das System wird in `company-explorer/` neu aufgebaut. Wir lösen Abhängigkeiten zur Root `helpers.py` auf. + +### A. Core Backend (`backend/`) + +| Komponente | Aufgabe & Neue Logik | Prio | +| :--- | :--- | :--- | +| **Database** | Ersetzt `GoogleSheetHandler`. Speichert Firmen & "Enrichment Blobs". | 1 | +| **Importer** | Ersetzt `SyncManager`. Importiert Excel-Dumps (CRM) und Event-Listen. | 1 | +| **Deduplicator** | Ersetzt `company_deduplicator.py`. **Kern-Feature:** Checkt Event-Listen gegen DB. Muss "intelligent" matchen (Name + Ort + Web). | 1 | +| **Scraper (Base)** | Extrahiert Text von Websites. Basis für alle Analysen. | 1 | +| **Classification Service** | **NEU (v0.7.0).** Zweistufige Logik:
1. Strict Industry Classification.
2. Metric Extraction Cascade (Web -> Wiki -> SerpAPI). | 1 | +| **Marketing Engine** | Ersetzt `generate_marketing_text.py`. Nutzt neue `marketing_wissen_robotics.yaml`. | 3 | + +**Identifizierte Hauptdatei:** `company-explorer/backend/app.py` + +### B. Frontend (`frontend/`) - React + +* **View 1: Der "Explorer":** DataGrid aller Firmen. Filterbar nach "Roboter-Potential" und Status. +* **View 2: Der "Inspector":** Detailansicht einer Firma. Zeigt gefundene Signale ("Hat SPA Bereich"). Manuelle Korrektur-Möglichkeit. + * **Identifizierte Komponente:** `company-explorer/frontend/src/components/Inspector.tsx` +* **View 3: "List Matcher":** Upload einer Excel-Liste -> Anzeige von Duplikaten -> Button "Neue importieren". +* **View 4: "Settings":** Konfiguration von Branchen, Rollen und Robotik-Logik. + * **Frontend "Settings" Komponente:** `company-explorer/frontend/src/components/RoboticsSettings.tsx` + +### C. Architekturmuster für die Client-Integration + +Um externen Diensten (wie der `lead-engine`) eine einfache und robuste Anbindung an den `company-explorer` zu ermöglichen, wurde ein standardisiertes Client-Connector-Muster implementiert. + +| Komponente | Aufgabe & Neue Logik | +| :--- | :--- | +| **`company_explorer_connector.py`** | **NEU:** Ein zentrales Python-Skript, das als "offizieller" Client-Wrapper für die API des Company Explorers dient. Es kapselt die Komplexität der asynchronen Enrichment-Prozesse. | +| **`handle_company_workflow()`** | Die Kernfunktion des Connectors. Sie implementiert den vollständigen "Find-or-Create-and-Enrich"-Workflow:
1. **Prüfen:** Stellt fest, ob ein Unternehmen bereits existiert.
2. **Erstellen:** Legt das Unternehmen an, falls es neu ist.
3. **Anstoßen:** Startet den asynchronen `discover`-Prozess.
4. **Warten (Polling):** Überwacht den Status des Unternehmens, bis eine Website gefunden wurde.
5. **Analysieren:** Startet den asynchronen `analyze`-Prozess.
**Vorteil:** Bietet dem aufrufenden Dienst eine einfache, quasi-synchrone Schnittstelle und stellt sicher, dass die Prozessschritte in der korrekten Reihenfolge ausgeführt werden. | + +## 3. Umgang mit Shared Code (`helpers.py` & Co.) + +Wir kapseln das neue Projekt vollständig ab ("Fork & Clean"). + +* **Quelle:** `helpers.py` (Root) +* **Ziel:** `company-explorer/backend/lib/core_utils.py` +* **Aktion:** Wir kopieren nur relevante Teile und ergänzen sie (z.B. `safe_eval_math`, `run_serp_search`). + +## 4. Datenstruktur (SQLite Schema) + +### Tabelle `companies` (Stammdaten & Analyse) +* `id` (PK) +* `name` (String) +* `website` (String) +* `crm_id` (String, nullable - Link zum D365) +* `industry_crm` (String - Die "erlaubte" Branche aus Notion) +* `city` (String) +* `country` (String - Standard: "DE" oder aus Impressum) +* `status` (Enum: NEW, IMPORTED, ENRICHED, QUALIFIED) +* **NEU (v0.7.0):** + * `calculated_metric_name` (String - z.B. "Anzahl Betten") + * `calculated_metric_value` (Float - z.B. 180) + * `calculated_metric_unit` (String - z.B. "Betten") + * `standardized_metric_value` (Float - z.B. 4500) + * `standardized_metric_unit` (String - z.B. "m²") + * `metric_source` (String - "website", "wikipedia", "serpapi") + +### Tabelle `signals` (Deprecated) +* *Veraltet ab v0.7.0. Wird durch quantitative Metriken in `companies` ersetzt.* + +### Tabelle `contacts` (Ansprechpartner) +* `id` (PK) +* `account_id` (FK -> companies.id) +* `gender`, `title`, `first_name`, `last_name`, `email` +* `job_title` (Visitenkarte) +* `role` (Standardisierte Rolle: "Operativer Entscheider", etc.) +* `status` (Marketing Status) + +### Tabelle `industries` (Branchen-Fokus - Synced from Notion) +* `id` (PK) +* `notion_id` (String, Unique) +* `name` (String - "Vertical" in Notion) +* `description` (Text - "Definition" in Notion) +* `metric_type` (String - "Metric Type") +* `min_requirement` (Float - "Min. Requirement") +* `whale_threshold` (Float - "Whale Threshold") +* `proxy_factor` (Float - "Proxy Factor") +* `scraper_search_term` (String - "Scraper Search Term") +* `scraper_keywords` (Text - "Scraper Keywords") +* `standardization_logic` (String - "Standardization Logic") + +### Tabelle `job_role_mappings` (Rollen-Logik) +* `id` (PK) +* `pattern` (String - Regex für Jobtitles) +* `role` (String - Zielrolle) + +## 7. Historie & Fixes (Jan 2026) + + * **[CRITICAL] v0.7.4: Service Restoration & Logic Fix (Jan 24, 2026)** + * **[STABILITY] v0.7.3: Hardening Metric Parser & Regression Testing (Jan 23, 2026)** + * **[STABILITY] v0.7.2: Robust Metric Parsing (Jan 23, 2026)** + * **[STABILITY] v0.7.1: AI Robustness & UI Fixes (Jan 21, 2026)** + * **[MAJOR] v0.7.0: Quantitative Potential Analysis (Jan 20, 2026)** + * **[UPGRADE] v0.6.x: Notion Integration & UI Improvements** + +## 14. Upgrade v2.0 (Feb 18, 2026): "Lead-Fabrik" Erweiterung + +Dieses Upgrade transformiert den Company Explorer in das zentrale Gehirn der Lead-Generierung (Vorratskammer). + +### 14.1 Detaillierte Logik der neuen Datenfelder + +Um Gemini CLI (dem Bautrupp) die Umsetzung zu ermöglichen, hier die semantische Bedeutung der neuen Spalten: + +#### Tabelle `companies` (Qualitäts- & Abgleich-Metriken) + +* **`confidence_score` (FLOAT, 0.0 - 1.0):** Indikator für die Sicherheit der KI-Klassifizierung. `> 0.8` = Grün. +* **`data_mismatch_score` (FLOAT, 0.0 - 1.0):** Abweichung zwischen CRM-Bestand und Web-Recherche (z.B. Umzug). +* **`crm_name`, `crm_address`, `crm_website`, `crm_vat`:** Read-Only Snapshot aus SuperOffice zum Vergleich. +* **Status-Flags:** `website_scrape_status` und `wiki_search_status`. + +#### Tabelle `industries` (Strategie-Parameter) + +* **`pains` / `gains`:** Strukturierte Textblöcke (getrennt durch `[Primary Product]` und `[Secondary Product]`). +* **`ops_focus_secondary` (BOOLEAN):** Steuerung für rollenspezifische Produkt-Priorisierung. + +--- ## 15. Offene Arbeitspakete (Bauleitung) -### Task 1: UI-Implementierung "Data Match & Strategy" +Anweisungen für den "Bautrupp" (Gemini CLI). + +### Task 1: UI-Anpassung - Side-by-Side CRM View & Settings (In Arbeit / Teilweise erledigt durch Gemini CLI) ### Task 2: Intelligenter CRM-Importer (Bestandsdaten) -**Ziel:** Importieren der `demo_100.xlsx` in die SQLite-Datenbank unter Berücksichtigung von Dubletten und Datenqualität. +**Ziel:** Importieren der `demo_100.xlsx` in die SQLite-Datenbank. -**Dateien:** -* `company-explorer/backend/scripts/ingest_superoffice_excel.py` +**Anforderungen:** +1. **PLZ-Handling:** Zwingend als **String** einlesen (führende Nullen erhalten). +2. **Normalisierung:** Website bereinigen (kein `www.`, `https://`). +3. **Matching:** Kaskade über CRM-ID, VAT, Domain, Fuzzy Name. +4. **Isolierung:** Nur `crm_` Spalten updaten, Golden Records unberührt lassen. -**Anforderungen & Logik:** +--- -1. **Dateihandling:** - * Nutze `openpyxl` (oder `pandas`, falls im Container installiert). - * **WICHTIG:** Die Spalte `PLZ` muss zwingend als **String** eingelesen werden, um führende Nullen (z.B. 01234) zu erhalten. - * Normalisiere die Spalte `Website`: Entferne `https://`, `http://`, `www.` und abschließende Slashes. - -2. **Matching-Logik (Deduplizierung):** - * Suche in Tabelle `companies` nach: - * a) `crm_id` (falls in DB bereits vorhanden). - * b) `crm_vat` (Ust-ID Match). - * c) Normalisierte Domain (Website). - * d) Fuzzy Name + Stadt (Score < 1.0). - -3. **Update-Prozess:** - * **Match gefunden:** Befülle nur die `crm_*` Spalten (`crm_name`, `crm_address`, `crm_website`). Ändere NICHT die Felder `name` oder `website`, falls diese schon durch Recherche befüllt wurden. - * **Kein Match:** Lege neuen Record an. Kopiere CRM-Werte initial in `crm_*` UND in die Golden-Record Felder (`name`, `website`). - * **Status:** Setze `status` auf `TO_ENRICH`. - -4. **Länder-Fokus:** - * Gehe davon aus, dass alle Leads für den deutschen Markt sind (`country="DE"`). - -**Akzeptanzkriterien:** -* Skript läuft ohne Fehler durch. -* In der SQLite-DB sind die `crm_` Felder befüllt. -* Führende Nullen bei PLZ bleiben erhalten. +## 16. Deployment-Referenz (NAS) +* **Pfad:** `/volume1/homes/Floke/python/brancheneinstufung/company-explorer` +* **DB:** `/app/companies_v3_fixed_2.db` +* **Sync:** `docker exec -it company-explorer python backend/scripts/sync_notion_to_ce_enhanced.py` diff --git a/company-explorer/MIGRATION_PLAN.md b/company-explorer/MIGRATION_PLAN.md index 2e0b9361..a985d8b9 100644 --- a/company-explorer/MIGRATION_PLAN.md +++ b/company-explorer/MIGRATION_PLAN.md @@ -1,47 +1,161 @@ # Migrations-Plan: Legacy GSheets -> Company Explorer (Robotics Edition v0.8.5) -**Kontext:** Strategische Neuausrichtung der Lead-Analyse für RoboPlanet. -**Zentrale Philosophie:** Trennung von CRM-Historie ("Was wir wissen") und KI-Recherche ("Was aktuell wahr ist"). +**Kontext:** Neuanfang für die Branche **Robotik & Facility Management**. +**Ziel:** Ablösung von Google Sheets/CLI durch eine Web-App ("Company Explorer") mit SQLite-Backend. -## 14. Detaillierte Logik der neuen Datenfelder (v2.0) +## 1. Strategische Neuausrichtung -... (Kapitel 14 bleibt unverändert) ... +| Bereich | Alt (Legacy) | Neu (Robotics Edition) | +| :--- | :--- | :--- | +| **Daten-Basis** | Google Sheets | **SQLite** (Lokal, performant, filterbar). | +| **Ziel-Daten** | Allgemein / Kundenservice | **Quantifizierbares Potenzial** (z.B. 4500m² Fläche, 120 Betten). | +| **Branchen** | KI-Vorschlag (Freitext) | **Strict Mode:** Mapping auf definierte Notion-Liste (z.B. "Hotellerie", "Automotive"). | +| **Bewertung** | 0-100 Score (Vage) | **Data-Driven:** Rohwert (Scraper/Search) -> Standardisierung (Formel) -> Potenzial. | +| **Analytics** | Techniker-ML-Modell | **Deaktiviert**. Fokus auf harte Fakten. | +| **Operations** | D365 Sync (Broken) | **Excel-Import & Deduplizierung**. Fokus auf Matching externer Listen gegen Bestand. | + +## 2. Architektur & Komponenten-Mapping + +Das System wird in `company-explorer/` neu aufgebaut. Wir lösen Abhängigkeiten zur Root `helpers.py` auf. + +### A. Core Backend (`backend/`) + +| Komponente | Aufgabe & Neue Logik | Prio | +| :--- | :--- | :--- | +| **Database** | Ersetzt `GoogleSheetHandler`. Speichert Firmen & "Enrichment Blobs". | 1 | +| **Importer** | Ersetzt `SyncManager`. Importiert Excel-Dumps (CRM) und Event-Listen. | 1 | +| **Deduplicator** | Ersetzt `company_deduplicator.py`. **Kern-Feature:** Checkt Event-Listen gegen DB. Muss "intelligent" matchen (Name + Ort + Web). | 1 | +| **Scraper (Base)** | Extrahiert Text von Websites. Basis für alle Analysen. | 1 | +| **Classification Service** | **NEU (v0.7.0).** Zweistufige Logik:
1. Strict Industry Classification.
2. Metric Extraction Cascade (Web -> Wiki -> SerpAPI). | 1 | +| **Marketing Engine** | Ersetzt `generate_marketing_text.py`. Nutzt neue `marketing_wissen_robotics.yaml`. | 3 | + +**Identifizierte Hauptdatei:** `company-explorer/backend/app.py` + +### B. Frontend (`frontend/`) - React + +* **View 1: Der "Explorer":** DataGrid aller Firmen. Filterbar nach "Roboter-Potential" und Status. +* **View 2: Der "Inspector":** Detailansicht einer Firma. Zeigt gefundene Signale ("Hat SPA Bereich"). Manuelle Korrektur-Möglichkeit. + * **Identifizierte Komponente:** `company-explorer/frontend/src/components/Inspector.tsx` +* **View 3: "List Matcher":** Upload einer Excel-Liste -> Anzeige von Duplikaten -> Button "Neue importieren". +* **View 4: "Settings":** Konfiguration von Branchen, Rollen und Robotik-Logik. + * **Frontend "Settings" Komponente:** `company-explorer/frontend/src/components/RoboticsSettings.tsx` + +### C. Architekturmuster für die Client-Integration + +Um externen Diensten (wie der `lead-engine`) eine einfache und robuste Anbindung an den `company-explorer` zu ermöglichen, wurde ein standardisiertes Client-Connector-Muster implementiert. + +| Komponente | Aufgabe & Neue Logik | +| :--- | :--- | +| **`company_explorer_connector.py`** | **NEU:** Ein zentrales Python-Skript, das als "offizieller" Client-Wrapper für die API des Company Explorers dient. Es kapselt die Komplexität der asynchronen Enrichment-Prozesse. | +| **`handle_company_workflow()`** | Die Kernfunktion des Connectors. Sie implementiert den vollständigen "Find-or-Create-and-Enrich"-Workflow:
1. **Prüfen:** Stellt fest, ob ein Unternehmen bereits existiert.
2. **Erstellen:** Legt das Unternehmen an, falls es neu ist.
3. **Anstoßen:** Startet den asynchronen `discover`-Prozess.
4. **Warten (Polling):** Überwacht den Status des Unternehmens, bis eine Website gefunden wurde.
5. **Analysieren:** Startet den asynchronen `analyze`-Prozess.
**Vorteil:** Bietet dem aufrufenden Dienst eine einfache, quasi-synchrone Schnittstelle und stellt sicher, dass die Prozessschritte in der korrekten Reihenfolge ausgeführt werden. | + +## 3. Umgang mit Shared Code (`helpers.py` & Co.) + +Wir kapseln das neue Projekt vollständig ab ("Fork & Clean"). + +* **Quelle:** `helpers.py` (Root) +* **Ziel:** `company-explorer/backend/lib/core_utils.py` +* **Aktion:** Wir kopieren nur relevante Teile und ergänzen sie (z.B. `safe_eval_math`, `run_serp_search`). + +## 4. Datenstruktur (SQLite Schema) + +### Tabelle `companies` (Stammdaten & Analyse) +* `id` (PK) +* `name` (String) +* `website` (String) +* `crm_id` (String, nullable - Link zum D365) +* `industry_crm` (String - Die "erlaubte" Branche aus Notion) +* `city` (String) +* `country` (String - Standard: "DE" oder aus Impressum) +* `status` (Enum: NEW, IMPORTED, ENRICHED, QUALIFIED) +* **NEU (v0.7.0):** + * `calculated_metric_name` (String - z.B. "Anzahl Betten") + * `calculated_metric_value` (Float - z.B. 180) + * `calculated_metric_unit` (String - z.B. "Betten") + * `standardized_metric_value` (Float - z.B. 4500) + * `standardized_metric_unit` (String - z.B. "m²") + * `metric_source` (String - "website", "wikipedia", "serpapi") + +### Tabelle `signals` (Deprecated) +* *Veraltet ab v0.7.0. Wird durch quantitative Metriken in `companies` ersetzt.* + +### Tabelle `contacts` (Ansprechpartner) +* `id` (PK) +* `account_id` (FK -> companies.id) +* `gender`, `title`, `first_name`, `last_name`, `email` +* `job_title` (Visitenkarte) +* `role` (Standardisierte Rolle: "Operativer Entscheider", etc.) +* `status` (Marketing Status) + +### Tabelle `industries` (Branchen-Fokus - Synced from Notion) +* `id` (PK) +* `notion_id` (String, Unique) +* `name` (String - "Vertical" in Notion) +* `description` (Text - "Definition" in Notion) +* `metric_type` (String - "Metric Type") +* `min_requirement` (Float - "Min. Requirement") +* `whale_threshold` (Float - "Whale Threshold") +* `proxy_factor` (Float - "Proxy Factor") +* `scraper_search_term` (String - "Scraper Search Term") +* `scraper_keywords` (Text - "Scraper Keywords") +* `standardization_logic` (String - "Standardization Logic") + +### Tabelle `job_role_mappings` (Rollen-Logik) +* `id` (PK) +* `pattern` (String - Regex für Jobtitles) +* `role` (String - Zielrolle) + +## 7. Historie & Fixes (Jan 2026) + + * **[CRITICAL] v0.7.4: Service Restoration & Logic Fix (Jan 24, 2026)** + * **[STABILITY] v0.7.3: Hardening Metric Parser & Regression Testing (Jan 23, 2026)** + * **[STABILITY] v0.7.2: Robust Metric Parsing (Jan 23, 2026)** + * **[STABILITY] v0.7.1: AI Robustness & UI Fixes (Jan 21, 2026)** + * **[MAJOR] v0.7.0: Quantitative Potential Analysis (Jan 20, 2026)** + * **[UPGRADE] v0.6.x: Notion Integration & UI Improvements** + +## 14. Upgrade v2.0 (Feb 18, 2026): "Lead-Fabrik" Erweiterung + +Dieses Upgrade transformiert den Company Explorer in das zentrale Gehirn der Lead-Generierung (Vorratskammer). + +### 14.1 Detaillierte Logik der neuen Datenfelder + +Um Gemini CLI (dem Bautrupp) die Umsetzung zu ermöglichen, hier die semantische Bedeutung der neuen Spalten: + +#### Tabelle `companies` (Qualitäts- & Abgleich-Metriken) + +* **`confidence_score` (FLOAT, 0.0 - 1.0):** Indikator für die Sicherheit der KI-Klassifizierung. `> 0.8` = Grün. +* **`data_mismatch_score` (FLOAT, 0.0 - 1.0):** Abweichung zwischen CRM-Bestand und Web-Recherche (z.B. Umzug). +* **`crm_name`, `crm_address`, `crm_website`, `crm_vat`:** Read-Only Snapshot aus SuperOffice zum Vergleich. +* **Status-Flags:** `website_scrape_status` und `wiki_search_status`. + +#### Tabelle `industries` (Strategie-Parameter) + +* **`pains` / `gains`:** Strukturierte Textblöcke (getrennt durch `[Primary Product]` und `[Secondary Product]`). +* **`ops_focus_secondary` (BOOLEAN):** Steuerung für rollenspezifische Produkt-Priorisierung. + +--- ## 15. Offene Arbeitspakete (Bauleitung) -### Task 1: UI-Implementierung "Data Match & Strategy" +Anweisungen für den "Bautrupp" (Gemini CLI). + +### Task 1: UI-Anpassung - Side-by-Side CRM View & Settings (In Arbeit / Teilweise erledigt durch Gemini CLI) ### Task 2: Intelligenter CRM-Importer (Bestandsdaten) -**Ziel:** Importieren der `demo_100.xlsx` in die SQLite-Datenbank unter Berücksichtigung von Dubletten und Datenqualität. +**Ziel:** Importieren der `demo_100.xlsx` in die SQLite-Datenbank. -**Dateien:** -* `company-explorer/backend/scripts/ingest_superoffice_excel.py` +**Anforderungen:** +1. **PLZ-Handling:** Zwingend als **String** einlesen (führende Nullen erhalten). +2. **Normalisierung:** Website bereinigen (kein `www.`, `https://`). +3. **Matching:** Kaskade über CRM-ID, VAT, Domain, Fuzzy Name. +4. **Isolierung:** Nur `crm_` Spalten updaten, Golden Records unberührt lassen. -**Anforderungen & Logik:** +--- -1. **Dateihandling:** - * Nutze `openpyxl` (oder `pandas`, falls im Container installiert). - * **WICHTIG:** Die Spalte `PLZ` muss zwingend als **String** eingelesen werden, um führende Nullen (z.B. 01234) zu erhalten. - * Normalisiere die Spalte `Website`: Entferne `https://`, `http://`, `www.` und abschließende Slashes. - -2. **Matching-Logik (Deduplizierung):** - * Suche in Tabelle `companies` nach: - * a) `crm_id` (falls in DB bereits vorhanden). - * b) `crm_vat` (Ust-ID Match). - * c) Normalisierte Domain (Website). - * d) Fuzzy Name + Stadt (Score < 1.0). - -3. **Update-Prozess:** - * **Match gefunden:** Befülle nur die `crm_*` Spalten (`crm_name`, `crm_address`, `crm_website`). Ändere NICHT die Felder `name` oder `website`, falls diese schon durch Recherche befüllt wurden. - * **Kein Match:** Lege neuen Record an. Kopiere CRM-Werte initial in `crm_*` UND in die Golden-Record Felder (`name`, `website`). - * **Status:** Setze `status` auf `TO_ENRICH`. - -4. **Länder-Fokus:** - * Gehe davon aus, dass alle Leads für den deutschen Markt sind (`country="DE"`). - -**Akzeptanzkriterien:** -* Skript läuft ohne Fehler durch. -* In der SQLite-DB sind die `crm_` Felder befüllt. -* Führende Nullen bei PLZ bleiben erhalten. +## 16. Deployment-Referenz (NAS) +* **Pfad:** `/volume1/homes/Floke/python/brancheneinstufung/company-explorer` +* **DB:** `/app/companies_v3_fixed_2.db` +* **Sync:** `docker exec -it company-explorer python backend/scripts/sync_notion_to_ce_enhanced.py`