# Migrations-Plan: Legacy GSheets -> Company Explorer (Robotics Edition v0.7.0) **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. ## 1. Strategische Neuausrichtung | 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 | ### 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. * **View 3: "List Matcher":** Upload einer Excel-Liste -> Anzeige von Duplikaten -> Button "Neue importieren". * **View 4: "Settings":** Konfiguration von Branchen, Rollen und Robotik-Logik. ## 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) * **[MAJOR] v0.7.0: Quantitative Potential Analysis (Jan 20, 2026)** * **Zweistufige Analyse:** 1. **Strict Classification:** Ordnet Firmen einer Notion-Branche zu (oder "Others"). 2. **Metric Cascade:** Sucht gezielt nach der branchenspezifischen Metrik ("Scraper Search Term"). * **Fallback-Kaskade:** Website -> Wikipedia -> SerpAPI (Google Search). * **Standardisierung:** Berechnet vergleichbare Werte (z.B. m²) aus Rohdaten mit der `Standardization Logic`. * **Datenbank:** Erweiterung der `companies`-Tabelle um Metrik-Felder, Deprecation der `signals`-Tabelle. * **[UPGRADE] v0.6.1: Notion Sync Fixes** * **Mapping:** Korrektur des Mappings für `Metric Type` und `Scraper Search Term` (Notion Select Fields). * **Truncate-and-Reload:** Sync-Skript löscht alte Daten vor dem Import (für `industries`), behält aber `robotics_categories` bei (Upsert), um FK-Constraints zu schützen. * **Frontend:** Korrektur der Einheiten-Anzeige ("Unit") im Settings-Dialog. * **[UPGRADE] v0.6.0: Notion Single Source of Truth** * Synchronisation von Branchen und Kategorien direkt aus Notion. * **[UPGRADE] v0.5.1: Robustness** * Logging, Wikipedia-Optimierung, UI-Fixes. ## 8. Eingesetzte Prompts (Account-Analyse v0.7.0) ### 8.1 Strict Industry Classification Ordnet das Unternehmen einer definierten Branche zu. ```python prompt = r""" Du bist ein präziser Branchen-Klassifizierer. ... --- ZU VERWENDENDE BRANCHEN-DEFINITIONEN (STRIKT) --- {industry_definitions_json} ... Wähle EINE der folgenden Branchen... Wenn keine zutrifft, wähle "Others". """ ``` ### 8.2 Metric Extraction Extrahiert den spezifischen Zahlenwert ("Scraper Search Term"). ```python prompt = r""" Analysiere den folgenden Text... --- KONTEXT --- Branche: {industry_name} Gesuchter Wert: '{search_term}' ... Gib NUR ein JSON-Objekt zurück: 'raw_value', 'raw_unit', 'area_value' (falls explizit m² genannt). """ ``` ## 9. Notion Integration Das System nutzt Notion als SSoT für `Industries` und `RoboticsCategories`. Sync-Skript: `backend/scripts/sync_notion_industries.py`. ## 10. Database Migration Bei Schema-Änderungen ohne Datenverlust: `backend/scripts/migrate_db.py`.