Add Cortex Portal — web visualization for knowledge graph
Express API server wrapping existing store/graph core with REST endpoints for nodes, edges, graph, and search. React + Vite portal with React Flow for interactive graph visualization, Tailwind CSS styling, and full CRUD UI (sidebar, node panel, add/link modals, search bar, toast notifications).
This commit is contained in:
44
portal/src/api.ts
Normal file
44
portal/src/api.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { CortexNode, CortexEdge, GraphData, NodeWithConnections, SearchResult, NodeKind, EdgeType } from './types';
|
||||
|
||||
const BASE = '/api';
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`${BASE}${path}`, {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
...init,
|
||||
});
|
||||
if (!res.ok) {
|
||||
const body = await res.json().catch(() => ({}));
|
||||
throw new Error(body.error || `HTTP ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export const api = {
|
||||
listNodes: (params?: { kind?: string; status?: string; tags?: string }) =>
|
||||
request<CortexNode[]>(`/nodes?${new URLSearchParams(params as any || {})}`),
|
||||
|
||||
getNode: (id: string) =>
|
||||
request<NodeWithConnections>(`/nodes/${id}`),
|
||||
|
||||
addNode: (body: { kind: NodeKind; title: string; content?: string; status?: string; tags?: string[] }) =>
|
||||
request<CortexNode>('/nodes', { method: 'POST', body: JSON.stringify(body) }),
|
||||
|
||||
updateNode: (id: string, body: Record<string, any>) =>
|
||||
request<CortexNode>(`/nodes/${id}`, { method: 'PATCH', body: JSON.stringify(body) }),
|
||||
|
||||
deleteNode: (id: string, hard = false) =>
|
||||
request<{ ok: boolean }>(`/nodes/${id}?hard=${hard}`, { method: 'DELETE' }),
|
||||
|
||||
addEdge: (body: { fromId: string; toId: string; type: EdgeType }) =>
|
||||
request<CortexEdge>('/edges', { method: 'POST', body: JSON.stringify(body) }),
|
||||
|
||||
deleteEdge: (id: string) =>
|
||||
request<{ ok: boolean }>(`/edges/${id}`, { method: 'DELETE' }),
|
||||
|
||||
getGraph: () =>
|
||||
request<GraphData>('/graph'),
|
||||
|
||||
search: (text: string, options?: Record<string, any>) =>
|
||||
request<SearchResult[]>('/search', { method: 'POST', body: JSON.stringify({ text, options }) }),
|
||||
};
|
||||
Reference in New Issue
Block a user