feat: Documentation and Tool Config Update
This commit is contained in:
@@ -1,265 +0,0 @@
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv(dotenv_path="/home/node/clawd/.env")
|
||||
|
||||
NOTION_TOKEN = os.getenv("NOTION_API_KEY")
|
||||
HEADERS = {
|
||||
"Authorization": f"Bearer {NOTION_TOKEN}",
|
||||
"Content-Type": "application/json",
|
||||
"Notion-Version": "2022-06-28"
|
||||
}
|
||||
|
||||
# --- Load Product Mapping ---
|
||||
try:
|
||||
with open("data/product_mapping.json", "r") as f:
|
||||
PRODUCT_MAP = json.load(f)
|
||||
except FileNotFoundError:
|
||||
print("❌ Product mapping not found. Run fetch_product_mapping.py first.")
|
||||
exit(1)
|
||||
|
||||
# Helper to find DB ID
|
||||
def find_db_id(query_name):
|
||||
url = "https://api.notion.com/v1/search"
|
||||
payload = {"query": query_name, "filter": {"value": "database", "property": "object"}}
|
||||
resp = requests.post(url, headers=HEADERS, json=payload)
|
||||
if resp.status_code == 200:
|
||||
results = resp.json().get("results", [])
|
||||
if results:
|
||||
return results[0]['id']
|
||||
return None
|
||||
|
||||
def get_page_by_vertical(db_id, vertical_name):
|
||||
url = f"https://api.notion.com/v1/databases/{db_id}/query"
|
||||
# Using 'Vertical' as the title property name based on previous audit
|
||||
payload = {
|
||||
"filter": {
|
||||
"property": "Vertical",
|
||||
"title": {"equals": vertical_name}
|
||||
}
|
||||
}
|
||||
resp = requests.post(url, headers=HEADERS, json=payload)
|
||||
if resp.status_code == 200:
|
||||
results = resp.json().get("results", [])
|
||||
if results:
|
||||
return results[0]
|
||||
return None
|
||||
|
||||
def update_page(page_id, properties):
|
||||
url = f"https://api.notion.com/v1/pages/{page_id}"
|
||||
payload = {"properties": properties}
|
||||
resp = requests.patch(url, headers=HEADERS, json=payload)
|
||||
if resp.status_code == 200:
|
||||
print(f"✅ Updated '{page_id}'")
|
||||
else:
|
||||
print(f"❌ Error updating '{page_id}': {resp.text}")
|
||||
|
||||
def create_page(db_id, properties):
|
||||
url = "https://api.notion.com/v1/pages"
|
||||
payload = {"parent": {"database_id": db_id}, "properties": properties}
|
||||
resp = requests.post(url, headers=HEADERS, json=payload)
|
||||
if resp.status_code == 200:
|
||||
print(f"✅ Created new page")
|
||||
else:
|
||||
print(f"❌ Error creating page: {resp.text}")
|
||||
|
||||
# --- CONTENT DEFINITION ---
|
||||
|
||||
# Format: Vertical -> { props... }
|
||||
UPDATES = {
|
||||
"Healthcare - Care Home": {
|
||||
"product": "Cleaning Indoor Roboter (Wet Surface)",
|
||||
"pains": """[Primary Product: Cleaning]
|
||||
- Infektionsrisiko: Mangelnde Bodenhygiene und Keimverschleppung in sensiblen Bereichen gefährden Bewohner.
|
||||
- Dokumentationspflicht: Lückenlose Nachweise für Hygiene-Audits binden wertvolle Pflegezeit.
|
||||
- Personalmangel: Reinigungskräfte fehlen, Standards können manuell kaum gehalten werden.
|
||||
|
||||
[Secondary Product: Service]
|
||||
- Pflegeressourcen: Fachkräfte binden bis zu 30% ihrer Zeit mit nicht-pflegerischen Transportwegen (Essen/Wäsche).
|
||||
- Körperliche Belastung: Schweres Heben und weite Wege führen zu krankheitsbedingten Ausfällen im Pflegeteam.""",
|
||||
"gains": """[Primary Product: Cleaning]
|
||||
- Audit-Sicherheit: Automatisierte, protokollierte Reinigung sichert Compliance ohne Mehraufwand.
|
||||
- Entlastung Housekeeping: Personal konzentriert sich auf Sichtreinigung und Desinfektion statt Bodenfläche.
|
||||
|
||||
[Secondary Product: Service]
|
||||
- Mehr Zeit am Patienten: Reduktion der Laufwege gibt Pflegekräften 2-3 Std./Schicht zurück.
|
||||
- Mitarbeiterzufriedenheit: Reduktion körperlicher Belastung senkt Krankenstand.""",
|
||||
"ops_focus": True,
|
||||
"status": "Freigegeben",
|
||||
"notes": "Prio 1: Reinigung. Prio 2: Service (Essen). Fokus auf Fachkräftemangel & Hygiene."
|
||||
},
|
||||
"Healthcare - Hospital": {
|
||||
"product": "Cleaning Indoor Roboter (Wet Surface)",
|
||||
"pains": """[Primary Product: Cleaning]
|
||||
- Infektionsschutz: Hohe Frequenz an Patientenbewegungen erfordert permanente Desinfektion der Böden.
|
||||
- Audit-Druck: Behördliche Auflagen verlangen lückenlose Dokumentation, die manuell kaum leistbar ist.
|
||||
- Kostendruck: Steigende Personalkosten bei fixen Fallpauschalen zwingen zur Effizienzsteigerung.
|
||||
|
||||
[Secondary Product: Service]
|
||||
- Logistik-Aufwand: Transport von Proben, Wäsche und Essen bindet Pflegepersonal in unproduktiven Wegezeiten.""",
|
||||
"gains": """[Primary Product: Cleaning]
|
||||
- Hygiene-Standard: 24/7 gleichbleibende Reinigungsqualität reduziert Keimbelastung messbar.
|
||||
- Compliance: Automatische Protokollierung aller Reinigungsfahrten für Audits.
|
||||
|
||||
[Secondary Product: Service]
|
||||
- Prozess-Effizienz: Automatisierter Warentransport entlastet Fachpersonal für medizinische Aufgaben.""",
|
||||
"ops_focus": True,
|
||||
"status": "Freigegeben",
|
||||
"notes": "Prio 1: Reinigung (Alex Veto). Service ist 'nice to have'. KPI: Hygiene-Sicherheit."
|
||||
},
|
||||
"Leisure - Entertainment": {
|
||||
"product": "Service Roboter", # FIX: Changed from Cleaning to Service
|
||||
"pains": """[Primary Product: Service]
|
||||
- Service-Engpass: Umsatzverlust zu Stoßzeiten, da Personal nicht schnell genug Getränke/Snacks nachliefert.
|
||||
- Personalmangel: Schwierige Besetzung von Spätschichten führt zu geschlossenen Stationen/Bahnen.
|
||||
- Wartezeiten: Gäste sind unzufrieden, wenn Bestellungen zu lange dauern.
|
||||
|
||||
[Secondary Product: Cleaning]
|
||||
- Bodenverschmutzung: Klebrige Böden (Getränke/Popcorn) im Foyer stören das Gästeerlebnis.""",
|
||||
"gains": """[Primary Product: Service]
|
||||
- Umsatzsteigerung: Permanente Verfügbarkeit von Snacks/Getränken direkt am Platz (Cross-Selling).
|
||||
- Erlebnis-Faktor: Innovative Roboter begeistern Gäste und fördern Social-Media-Sichtbarkeit.
|
||||
- Entlastung: Servicepersonal hat mehr Zeit für Gästebetreuung statt Laufwege.""",
|
||||
"ops_focus": True, # Keep secondary focus plausible
|
||||
"status": "Freigegeben",
|
||||
"notes": "Prio 1: Service Robotik (BellaBot). Cleaning nur Prio 2 (Foyer/Gänge)."
|
||||
},
|
||||
"Logistics - Warehouse": {
|
||||
"product": "Cleaning Outdoor Roboter (Sweeper)",
|
||||
"pains": """[Primary Product: Sweeper]
|
||||
- Prozesssicherheit: Staub auf Sensoren und Lichtschranken führt zu Anlagenstörungen und Produktionsstopps.
|
||||
- Arbeitssicherheit: Verschmutzte Fahrwege durch Palettenreste/Staub erhöhen das Unfallrisiko.
|
||||
- Manuelle Bindung: Fachkräfte müssen kehren statt kommissionieren.
|
||||
|
||||
[Secondary Product: Cleaning Wet]
|
||||
- Hartnäckige Verschmutzungen: Öl/Reifenabrieb erfordern Nassreinigung, die manuell zeitintensiv ist.""",
|
||||
"gains": """[Primary Product: Sweeper]
|
||||
- Staubfreie Umgebung: Werterhalt des Hallenbodens und Schutz empfindlicher Ware/Anlagen.
|
||||
- Produktivität: Reinigung erfolgt parallel zum Betrieb oder nachts, ohne Störung.
|
||||
- Sicherheit: Saubere Fahrwege reduzieren Unfallrisiko für Flurförderzeuge.""",
|
||||
"ops_focus": True,
|
||||
"status": "Freigegeben",
|
||||
"notes": "Prio 1: Sweeper (Staub). Prio 2: Wet. Transport schwierig wegen Paletten."
|
||||
},
|
||||
"Tech - Data Center": {
|
||||
"product": "Security Roboter",
|
||||
"pains": """[Primary Product: Security]
|
||||
- Sicherheitsrisiko: Unbefugter Zutritt in Sicherheitsbereiche muss lückenlos detektiert werden (24/7).
|
||||
- Personalbindung: Wachpersonal ist teuer und kann nicht überall gleichzeitig sein.
|
||||
|
||||
[Secondary Product: Cleaning]
|
||||
- Feinstaub: Staubpartikel in Serverräumen gefährden Hardware und Kühlung.""",
|
||||
"gains": """[Primary Product: Security]
|
||||
- Lückenlose Überwachung: Permanente Patrouille und sofortige Alarmierung ohne Personalbindung.
|
||||
- Dokumentation: Video- und Sensorprotokolle aller Ereignisse.
|
||||
|
||||
[Secondary Product: Cleaning]
|
||||
- Ausfallsicherheit: Staubfreie Umgebung verlängert Hardware-Lebensdauer.""",
|
||||
"ops_focus": True,
|
||||
"status": "Klärrungsbedarf", # New, needs review
|
||||
"notes": "Neu angelegt. Prio 1 Security (lt. Transkript). Prio 2 Cleaning (Staub)."
|
||||
},
|
||||
"Reinigungsdienstleister": {
|
||||
"product": "Cleaning Indoor Roboter (Wet Surface)",
|
||||
"pains": """[Primary Product: Cleaning]
|
||||
- Personalmangel: Schwierigkeit, zuverlässiges Personal für alle Objekte zu finden.
|
||||
- Kostendruck: Geringe Margen bei Ausschreibungen erfordern hohe Effizienz.
|
||||
- Qualitätsschwankungen: Manuelle Reinigung variiert stark, Kunden beschweren sich.
|
||||
- Fluktuation: Hoher Aufwand für ständige Neueinarbeitung.""",
|
||||
"gains": """[Primary Product: Cleaning]
|
||||
- Skalierbarkeit: Roboter übernehmen Flächenleistung, Personal macht Detailreinigung.
|
||||
- Innovation: Wettbewerbsvorteil bei Ausschreibungen durch Technologie-Einsatz.
|
||||
- Kalkulationssicherheit: Fixe Kosten statt variabler Personalkosten/Krankheitstage.""",
|
||||
"ops_focus": False,
|
||||
"status": "Klärrungsbedarf",
|
||||
"notes": "Neu angelegt. Zielgruppe: Wisag, Dussmann etc. (Alex: Größter Markt)."
|
||||
},
|
||||
"Infrastructure - Communities": {
|
||||
"product": "Cleaning Indoor Roboter (Wet Surface)",
|
||||
"pains": """[Primary Product: Cleaning]
|
||||
- Großflächen-Reinigung: Sporthallen, Aulen und Flure binden enorm viele Personalstunden.
|
||||
- Budget-Druck: Kommunen müssen sparen, Reinigungskosten sind großer Posten.
|
||||
- Nutzungs-Konflikte: Reinigung muss in engen Zeitfenstern zwischen Schul/Vereinsnutzung erfolgen.""",
|
||||
"gains": """[Primary Product: Cleaning]
|
||||
- Kosteneffizienz: Reduktion der Reinigungskosten pro Quadratmeter.
|
||||
- Flexibilität: Reinigung kann nachts oder in Randzeiten erfolgen.
|
||||
- Werterhalt: Schonende, regelmäßige Reinigung verlängert Lebensdauer von Sportböden.""",
|
||||
"ops_focus": False,
|
||||
"status": "Klärrungsbedarf",
|
||||
"notes": "Neu angelegt (Schulen, Gemeinden)."
|
||||
},
|
||||
"Infrastructure Parking": {
|
||||
"product": "Cleaning Outdoor Roboter (Sweeper)",
|
||||
"pains": """[Primary Product: Sweeper]
|
||||
- Außenwirkung: Verschmutzte Parkflächen/Müll schaden dem Image (erster Eindruck).
|
||||
- Manuelle Arbeit: Fegen von großen Außenflächen ist personalintensiv und unbeliebt.
|
||||
- Umwelt: Müll gelangt in die Umgebung/Kanalisation.""",
|
||||
"gains": """[Primary Product: Sweeper]
|
||||
- Gepflegtes Erscheinungsbild: Täglich saubere Außenanlagen.
|
||||
- Autonomie: Roboter reinigt selbstständig, auch bei schlechtem Wetter.
|
||||
- Entlastung: Hausmeister kann sich um Wartung kümmern statt Fegen.""",
|
||||
"ops_focus": False,
|
||||
"status": "Klärrungsbedarf",
|
||||
"notes": "Neu angelegt (Parkplätze, Außenanlagen)."
|
||||
}
|
||||
}
|
||||
|
||||
def run_enrichment():
|
||||
db_id = find_db_id("Industries")
|
||||
if not db_id:
|
||||
print("❌ Industries DB not found.")
|
||||
return
|
||||
|
||||
print(f"--- Enriching Verticals in DB {db_id} ---")
|
||||
|
||||
for vertical, data in UPDATES.items():
|
||||
# Resolve Product ID
|
||||
prod_id = PRODUCT_MAP.get(data["product"])
|
||||
if not prod_id:
|
||||
print(f"❌ Product '{data['product']}' not found in map. Skipping {vertical}.")
|
||||
continue
|
||||
|
||||
# Prepare Properties
|
||||
props = {
|
||||
"Pains": {"rich_text": [{"text": {"content": data["pains"]}}]},
|
||||
"Gains": {"rich_text": [{"text": {"content": data["gains"]}}]},
|
||||
"Primary Product Category": {"relation": [{"id": prod_id}]},
|
||||
"Notes": {"rich_text": [{"text": {"content": data["notes"]}}]},
|
||||
# Handle Status (Try Select first, then Status)
|
||||
# We assume "Freigabe" exists
|
||||
}
|
||||
|
||||
# Add checkbox if present in logic
|
||||
if "ops_focus" in data:
|
||||
props["Ops Focus: Secondary"] = {"checkbox": data["ops_focus"]}
|
||||
|
||||
# Check if page exists
|
||||
page = get_page_by_vertical(db_id, vertical)
|
||||
|
||||
if page:
|
||||
# Update existing
|
||||
# Add Status Update
|
||||
# (Note: Logic to detect Select vs Status type is needed, but we assume Select/Status name is consistent)
|
||||
# For robustness, we check the property type in the page object
|
||||
status_type = page['properties'].get("Freigabe", {}).get("type")
|
||||
if status_type == "status":
|
||||
props["Freigabe"] = {"status": {"name": data["status"]}}
|
||||
elif status_type == "select":
|
||||
props["Freigabe"] = {"select": {"name": data["status"]}}
|
||||
|
||||
print(f"Updating '{vertical}'...")
|
||||
update_page(page['id'], props)
|
||||
else:
|
||||
# Create new
|
||||
print(f"Creating new vertical '{vertical}'...")
|
||||
props["Vertical"] = {"title": [{"text": {"content": vertical}}]}
|
||||
# Guess status type (usually Select or Status) - Try Status first as default in new Notion DBs
|
||||
# Or omit status if unsure, but we want to set it.
|
||||
# We'll try Status format.
|
||||
props["Freigabe"] = {"status": {"name": data["status"]}}
|
||||
create_page(db_id, props)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_enrichment()
|
||||
Reference in New Issue
Block a user