feat: Phase 4 - Notes + Graph + Wikilinks

- Wikilink parser: [[Title]], [[Title|Display]], [[entity_type:Title]] patterns
- Notes REST API: CRUD under /api/domains/[domainId]/notes/ with wikilink sync
- Note link service: idempotent wikilink resolution, backlinks, outgoing links
- Notes list page: search, filter (all/pinned/archived), domain selector
- Note editor: TipTap with backlinks panel and outgoing links display
- Graph data API: /api/domains/[domainId]/graph and /api/graph
- Graph view page: D3 force-directed graph with entity type filters, search, zoom
- Keyboard shortcuts: g g → graph, c n → new note
- 18 passing wikilink parser tests
- All API routes follow AGENTS.md contract (activity + pg_notify)
This commit is contained in:
2026-07-29 06:56:23 -04:00
parent 064a46f97d
commit 40a26d2672
14 changed files with 1827 additions and 135 deletions
+19
View File
@@ -0,0 +1,19 @@
// AGENT INSTRUCTION: After every write (INSERT/UPDATE/DELETE), you MUST:
// 1. Insert activity feed entry
// 2. Call pg.notify('project_e_events', JSON.stringify({ type, action, id, workspace_id }))
// See AGENTS.md for full rules.
import { NextRequest, NextResponse } from 'next/server';
import { withAuth } from '@/lib/auth';
import { getGlobalGraphData } from '@/lib/graph-service';
// GET /api/graph — Get global graph data (all domains the user has access to)
export const GET = withAuth(async (request: NextRequest, user) => {
const graphData = await getGlobalGraphData();
return NextResponse.json(graphData, {
headers: {
'Cache-Control': 'private, max-age=30, stale-while-revalidate=120',
},
});
});