diff --git a/app/frontend/ui_graph_cytoscape.py b/app/frontend/ui_graph_cytoscape.py index 46f3c43..ec30b38 100644 --- a/app/frontend/ui_graph_cytoscape.py +++ b/app/frontend/ui_graph_cytoscape.py @@ -153,6 +153,26 @@ def render_graph_explorer_cytoscape(graph_service): ) # 2. Detail Daten (Inspector) inspected_data = graph_service.get_note_with_full_content(inspected_id) + + # DEBUG: Zeige Debug-Informationen + with st.expander("🔍 Debug-Informationen", expanded=False): + st.write(f"**Gefundene Knoten:** {len(nodes_data) if nodes_data else 0}") + st.write(f"**Gefundene Kanten:** {len(edges_data) if edges_data else 0}") + if nodes_data: + st.write("**Knoten-IDs:**") + for n in nodes_data[:10]: + nid = getattr(n, 'id', 'N/A') + st.write(f" - {nid}") + if len(nodes_data) > 10: + st.write(f" ... und {len(nodes_data) - 10} weitere") + if edges_data: + st.write("**Kanten:**") + for e in edges_data[:10]: + src = getattr(e, "source", "N/A") + tgt = getattr(e, "to", getattr(e, "target", "N/A")) + st.write(f" - {src} -> {tgt}") + if len(edges_data) > 10: + st.write(f" ... und {len(edges_data) - 10} weitere") # --- ACTION BAR --- action_container = st.container() diff --git a/app/frontend/ui_graph_service.py b/app/frontend/ui_graph_service.py index a66b015..090dd9f 100644 --- a/app/frontend/ui_graph_service.py +++ b/app/frontend/ui_graph_service.py @@ -61,10 +61,25 @@ class GraphExplorerService: # Suche Kanten für Center (L1) l1_edges = self._find_connected_edges([center_note_id], center_note.get("title")) + # DEBUG: Zeige gefundene Kanten + print(f"DEBUG: Gefundene L1-Kanten: {len(l1_edges)}") + + processed_count = 0 + failed_count = 0 for edge_data in l1_edges: src_id, tgt_id = self._process_edge(edge_data, nodes_dict, unique_edges, current_depth=1) - if src_id: level_1_ids.add(src_id) - if tgt_id: level_1_ids.add(tgt_id) + if src_id and tgt_id: + processed_count += 1 + level_1_ids.add(src_id) + level_1_ids.add(tgt_id) + else: + failed_count += 1 + # DEBUG: Zeige fehlgeschlagene Kanten + if edge_data and edge_data.payload: + print(f"DEBUG: Kante konnte nicht verarbeitet werden: {edge_data.payload.get('source_id')} -> {edge_data.payload.get('target_id')}") + + print(f"DEBUG: Verarbeitete Kanten: {processed_count}, Fehlgeschlagen: {failed_count}") + print(f"DEBUG: Nodes im Dict: {len(nodes_dict)}, Edges im Dict: {len(unique_edges)}") # Level 2 Suche (begrenzt für Performance) if depth > 1 and len(level_1_ids) > 1 and len(level_1_ids) < 80: @@ -382,6 +397,12 @@ class GraphExplorerService: src_note = self._resolve_note_from_ref(src_ref) tgt_note = self._resolve_note_from_ref(tgt_ref) + # DEBUG: Zeige Auflösungs-Ergebnisse (nur bei Fehlern) + if not src_note: + print(f"DEBUG _process_edge: Konnte src_note nicht auflösen für: {src_ref}") + if not tgt_note: + print(f"DEBUG _process_edge: Konnte tgt_note nicht auflösen für: {tgt_ref}") + if src_note and tgt_note: src_id = src_note.get('note_id') tgt_id = tgt_note.get('note_id') @@ -490,7 +511,7 @@ class GraphExplorerService: res, _ = self.client.scroll( collection_name=self.notes_col, scroll_filter=models.Filter(must=[models.FieldCondition(key="title", match=models.MatchText(text=possible_title))]), - limit=10, with_payload=True # Mehr Ergebnisse für Fuzzy-Matching + limit=50, with_payload=True # Mehr Ergebnisse für Fuzzy-Matching ) if res: # Prüfe alle Ergebnisse mit normalisiertem Vergleich @@ -506,6 +527,30 @@ class GraphExplorerService: return r.payload except Exception: pass + + # Versuch 3c: Fallback - Lade alle Notes und filtere clientseitig (nur wenn Text-Suche fehlschlägt) + # Dies ist langsamer, aber findet auch Notes, die die Text-Suche nicht findet + if possible_title_norm and len(possible_title_norm) > 5: + try: + # Lade eine größere Anzahl von Notes (nur wenn nötig) + res_all, _ = self.client.scroll( + collection_name=self.notes_col, + limit=200, # Begrenzt, um Performance zu gewährleisten + with_payload=True + ) + if res_all: + for r in res_all: + if r.payload: + note_title = r.payload.get("title", "") + note_title_norm = normalize_title(note_title) + if note_title_norm and possible_title_norm: + if (note_title_norm == possible_title_norm or + note_title_norm.startswith(possible_title_norm) or + possible_title_norm.startswith(note_title_norm)): + self._note_cache[r.payload['note_id']] = r.payload + return r.payload + except Exception: + pass # Fall B: Note ID direkt note = self._fetch_note_cached(ref_str)