Skip to content

Commit 5d1595f

Browse files
committed
docs: saved queries user guide and docstring coverage for unified query system
- Create docs/guides/SAVED_QUERIES.md covering cross-explorer flow, +/- algebra, query types, and document explorer integration - Add cross-reference from exploring.md - Fill docstring gaps: graphStore (4/9→9/9), queryDefinitionStore (0/1→1/1), useQueryReplay (1/2→2/2), ExplorerView (0/1→1/1), useGraphContextMenu (2/5→5/5) - Mark Phase 5 complete in unified query exploration tracker
1 parent 7b5be48 commit 5d1595f

8 files changed

Lines changed: 156 additions & 4 deletions

File tree

.claude/todo-unified-query-exploration.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,15 @@ Folder icon in the nav rail across all explorer views. Same saved queries list,
6767
- [x] Extract color computation from graphTransform.ts into colorScale.ts
6868
- [x] Rename D3Node/D3Link to RenderNode/RenderLink (renderer-agnostic)
6969

70-
### Phase 5: Documentation & Docstrings
70+
### Phase 5: Documentation & Docstrings
7171
- [x] Add JSDoc docstrings to new exploration tracking code
7272
- [x] Add JSDoc docstrings to graphStore (actions, types)
7373
- [x] Add JSDoc docstrings to cypherGenerator
7474
- [x] Add JSDoc docstrings to SearchBar handlers
7575
- [x] Add JSDoc docstrings to useGraphContextMenu handlers
76-
- [ ] Document the unified query exploration workflow in user manual
77-
- [ ] Document the +/- operator algebra concept
76+
- [x] Document the unified query exploration workflow in user manual (`docs/guides/SAVED_QUERIES.md`)
77+
- [x] Document the +/- operator algebra concept
78+
- [x] Fill remaining docstring gaps (graphStore 4/9→9/9, queryDefinitionStore, useQueryReplay, ExplorerView, useGraphContextMenu)
7879

7980
### Phase 6: Type-Aware Saved Queries ✓
8081
- [x] Backend: `POST /query/documents/by-concepts` endpoint (concept→document reverse lookup)

docs/guides/SAVED_QUERIES.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# Saved Queries
2+
3+
How to save, load, and share graph explorations across explorer views.
4+
5+
## What is a Saved Query?
6+
7+
A saved query is an ordered list of graph operations — each tagged as additive (+) or subtractive (-). This is the universal unit of work across all explorer views.
8+
9+
```
10+
+ MATCH (c:Concept)-[r*1..1]-(n:Concept) WHERE c.concept_id = 'abc' RETURN c, r, n;
11+
+ MATCH (c:Concept)-[r*1..1]-(n:Concept) WHERE c.concept_id = 'def' RETURN c, r, n;
12+
- MATCH (c:Concept) WHERE c.concept_id = 'xyz' RETURN c;
13+
```
14+
15+
The `+` operator merges results into the graph. The `-` operator removes nodes and their edges. This lets you sculpt a graph by building it up and trimming it down.
16+
17+
## Creating a Saved Query
18+
19+
### From Smart Search (2D/3D Graph)
20+
21+
Every action you take in the graph explorer is recorded as a step:
22+
23+
1. **Search** for a concept — step recorded as `+ MATCH ...`
24+
2. **Right-click a node** and choose "Add Adjacent" — step recorded as `+`
25+
3. **Right-click a node** and choose "Remove from Graph" — step recorded as `-`
26+
4. **Follow** a concept (double-click) — step recorded as `+`
27+
28+
When you have a graph you want to keep:
29+
1. Open the **Saved Queries** panel (folder icon in the left rail)
30+
2. Click **Save Exploration**
31+
3. Give it a name
32+
4. The full step sequence is saved as a replayable program
33+
34+
### From the Cypher Editor
35+
36+
Write `+` and `-` prefixed statements directly:
37+
38+
```
39+
+ MATCH (c:Concept)-[r*1..2]-(n:Concept) WHERE c.label CONTAINS 'governance' RETURN c, r, n;
40+
- MATCH (c:Concept) WHERE c.label CONTAINS 'deprecated' RETURN c;
41+
```
42+
43+
Save via the Saved Queries panel.
44+
45+
### From the Block Editor
46+
47+
Block diagrams compile to Cypher statements. Save via the panel as a block diagram definition.
48+
49+
## Loading a Saved Query
50+
51+
1. Open any explorer view
52+
2. Open the **Saved Queries** panel (folder icon)
53+
3. Click a saved query
54+
55+
The system replays each statement in order, applying `+/-` operators to build the graph state. The result is identical to the original exploration.
56+
57+
## Cross-Explorer Flow
58+
59+
Saved queries are shared across all explorer views. Save in one, load in another:
60+
61+
| Explorer | What it shows from the same query |
62+
|----------|-----------------------------------|
63+
| 2D Graph | Force-directed node/edge visualization |
64+
| 3D Graph | Spatial perspective of the same graph |
65+
| Cypher Editor | The `+/-` statements as editable text |
66+
| Vocabulary Analysis | Relationship type breakdown of query results |
67+
| Document Explorer | Source documents for the query's concepts |
68+
| Polarity Explorer | Semantic axis analysis of query concepts |
69+
| Embedding Landscape | Embedding space projection of query concepts |
70+
71+
Switching views preserves the graph. The folder icon appears consistently in all rails.
72+
73+
## Query Types
74+
75+
Each saved query has a type that determines how it replays:
76+
77+
| Type | Saved From | Contains |
78+
|------|-----------|----------|
79+
| `exploration` | Smart search, Cypher editor | `{ op, cypher }[]` statements |
80+
| `polarity` | Polarity explorer | Pole concept IDs + analysis params |
81+
| `block_diagram` | Block editor | ReactFlow nodes/edges layout |
82+
83+
The Saved Queries panel shows type-aware subtitles (e.g., "3 steps" for explorations, "2 poles" for polarity).
84+
85+
## The +/- Operator Algebra
86+
87+
The operators work like set arithmetic on graph results:
88+
89+
- **`+` (union)**: Execute the Cypher statement and merge its nodes/edges into the current graph. Duplicate nodes are deduplicated by ID.
90+
- **`-` (difference)**: Execute the Cypher statement and remove matching nodes from the current graph. Edges connected to removed nodes are also removed.
91+
92+
### Example: Building a Focused Subgraph
93+
94+
```
95+
# Start with everything related to "governance"
96+
+ MATCH (c:Concept)-[r*1..2]-(n) WHERE c.label CONTAINS 'governance' RETURN c, r, n;
97+
98+
# Add concepts about "compliance"
99+
+ MATCH (c:Concept)-[r*1..1]-(n) WHERE c.label CONTAINS 'compliance' RETURN c, r, n;
100+
101+
# Remove noise — concepts about "legacy systems"
102+
- MATCH (c:Concept) WHERE c.label CONTAINS 'legacy' RETURN c;
103+
```
104+
105+
This produces a graph focused on governance + compliance, with legacy system noise trimmed out.
106+
107+
## Exporting to Cypher
108+
109+
From the 2D/3D graph explorer, your exploration can be sent to the Cypher editor:
110+
111+
1. Build your graph through search and navigation
112+
2. The exploration session is automatically tracked
113+
3. Switch to the Cypher editor tab
114+
4. Your steps appear as `+/-` prefixed statements
115+
5. Edit, rearrange, or share the text
116+
117+
The text format is designed to be copy/pasteable between users.
118+
119+
## Document Explorer Integration
120+
121+
The Document Explorer uses saved exploration queries differently:
122+
123+
1. Load an exploration query
124+
2. The system finds all documents containing those concepts
125+
3. A multi-document concept graph is built automatically
126+
4. Passage search adds colored rings to matching nodes
127+
5. Double-click a document to view it with highlighted passages
128+
129+
## Tips
130+
131+
- **Name queries descriptively** — "Governance + Compliance minus Legacy" is better than "Query 1"
132+
- **Start broad, then subtract** — it's easier to remove noise than to find everything piecemeal
133+
- **Use the Cypher editor to inspect** — seeing the statements helps understand what an exploration actually does
134+
- **Cross-explorer replay is instant** — saved queries don't re-fetch from the API, they replay the recorded operations
135+
136+
## Next Steps
137+
138+
- [Exploring Knowledge](exploring.md) — General search and navigation
139+
- [Querying](querying.md) — CLI, API, and MCP query access
140+
- [Polarity Axis Analysis](POLARITY_AXIS_ANALYSIS.md) — Semantic dimension analysis

docs/guides/exploring.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,5 +248,6 @@ If you have separate knowledge bases, search both to see how different document
248248

249249
## Next Steps
250250

251+
- [Saved Queries](SAVED_QUERIES.md) - Save, load, and share explorations across views
251252
- [Understanding Grounding](understanding-grounding.md) - Interpret confidence scores
252253
- [Querying](querying.md) - Programmatic access via CLI, API, and MCP

web/src/explorers/common/useGraphContextMenu.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,13 @@ import {
3838
FileSpreadsheet,
3939
} from 'lucide-react';
4040

41+
/** Identifies the node a context menu was opened on. @verified 7b5be48d */
4142
export interface NodeContextMenuParams {
4243
nodeId: string;
4344
nodeLabel: string;
4445
}
4546

47+
/** Callbacks wired into the context menu — generic actions plus explorer-specific ones. @verified 7b5be48d */
4648
export interface GraphContextMenuHandlers {
4749
// Generic handlers (provided by hook)
4850
handleFollowConcept: (nodeId: string) => Promise<void>;
@@ -68,6 +70,7 @@ export interface GraphContextMenuHandlers {
6870
applyDestinationMarker?: (nodeId: string) => void;
6971
}
7072

73+
/** Lifecycle callbacks from the context menu overlay back to the explorer. @verified 7b5be48d */
7174
export interface GraphContextMenuCallbacks {
7275
onClose: () => void;
7376
onSettingsChange?: (settings: any) => void;

web/src/hooks/useQueryReplay.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { useGraphStore, type SearchParams } from '../store/graphStore';
1313
import { apiClient } from '../api/client';
1414
import { mapCypherResultToRawGraph } from '../utils/cypherResultMapper';
1515

16+
/** Minimal shape a saved query must have to be replayed (exploration, polarity, or legacy). @verified 7b5be48d */
1617
export interface ReplayableDefinition {
1718
id?: number;
1819
name?: string;

web/src/store/graphStore.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ interface UISettings {
3838

3939
// Search parameters — parameter-presence model where mode is derived, not declared.
4040
// SearchBar sets these, ExplorerView reacts to them.
41+
/** Active query authoring mode in the search bar. @verified 7b5be48d */
4142
export type QueryMode = 'smart-search' | 'block-builder' | 'cypher-editor';
4243

44+
/** Parameter-presence model for graph queries; mode is derived, not declared. @verified 7b5be48d */
4345
export interface SearchParams {
4446
// Primary concept (always present for any search)
4547
primaryConceptId?: string;
@@ -59,9 +61,10 @@ export interface SearchParams {
5961
loadMode: 'clean' | 'add';
6062
}
6163

62-
// Derived from which parameters are populated — never stored explicitly
64+
/** Derived query mode: idle (no primary), explore (neighborhood), or path (A→B). @verified 7b5be48d */
6365
export type DerivedMode = 'idle' | 'explore' | 'path';
6466

67+
/** Derive the query mode from which SearchParams fields are populated. @verified 7b5be48d */
6568
export function deriveMode(params: SearchParams): DerivedMode {
6669
if (!params.primaryConceptId) return 'idle';
6770
if (params.destinationConceptId) return 'path';
@@ -278,6 +281,7 @@ const defaultSearchParams: SearchParams = {
278281
loadMode: 'clean',
279282
};
280283

284+
/** Central Zustand store for graph state, exploration session, and UI settings. @verified 7b5be48d */
281285
export const useGraphStore = create<GraphStore>()(
282286
persist(
283287
(set) => ({

web/src/store/queryDefinitionStore.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ interface QueryDefinitionStoreActions {
6868

6969
type QueryDefinitionStore = QueryDefinitionStoreState & QueryDefinitionStoreActions;
7070

71+
/** Zustand store for saved query definitions — CRUD + pagination against the API. @verified 7b5be48d */
7172
export const useQueryDefinitionStore = create<QueryDefinitionStore>()(
7273
persist(
7374
(set, get) => ({

web/src/views/ExplorerView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ interface ExplorerViewProps {
3434
explorerType: VisualizationType;
3535
}
3636

37+
/** Main explorer view — search bar, graph renderer, saved queries panel, and Cypher editor. @verified 7b5be48d */
3738
export const ExplorerView: React.FC<ExplorerViewProps> = ({ explorerType }) => {
3839
const navigate = useNavigate();
3940
const [urlParams, setUrlParams] = useSearchParams();

0 commit comments

Comments
 (0)