feat(notion): Finalize Competitive Radar v3.0 (Level 3 Relational Model)

- Extended import_relational_radar.py to include a 'Products' database.
- Implemented full dual-way relations for Companies <-> Landmines, References, Products.
- Updated documentation to reflect the 4-database architecture.
This commit is contained in:
2026-01-11 12:14:45 +00:00
parent e1d115e0ba
commit 9a769f62a0
3 changed files with 50 additions and 13 deletions

View File

@@ -72,11 +72,12 @@ Die App ist unter `/ca/` voll funktionsfähig und verfügt nun über eine "Groun
### 📊 Relationaler Notion Import (Competitive Radar v2.0)
Um die Analyse-Ergebnisse optimal nutzbar zu machen, wurde ein bidirektionaler Import-Prozess nach Notion implementiert (`import_relational_radar.py`).
* **Architektur:** Statt Textblöcken werden drei vernetzte Datenbanken erstellt:
1. **📦 Companies (Hub):** Stammdaten, USPs, Portfolio.
* **Architektur:** Statt Textblöcken werden vier vernetzte Datenbanken erstellt:
1. **📦 Companies (Hub):** Stammdaten, USPs, Portfolio-Summary.
2. **💣 Landmines (Satellite):** Einzelfragen und Angriffsvektoren, verknüpft mit der Company.
3. **🏆 References (Satellite):** Konkrete Kundenprojekte, verknüpft mit der Company.
* **Dual-Way Relations:** Dank `dual_property` Konfiguration sind die Verknüpfungen in Notion sofort in beide Richtungen navigierbar (z.B. sieht man auf der Company-Seite sofort alle zugehörigen Landmines).
4. **🤖 Products (Satellite):** Einzelne Produkte als Datensätze, ermöglicht marktweiten Vergleich (z.B. "Alle Reinigungsroboter").
* **Dual-Way Relations:** Dank `dual_property` Konfiguration sind die Verknüpfungen in Notion sofort in beide Richtungen navigierbar.
* **Daten-Qualität:** Durch die Map-Reduce Analyse und das gezielte Reference-Scraping werden nun echte Fakten statt KI-Halluzinationen importiert.
---

View File

@@ -43,7 +43,7 @@ Die Schaltstelle für die hyper-personalisierte Ansprache.
Automatisierte Überwachung der Marktbegleiter mit Fokus auf "Grounded Truth".
* **Funktion:** Kontinuierliches Scraping von Wettbewerber-Webseiten, gezielte Suche nach Referenzkunden und Case Studies.
* **Kill-Argumente & Landmines:** Erstellung von strukturierten Battlecards und spezifischen "Landmine Questions" für den Sales-Außendienst.
* **Relationaler Ansatz:** Trennung in drei verknüpfte Datenbanken (Firmen, Landmines, Referenzen) für maximale Filterbarkeit und Übersicht.
* **Relationaler Ansatz:** Trennung in vier verknüpfte Datenbanken (Firmen, Landmines, Referenzen, Produkte) für maximale Filterbarkeit und Übersicht.
### 3.5 Enrichment Factory & RevOps
Datenanreicherung der CRM-Accounts.
@@ -93,6 +93,7 @@ Um die relationale Integrität zu wahren, sind folgende Datenbanken in Notion zw
* **Messaging Matrix** $\leftrightarrow$ **Sector Master** (Welcher Schmerz gehört zu welcher Branche?)
* **Competitive Radar (Companies)** $\leftrightarrow$ **Competitive Radar (Landmines)** (Welche Angriffsfragen gehören zu welchem Wettbewerber?)
* **Competitive Radar (Companies)** $\leftrightarrow$ **Competitive Radar (References)** (Welche Kundenprojekte hat der Wettbewerber realisiert?)
* **Competitive Radar (Companies)** $\leftrightarrow$ **Competitive Radar (Products)** (Welche Produkte hat der Wettbewerber im Portfolio?)
* **The Brain** $\leftrightarrow$ **Product Master** (Welches Support-Wissen gehört zu welcher Hardware?)
* **GTM Workspace** $\leftrightarrow$ **Product Master** (Welche Kampagne bewirbt welches Gerät?)
* **Feature-to-Value Translator** $\leftrightarrow$ **Product Master** (Welcher Nutzen gehört zu welchem Feature?)

View File

@@ -6,12 +6,13 @@ import sys
# Configuration
JSON_FILE = 'analysis_robo-planet.de.json'
TOKEN_FILE = 'notion_token.txt'
PARENT_PAGE_ID = "2e088f42-8544-8024-8289-deb383da3818"
PARENT_PAGE_ID = "2e088f42-8544-8024-8289-deb383da3818"
# Database Titles
DB_TITLE_HUB = "📦 Competitive Radar (Companies)"
DB_TITLE_LANDMINES = "💣 Competitive Radar (Landmines & Intel)"
DB_TITLE_REFS = "🏆 Competitive Radar (References)"
DB_TITLE_PRODUCTS = "🤖 Competitive Radar (Products)"
def load_json_data(filepath):
try:
@@ -81,7 +82,7 @@ def main():
token = load_notion_token(TOKEN_FILE)
data = load_json_data(JSON_FILE)
print("🚀 Starting Relational Import...")
print("🚀 Starting Relational Import (Level 3 - Full Radar)...")
# --- STEP 1: Define & Create Competitors Hub DB ---
props_hub = {
@@ -130,6 +131,19 @@ def main():
}
refs_db_id = create_database(token, PARENT_PAGE_ID, DB_TITLE_REFS, props_refs)
# Products DB
props_products = {
"Product Name": {"title": {}},
"Purpose / Description": {"rich_text": {}},
"Related Competitor": {
"relation": {
"database_id": hub_db_id,
"dual_property": {"synced_property_name": "Related Products"}
}
}
}
products_db_id = create_database(token, PARENT_PAGE_ID, DB_TITLE_PRODUCTS, props_products)
# --- STEP 3: Import Competitors (and store IDs) ---
competitor_map = {} # Maps Name -> Notion Page ID
@@ -156,10 +170,10 @@ def main():
# Create Page
props = {
"Name": {"title": [{"text": {"content": c_name}}]},
"Portfolio Summary": {"rich_text": [{"text": {"content": portfolio_text[:2000]}}]},
"Portfolio Summary": {"rich_text": [{"text": {"content": portfolio_text[:2000]}}]}, # Limit length
"USPs": {"rich_text": [{"text": {"content": usps[:2000]}}]},
"Silver Bullet": {"rich_text": [{"text": {"content": silver_bullet[:2000]}}]},
"Target Industries": {"multi_select": [{"name": i.replace(',', '')} for i in industries]},
"Target Industries": {"multi_select": [{"name": i.replace(',', '')} for i in industries]}
}
if c_url: props["Website"] = {"url": c_url}
@@ -185,10 +199,8 @@ def main():
create_page(token, landmines_db_id, props)
# 2. Weaknesses
# The JSON has "strengths_vs_weaknesses" combined. We'll import them as general Intel points.
for point in card.get('strengths_vs_weaknesses', []):
# Try to guess type based on text, or just default to Weakness context from Battlecard
p_type = "Competitor Weakness" # Assuming these are points for us to exploit
p_type = "Competitor Weakness"
props = {
"Statement / Question": {"title": [{"text": {"content": point}}]},
"Type": {"select": {"name": p_type}},
@@ -224,7 +236,30 @@ def main():
count_refs += 1
print(f" - {count_refs} References imported.")
print("\n✅ Relational Import Complete!")
# --- STEP 6: Import Products (Portfolio) ---
print("\nImporting Products...")
count_prods = 0
for analysis in data.get('analyses', []):
c_name = analysis.get('competitor', {}).get('name')
comp_page_id = competitor_map.get(c_name)
if not comp_page_id: continue
for prod in analysis.get('portfolio', []):
p_name = prod.get('product', 'Unknown Product')
p_purpose = prod.get('purpose', '')
props = {
"Product Name": {"title": [{"text": {"content": p_name}}]},
"Purpose / Description": {"rich_text": [{"text": {"content": p_purpose[:2000]}}]},
"Related Competitor": {"relation": [{"id": comp_page_id}]}
}
create_page(token, products_db_id, props)
count_prods += 1
print(f" - {count_prods} Products imported.")
print("\n✅ Relational Import Complete (Level 3)!")
if __name__ == "__main__":
main()
main()