feat: Step 10 - Node Editor & AI-Powered Linking
Implemented the node editor page and AI-powered link suggestions: 1. Node Editor Page (/editor/[id]): - Form with title and body fields using Mantine - Pre-fill support from query params (for chat redirects) - "Find Related" button to discover similar nodes - "Publish Node" button to save to ATproto + SurrealDB - Display of suggested links with similarity scores - Mantine notifications for success/error feedback 2. Suggest Links API (/api/suggest-links): - Authenticates using SurrealDB JWT cookie - Generates embedding for draft text using Google AI - Performs vector similarity search using SurrealDB - Returns top 5 most similar nodes with cosine scores - Enforces row-level security (users only see their nodes) 3. Magnitude Tests: - Editor page rendering - Pre-filled form from query params - Publishing new nodes - Form validation The editor integrates with the existing /api/nodes write-through cache from Step 6, completing the node creation workflow. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
43
tests/magnitude/10-linking.mag.ts
Normal file
43
tests/magnitude/10-linking.mag.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { test } from 'magnitude-test';
|
||||
|
||||
test('Editor page renders correctly', async (agent) => {
|
||||
await agent.act('Navigate to /editor/new');
|
||||
await agent.check('The text "Create New Node" is visible on the screen');
|
||||
await agent.check('A text input field labeled "Title" is visible');
|
||||
await agent.check('A textarea labeled "Body" is visible');
|
||||
await agent.check('A button labeled "Find Related" is visible');
|
||||
await agent.check('A button labeled "Publish Node" is visible');
|
||||
});
|
||||
|
||||
test('[Happy Path] User can navigate to editor from chat', async (agent) => {
|
||||
// Simulate pre-filled form from chat redirect
|
||||
await agent.act('Navigate to /editor/new?title=My%20Idea&body=This%20is%20my%20thought');
|
||||
await agent.check('The "Title" input contains "My Idea"');
|
||||
await agent.check('The "Body" textarea contains "This is my thought"');
|
||||
});
|
||||
|
||||
test('[Happy Path] User can fill out and publish a new node', async (agent) => {
|
||||
// Navigate to the editor
|
||||
await agent.act('Navigate to /editor/new');
|
||||
|
||||
// Fill out the form
|
||||
await agent.act('Type "My First Published Node" into the "Title" input');
|
||||
await agent.act('Type "This is the body of my first node. It contains interesting thoughts about technology and innovation." into the "Body" textarea');
|
||||
|
||||
// Click Publish
|
||||
await agent.act('Click the "Publish Node" button');
|
||||
|
||||
// Check: User is redirected to chat (galaxy not implemented yet)
|
||||
await agent.check('The page URL contains "/chat"');
|
||||
});
|
||||
|
||||
test('[Unhappy Path] Publishing requires both title and body', async (agent) => {
|
||||
await agent.act('Navigate to /editor/new');
|
||||
|
||||
// Try to publish without filling in the form
|
||||
await agent.act('Click the "Publish Node" button');
|
||||
|
||||
// The form should prevent submission (Mantine form validation)
|
||||
// The URL should still be /editor/new
|
||||
await agent.check('The page URL contains "/editor/new"');
|
||||
});
|
||||
Reference in New Issue
Block a user