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:
@@ -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.
|
||||
|
||||
---
|
||||
|
||||
@@ -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?)
|
||||
|
||||
@@ -12,6 +12,7 @@ PARENT_PAGE_ID = "2e088f42-8544-8024-8289-deb383da3818"
|
||||
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()
|
||||
Reference in New Issue
Block a user