feat: Implement node deletion with shared modal and fix SurrealDB RecordId handling
Implements complete node deletion functionality for both galaxy view and debug panel: **Core Changes:** - Created shared DeleteNodeModal component used by both ThoughtGalaxy and UserMenu - Modal provides consistent UX with proper confirmation messaging - Deletion follows write-through cache pattern: ATproto first, then SurrealDB **SurrealDB RecordId Fixes:** - Fixed SELECT query to use type::thing($table, $recordId) for UUID-based RecordIds - Fixed DELETE query to use type::thing() instead of db.delete() to handle dashes in UUIDs - Without type::thing(), SurrealDB interprets dashes as subtraction operators **Testing & Documentation:** - Added comprehensive Magnitude tests for delete functionality (galaxy view and debug panel) - Updated CLAUDE.md with complete testing workflow documentation - Added pre-commit checklist requiring database verification and test execution - Documented PlaywrightMCP manual testing process before Magnitude test writing **Database Setup:** - Configured docker-compose.yml to use environment variables for credentials - Updated namespace/database to match .env configuration (ponderants/main) **File Changes:** - app/api/nodes/[id]/route.ts: Fixed RecordId query patterns (SELECT and DELETE) - components/DeleteNodeModal.tsx: New shared modal component - components/ThoughtGalaxy.tsx: Uses shared DeleteNodeModal - components/UserMenu.tsx: Replaced browser confirm() with shared DeleteNodeModal - tests/magnitude/03-delete-node.mag.ts: Added debug panel delete test - AGENTS.md: Added testing workflow and pre-commit checklist documentation - docker-compose.yml: Environment variable configuration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -135,3 +135,70 @@ test('Node deletion removes associated links', async (agent) => {
|
||||
await agent.check('The link between the nodes is no longer visible');
|
||||
await agent.check('Only one node remains in the galaxy');
|
||||
});
|
||||
|
||||
test('User can delete node from debug panel in Profile menu', async (agent) => {
|
||||
// Act: Log in
|
||||
await agent.act('Navigate to /login');
|
||||
await agent.act(`Type "${TEST_HANDLE}" into the "Your Handle" input field`);
|
||||
await agent.act('Click the "Log in with Bluesky" button');
|
||||
await agent.check('The page URL contains "bsky.social"');
|
||||
await agent.act(`Type "${TEST_HANDLE}" into the username/identifier field`);
|
||||
await agent.act(`Type "${TEST_PASSWORD}" into the password field`);
|
||||
await agent.act('Click the submit/authorize button');
|
||||
await agent.check('The page URL contains "/chat"');
|
||||
|
||||
// Act: Create a test node via chat
|
||||
await agent.act('Type "Test node for debug panel deletion" into the chat input');
|
||||
await agent.act('Press Enter or click send');
|
||||
await agent.check('AI responds with a message');
|
||||
|
||||
// Act: Trigger node creation and publish
|
||||
await agent.act('Wait for the AI to suggest creating a node or manually trigger node creation');
|
||||
await agent.check('A node draft is created in the editor');
|
||||
await agent.act('Click the "Publish" button');
|
||||
await agent.check('A success notification appears');
|
||||
|
||||
// Act: Open Profile menu
|
||||
await agent.act('Click the "Profile" button in the navigation sidebar');
|
||||
await agent.check('The Profile menu opens');
|
||||
|
||||
// Check: Verify debug panel is visible (development mode only)
|
||||
await agent.check('A "Debug: SurrealDB Nodes" section is visible');
|
||||
|
||||
// Act: Fetch nodes from debug panel
|
||||
await agent.act('Click the "Fetch Nodes" button');
|
||||
await agent.check('The button shows a count greater than 0');
|
||||
await agent.check('At least one node is listed in the debug panel');
|
||||
|
||||
// Check: Verify the test node appears
|
||||
await agent.check('The node "Test node for debug panel deletion" is visible');
|
||||
|
||||
// Act: Click delete button in debug panel
|
||||
await agent.act('Click the "Delete" button next to the test node');
|
||||
|
||||
// Check: Verify delete confirmation modal appears
|
||||
await agent.check('A delete confirmation modal appears');
|
||||
await agent.check('The modal is displayed above the profile menu');
|
||||
await agent.check('The modal shows the node title "Test node for debug panel deletion"');
|
||||
await agent.check('The modal explains this will remove the post from Bluesky');
|
||||
await agent.check('The modal shows "This action cannot be undone"');
|
||||
await agent.check('The modal has a "Delete Permanently" button');
|
||||
await agent.check('The modal has a "Cancel" button');
|
||||
|
||||
// Act: Confirm deletion
|
||||
await agent.act('Click the "Delete Permanently" button');
|
||||
|
||||
// Check: Verify deletion succeeded
|
||||
await agent.check('A success notification appears saying "Node deleted"');
|
||||
await agent.check('The notification says "Node has been deleted from Bluesky and your galaxy"');
|
||||
await agent.check('The modal closes');
|
||||
|
||||
// Check: Verify node is removed from debug panel
|
||||
await agent.check('The "Fetch Nodes" button shows a count of 0 or the node is no longer in the list');
|
||||
|
||||
// Act: Verify node is deleted from Bluesky and database
|
||||
await agent.act('Refresh the page');
|
||||
await agent.act('Click the "Profile" button again');
|
||||
await agent.act('Click the "Fetch Nodes" button');
|
||||
await agent.check('The node "Test node for debug panel deletion" is not in the list');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user