""" app/routers/graph.py — Graph-Endpunkte (WP-04) Zweck: Liefert die Nachbarschaft einer Note/ID als JSON-Graph (Nodes/Edges/Stats). Kompatibilität: Python 3.12+, FastAPI 0.110+, qdrant-client 1.x Version: 0.1.0 (Erstanlage) Stand: 2025-10-07 Bezug: - app/core/graph_adapter.py - app/models/dto.py Nutzung: app.include_router(graph.router, prefix="/graph", tags=["graph"]) Änderungsverlauf: 0.1.0 (2025-10-07) – Erstanlage. """ from __future__ import annotations from typing import List, Optional from fastapi import APIRouter, Query from qdrant_client import QdrantClient from app.models.dto import GraphResponse, NodeDTO, EdgeDTO from app.core.graph_adapter import expand from app.config import get_settings router = APIRouter() @router.get("/{note_id}", response_model=GraphResponse) def get_graph(note_id: str, depth: int = 1, edge_types: Optional[List[str]] = Query(None)) -> GraphResponse: s = get_settings() client = QdrantClient(url=s.QDRANT_URL, api_key=s.QDRANT_API_KEY) sg = expand(client, s.COLLECTION_PREFIX, [note_id], depth=depth, edge_types=edge_types) # Seed-Node (Payload optional später ergänzen über get_note_payload) nodes = [NodeDTO(id=note_id, type="note", title=None, tags=[], in_degree=sg.in_degree.get(note_id, 0), out_degree=sg.out_degree.get(note_id, 0))] # direkte Out-Kanten des Seeds edges = [] for e in sg.adj.get(note_id, []): edges.append(EdgeDTO( id=f"{note_id}->{e['target']}:{e['kind']}", kind=e["kind"], source=note_id, target=e["target"], weight=float(e["weight"]), direction="out" )) return GraphResponse(center_note_id=note_id, nodes=nodes, edges=edges, stats={"node_count": len(nodes), "edge_count": len(edges)})