Skip to content

experiment: graph explorer API (neighborhood, shortest path, reindex) - #976

Draft
SHAcollision wants to merge 1 commit into
mainfrom
experiment/graph-viz
Draft

experiment: graph explorer API (neighborhood, shortest path, reindex)#976
SHAcollision wants to merge 1 commit into
mainfrom
experiment/graph-viz

Conversation

@SHAcollision

@SHAcollision SHAcollision commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

experiment: backend half of the graph explorer. Use together with the pubky-app branch experiment/graph-viz (frontend PR: pubky/pubky-app#2138).

What it adds

  • GET /v0/graph/{kind}/{id} with kind in user|post|tag: a typed node-link neighborhood around a center entity, painted in one request. Params: depth (1..2, user centers only), limit (1..50, default 30), kinds (csv filter). Node ids are kind-prefixed (user:{pubky}, post:{author}:{post_id}, tag:{label}); FOLLOWS/TAGGED edges carry indexed_at so the client can time-travel.
  • GET /v0/graph/path/{from}/{to}: undirected shortest FOLLOWS path, max 6 hops, nodes path-ordered. Distinct 404s for unknown users vs no path.
  • nexusd db reindex: rebuilds the whole Redis index from the Neo4j graph (flush, recreate the RediSearch post-content FT index, resync). Needed once after restoring a graph backup, and reusable as an operational tool.

Design notes

  • Neighborhood queries are single COLLECTed-row Cypher with per-class caps (hop-2 has a global DISTINCT cap of 120), anchored subqueries (no full TAGGED scans, verified with EXPLAIN), and deleted-user filtering.
  • Params validate through the house idioms: BoundedLimit, a GraphDepth newtype in the WotDepth style, GraphKinds with its own CSV Deserialize, Path<PubkyId> extraction. Invalid input is a 400, not a silent clamp.
  • Shared Cypher fragment helpers (user_projection, post_fields, not_deleted on USER_DELETED_SENTINEL) keep the projections in one place.
  • MockDb::sync_redis and db reindex now share one rebuild(); this fixes a real gap where a reindex skipped the FT index and post search came back empty. The flush is FLUSHALL ASYNC so production-sized indexes do not outlive the client timeout.

Tests

14 integration tests (nexus-webapi/tests/graph/) over the mock dataset: shapes for all three center kinds, depth/limit/kinds behavior, edge-endpoint closure, path ordering, and the full 4xx surface. Serde unit tests for the new deserializers. Full suite green: 625 passed.

We probably will not merge this as-is; it exists so the team can explore the feature end to end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant