docs: finalized MIGRATION_PLAN with DB schema and CLI tasks

This commit is contained in:
Moltbot-Jarvis
2026-02-18 12:32:20 +00:00
parent 3c5ce2d048
commit 955a0cbe7f

View File

@@ -108,176 +108,74 @@ Wir kapseln das neue Projekt vollständig ab ("Fork & Clean").
## 7. Historie & Fixes (Jan 2026)
* **[CRITICAL] v0.7.4: Service Restoration & Logic Fix (Jan 24, 2026)**
* **Summary:** Identified and resolved a critical issue where `ClassificationService` contained empty placeholder methods (`pass`), leading to "Others" classification and missing metrics.
* **Fixes Implemented:**
* **Service Restoration:** Completely re-implemented `classify_company_potential`, `_run_llm_classification_prompt`, and `_run_llm_metric_extraction_prompt` to restore AI functionality using `call_gemini_flash`.
* **Standardization Logic:** Connected the `standardization_logic` formula parser (e.g., "Values * 100m²") into the metric extraction cascade. It now correctly computes `standardized_metric_value` (e.g., 352 beds -> 35,200 m²).
* **Verification:** Confirmed end-to-end flow from "New Company" -> "Healthcare - Hospital" -> "352 Betten" -> "35.200 m²" via the UI "Play" button.
* **[STABILITY] v0.7.3: Hardening Metric Parser & Regression Testing (Jan 23, 2026)**
* **Summary:** A series of critical fixes were applied to the `MetricParser` to handle complex real-world scenarios, and a regression test suite was created to prevent future issues.
* **Specific Bug Fixes:**
* **Wolfra Bug ("802020"):** Logic to detect and remove trailing years from concatenated numbers (e.g., "Mitarbeiter: 802020" -> "80").
* **Erding Bug ("Year Prefix"):** Logic to ignore year-like prefixes appearing before the actual metric (e.g., "Seit 2022 ... 200.000 Besucher").
* **Greilmeier Bug ("Truncation"):** Removed aggressive sentence splitting on hyphens that was truncating text and causing the parser to miss numbers at the end of a phrase.
* **Expected Value Cleaning:** The parser now aggressively strips units (like "m²") from the LLM's `expected_value` to ensure it can find the correct numeric target even if the source text contains multiple numbers.
* **Regression Test Suite:** Created `/backend/tests/test_metric_parser.py` to lock in these fixes.
* **[STABILITY] v0.7.2: Robust Metric Parsing (Jan 23, 2026)**
* **Legacy Logic Restored:** Re-implemented the robust, regex-based number parsing logic (formerly in legacy helpers) as `MetricParser`.
* **German Formats:** Correctly handles "1.000" (thousands) vs "1,5" (decimal) and mixed formats.
* **Citation Cleaning:** Filters out Wikipedia citations like `[3]` and years in parentheses (e.g. "80 (2020)" -> 80).
* **Hybrid Extraction:** The ClassificationService now asks the LLM for the *text segment* and parses the number deterministically, fixing "LLM Hallucinations" (e.g. "1.005" -> 1).
* **[STABILITY] v0.7.1: AI Robustness & UI Fixes (Jan 21, 2026)**
* **SDK Stabilität:** Umstellung auf `gemini-2.0-flash` im Legacy-SDK zur Behebung von `404 Not Found` Fehlern.
* **API-Key Management:** Robustes Laden des Keys aus `/app/gemini_api_key.txt`.
* **Classification Prompt:** Schärfung auf "Best-Fit"-Entscheidungen (kein vorzeitiges "Others").
* **Scraping:** Wechsel auf `BeautifulSoup` nach Problemen mit `trafilatura`.
* **[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.
* **[UPGRADE] v0.6.x: Notion Integration & UI Improvements**
* **Notion SSoT:** Umstellung der Branchenverwaltung (`Industries`) auf Notion.
* **Sync Automation:** `backend/scripts/sync_notion_industries.py`.
* **Contacts Management:** Globale Kontaktliste, Bulk-Import, Marketing-Status.
* **UI Overhaul:** Light/Dark Mode, Grid View, Responsive Design.
## 8. Eingesetzte Prompts (Account-Analyse v0.7.4)
## 14. Upgrade v2.0 (Feb 18, 2026): "Lead-Fabrik" Erweiterung
### 8.1 Strict Industry Classification
Dieses Upgrade transformiert den Company Explorer in das zentrale Gehirn der Lead-Generierung.
Ordnet das Unternehmen einer definierten Branche zu.
### 14.1 Detaillierte Datenmodell-Erweiterung
```python
prompt = f"""
Act as a strict B2B Industry Classifier.
Company: {company_name}
Context: {website_text[:3000]}
#### Tabelle: `companies`
Um Bestandsdaten sauber von KI-Ergebnissen zu trennen, wurden folgende Spalten hinzugefügt:
Available Industries:
{json.dumps(industry_definitions, indent=2)}
* **`crm_name`** (TEXT): Name des Unternehmens im CRM.
* **`crm_website`** (TEXT): Website-URL im CRM.
* **`crm_address`** (TEXT): Adresse im CRM (Straße, PLZ, Stadt).
* **`crm_vat`** (TEXT): Umsatzsteuer-ID im CRM.
* **`confidence_score`** (FLOAT): Gesamt-Konfidenz der KI-Analyse (0.0 - 1.0).
* **`data_mismatch_score`** (FLOAT): Grad der Abweichung zwischen CRM- und KI-Daten (0.0 = Match, 1.0 = kompletter Mismatch).
* **`website_scrape_status`** (TEXT): Status der Website-Analyse (`PENDING`, `SUCCESS`, `FAILED`, `BLOCKED`).
* **`wiki_search_status`** (TEXT): Status der Wikipedia-Suche (`PENDING`, `FOUND`, `NOT_FOUND`).
Task: Select the ONE industry that best matches the company.
If the company is a Hospital/Klinik, select 'Healthcare - Hospital'.
If none match well, select 'Others'.
#### Tabelle: `industries`
Erweiterung um strategische Inhalte aus Notion (Voraussetzung für Sniper-Texte):
Return ONLY the exact name of the industry.
"""
```
### 8.2 Metric Extraction
Extrahiert den spezifischen Zahlenwert ("Scraper Search Term") und liefert JSON für den `MetricParser`.
```python
prompt = f"""
Extract the following metric for the company in industry '{industry_name}':
Target Metric: "{search_term}"
Source Text:
{text_content[:6000]}
Return a JSON object with:
- "raw_value": The number found (e.g. 352 or 352.0). If text says "352 Betten", extract 352. If not found, null.
- "raw_unit": The unit found (e.g. "Betten", "").
- "proof_text": A short quote from the text proving this value.
JSON ONLY.
"""
```
## 9. Notion Integration (Single Source of Truth)
Das System nutzt Notion als zentrales Steuerungselement für strategische Definitionen.
### 9.1 Datenfluss
1. **Definition:** Branchen und Robotik-Kategorien werden in Notion gepflegt (Whale Thresholds, Keywords, Definitionen).
2. **Synchronisation:** Das Skript `sync_notion_industries.py` zieht die Daten via API und führt einen Upsert in die lokale SQLite-Datenbank aus.
3. **App-Nutzung:** Das Web-Interface zeigt diese Daten schreibgeschützt an. Der `ClassificationService` nutzt sie als "System-Anweisung" für das LLM.
### 9.2 Technische Details
* **Notion Token:** Muss in `/app/notion_token.txt` (Container-Pfad) hinterlegt sein.
* **DB-Mapping:** Die Zuordnung erfolgt primär über die `notion_id`, sekundär über den Namen, um Dubletten bei der Migration zu vermeiden.
## 10. Database Migration
Wenn die `industries`-Tabelle in einer bestehenden Datenbank aktualisiert werden muss (z.B. um neue Felder aus Notion zu unterstützen), darf die Datenbankdatei **nicht** gelöscht werden. Stattdessen muss das Migrations-Skript ausgeführt werden.
**Prozess:**
1. **Sicherstellen, dass die Zieldatenbank vorhanden ist:** Die `companies_v3_fixed_2.db` muss im `company-explorer`-Verzeichnis liegen (bzw. via Volume gemountet sein).
2. **Migration ausführen:** Dieser Befehl fügt die fehlenden Spalten hinzu, ohne Daten zu löschen.
```bash
docker exec -it company-explorer python3 backend/scripts/migrate_db.py
```
3. **Container neu starten:** Damit der Server das neue Schema erkennt.
```bash
docker-compose restart company-explorer
```
4. **Notion-Sync ausführen:** Um die neuen Spalten mit Daten zu befüllen.
```bash
docker exec -it company-explorer python3 backend/scripts/sync_notion_industries.py
```
## 11. Lessons Learned (Retrospektive Jan 24, 2026)
1. **API-Routing-Reihenfolge (FastAPI):** Ein spezifischer Endpunkt (z.B. `/api/companies/export`) muss **vor** einem dynamischen Endpunkt (z.B. `/api/companies/{company_id}`) deklariert werden. Andernfalls interpretiert FastAPI "export" als eine `company_id`, was zu einem `422 Unprocessable Entity` Fehler führt.
2. **Nginx `proxy_pass` Trailing Slash:** Das Vorhandensein oder Fehlen eines `/` am Ende der `proxy_pass`-URL in Nginx ist kritisch. Für Dienste wie FastAPI, die mit einem `root_path` (z.B. `/ce`) laufen, darf **kein** Trailing Slash verwendet werden (`proxy_pass http://company-explorer:8000;`), damit der `root_path` in der an das Backend weitergeleiteten Anfrage erhalten bleibt.
3. **Docker-Datenbank-Persistenz:** Das Fehlen eines expliziten Volume-Mappings für die Datenbankdatei in `docker-compose.yml` führt dazu, dass der Container eine interne, ephemere Kopie der Datenbank verwendet. Alle Änderungen, die außerhalb des Containers an der "Host"-DB vorgenommen werden, sind für die Anwendung unsichtbar. Es ist zwingend erforderlich, ein Mapping wie `./companies_v3_fixed_2.db:/app/companies_v3_fixed_2.db` zu definieren.
4. **Code-Integrität & Platzhalter:** Es ist kritisch, bei Datei-Operationen sicherzustellen, dass keine Platzhalter (wie `pass` oder `# omitted`) in den produktiven Code gelangen. Eine "Zombie"-Datei, die äußerlich korrekt aussieht aber innerlich leer ist, kann schwer zu debuggende Logikfehler verursachen.
5. **Formel-Robustheit:** Formeln aus externen Quellen müssen vor der Auswertung bereinigt werden (Entfernung von Einheiten, Kommentaren), um Syntax-Fehler zu vermeiden.
## 12. Deployment & Access Notes
## 13. Task [2f388f42]: Report mistakes
### Aufgabenbeschreibung:
When a user notices an error on an account, such as a wrong value he should have the option to mark this mistake (specify whihch value is wrong) and add a link to the source and a quote option as well as a comment why the user prefers the information above the information found by the llm in the first place. These corrections should be collected in a database for later review. The database will be displayed in the settings.
The review shall happen by a sepcific checker-Process which should process the information and include the information into the research process to improve the search quality over time.
### Detaillierter Plan:
**Phase 1: Backend & Datenbank**
1. **Neue Datenbank-Tabelle:** Ich werde eine neue Tabelle `reported_mistakes` in der SQLite-Datenbank erstellen. Sie wird Spalten für die `company_id` (FK), den `field_name` (String), den `wrong_value` (Text), den `corrected_value` (Text), die `source_url` (String), das `quote` (Text), den `user_comment` (Text) und einen `status` (Enum: `PENDING`, `APPROVED`, `REJECTED`, Standard: `PENDING`) sowie `created_at` (Timestamp) und `updated_at` (Timestamp) enthalten.
2. **API-Endpunkt zum Melden (POST):** Ich erstelle einen neuen `POST /api/companies/{company_id}/report-mistake` Endpunkt in `company-explorer/backend/app.py`, der die gemeldeten Fehler entgegennimmt und in der neuen Tabelle speichert.
3. **API-Endpunkt zum Anzeigen (GET):** Ich füge einen `GET /api/mistakes` Endpunkt in `company-explorer/backend/app.py` hinzu, der alle gemeldeten Fehler (oder gefilterte nach Status) für die Anzeige auf der Einstellungsseite abruft.
4. **API-Endpunkt zum Aktualisieren (PUT):** Ich füge einen `PUT /api/mistakes/{mistake_id}` Endpunkt in `company-explorer/backend/app.py` hinzu, um den Status eines gemeldeten Fehlers (z.B. `APPROVED`, `REJECTED`) zu aktualisieren.
**Phase 2: Frontend (React)**
5. **Benutzeroberfläche zum Melden:** In der `Inspector.tsx` Komponente (`company-explorer/frontend/src/components/Inspector.tsx`) werde ich neben den wichtigsten Datenfeldern ein kleines "Fehler melden"-Icon hinzufügen. Ein Klick darauf öffnet ein Modalfenster/Formular, in das der Benutzer die Korrekturinformationen (Feldname, falscher Wert, korrigierter Wert, URL, Zitat, Kommentar) eingeben kann.
6. **Anzeige in den Einstellungen:** Im Einstellungsbereich, wahrscheinlich in `RoboticsSettings.tsx` (`company-explorer/frontend/src/components/RoboticsSettings.tsx`), wird ein neuer Tab "Gemeldete Fehler" oder eine neue Sektion hinzugefügt. Dort wird eine Tabelle alle Einträge aus der `reported_mistakes`-Tabelle anzeigen, mit Optionen zum Filtern nach Status und zur Interaktion (z.B. Genehmigen/Ablehnen).
**Phase 3: Prüfprozess & Ausblick**
7. **Manueller Prüf-Workflow:** Die Tabelle in den Einstellungen wird um "Genehmigen"- und "Ablehnen"-Buttons erweitert. Ein Prüfer kann damit den Status jeder Meldung aktualisieren. Dies wird über den `PUT /api/mistakes/{mistake_id}` Endpunkt umgesetzt.
8. **Konzept für die Zukunft:** Die gesammelten und genehmigten Korrekturen bilden die Grundlage für eine spätere, automatisierte Verbesserung. Dies könnte beinhalten:
* **LLM Fine-Tuning/Prompt-Verbesserung:** Genehmigte Korrekturen können als Beispiele für das Training oder die Kontextualisierung von LLM-Prompts verwendet werden, um die Genauigkeit der Datenextraktion zu verbessern.
* **Scraping-Regel-Anpassung:** Systematische Fehler, die durch gemeldete Fehler identifiziert werden, könnten zur Anpassung von Scraping-Regeln oder Parser-Logik führen.
* **Automatisierte Datenkorrektur:** Bei einer hohen Konfidenz könnten genehmigte Korrekturen direkt in die `companies`-Tabelle zurückgeschrieben werden.
### Wichtige Erkenntnisse zur Umsetzung:
* **Backend-Hauptdatei:** `company-explorer/backend/app.py`
* **Frontend "Inspector" Komponente:** `company-explorer/frontend/src/components/Inspector.tsx`
* **Frontend "Settings" Komponente:** `company-explorer/frontend/src/components/RoboticsSettings.tsx`
* **`pains`** (TEXT): Branchenspezifische Schmerzpunkte.
* **`gains`** (TEXT): Branchenspezifische Nutzungsversprechen.
* **`priority`** (TEXT): Strategischer Status (z.B. "Freigegeben", "Klärungsbedarf").
* **`notes`** (TEXT): Interne Anmerkungen zur Branche.
* **`ops_focus_secondary`** (BOOLEAN): Flag, ob für operative Rollen das Sekundärprodukt priorisiert werden soll.
* **`secondary_category_id`** (INTEGER): Fremdschlüssel auf das alternative Produkt.
---
## 15. Offene Arbeitspakete (Bauleitung)
**Wichtiger Hinweis zum Deployment-Setup:**
Anweisungen für den "Bautrupp" (Gemini CLI).
Dieses Projekt läuft in einer Docker-Compose-Umgebung, typischerweise auf einer Synology Diskstation. Der Zugriff auf die einzelnen Microservices erfolgt über einen zentralen Nginx-Reverse-Proxy (`proxy`-Service), der auf Port `8090` des Host-Systems lauscht.
### Task 1: UI-Anpassung - Side-by-Side CRM View & Settings
**Zugriffs-URLs für `company-explorer`:**
**Ziel:** Die neuen Datenfelder an der Oberfläche sichtbar machen.
* **Intern (im Docker-Netzwerk):** `http://company-explorer:8000`
* **Extern (über Proxy):** `https://floke-ai.duckdns.org/ce/` (bzw. lokal `http://192.168.x.x:8090/ce/`)
**Anforderungen:**
**Datenbank-Persistenz:**
* Die SQLite-Datenbankdatei (`companies_v3_fixed_2.db`) muss mittels Docker-Volume-Mapping vom Host-Dateisystem in den `company-explorer`-Container gemountet werden (`./companies_v3_fixed_2.db:/app/companies_v3_fixed_2.db`). Dies stellt sicher, dass Datenänderungen persistent sind und nicht verloren gehen, wenn der Container neu gestartet oder neu erstellt wird.
1. **Inspector-Update (`src/components/Inspector.tsx`):**
* Implementiere eine neue Sektion "Data Match (CRM vs. AI)".
* Zeige links die `crm_*` Felder (grau hinterlegt/ReadOnly).
* Zeige rechts die aktuellen Research-Daten (`name`, `website`).
* Visualisiere den `data_mismatch_score`.
* **Wichtig:** Entferne ungenutzte Imports wie `Save` oder `Calendar`, um Build-Fehler zu vermeiden!
* Fixe den Aufruf der `ContactsManager` Komponente (Props-Mismatch beheben).
2. **Settings-Update (`src/components/RoboticsSettings.tsx`):**
* Erweitere die Branchen-Übersicht (Industries) um die neuen Spalten.
* Zeige `Pains`, `Gains` und `Priorität` für jedes Vertical an.
* Diese Daten werden schreibgeschützt aus der DB angezeigt (Quelle ist Notion).
**Akzeptanzkriterien:**
* Das Frontend lässt sich fehlerfrei bauen (`npm run build`).
* In der Account-Detailansicht ist der Vergleich zwischen CRM- und Web-Daten sichtbar.
* In den Einstellungen sind die strategischen Inhalte (Pains/Gains) sichtbar.
---
## 12. Deployment & Access Notes (NAS)
**Pfad auf NAS:** `/volume1/homes/Floke/python/brancheneinstufung/company-explorer`
**Restart:** `docker-compose restart company-explorer`
**Build:** `docker-compose up -d --build company-explorer`