4.2 KiB
Ironpad - Chat Handover Document
Date: 2026-02-05
Context: See ai-context.md for full project overview
Session Summary
This session focused on fixing a critical bug where notes and tasks displayed stale/wrong content when switching between items. The issue caused data loss as the wrong content was being saved to the wrong files.
What Was Fixed
Problem: Stale Content When Switching Notes/Tasks
Symptoms:
- Click note A → shows content correctly
- Click note B → still shows note A's content
- Refresh sometimes fixes it, sometimes shows blank
- Auto-save then overwrites note B with note A's content (DATA LOSS)
Root Cause: The Milkdown WYSIWYG editor wasn't properly recreating when switching items. Two issues:
-
Module-level variables in
MilkdownEditorCore.vue- State likecurrentContentwas persisting across component recreations because they wereletvariables instead of Vuerefs. -
Race condition in view components - The editor key was changing BEFORE content was loaded:
noteId changes → editor recreates with empty content → content loads → too late
Solution:
- Converted module-level
letvariables torefs inMilkdownEditorCore.vue - Added retry mechanism for applying pending content
- Introduced separate
editorKeyref in all view components that only updates AFTER content is loaded - Added guards to prevent emitting stale content
Files Modified:
frontend/src/components/MilkdownEditorCore.vuefrontend/src/components/MilkdownEditor.vuefrontend/src/views/ProjectNotesView.vuefrontend/src/views/TasksView.vuefrontend/src/views/NotesView.vue
Outstanding Issues
All major issues from this session have been resolved:
- Auto-save aggressiveness - FIXED: Now tracks "last saved content" and only saves when actual changes are made
- Documentation - FIXED: Added README.md, docs/ARCHITECTURE.md, docs/API.md
Technical Context for Future Sessions
Milkdown Editor Lifecycle (Critical Knowledge)
The Milkdown editor (WYSIWYG markdown) has a complex lifecycle:
MilkdownProviderprovides Vue contextuseEditorhook creates theCrepeinstanceCrepe.editoris the actual Milkdown Editoreditor.action(replaceAll(content))updates content- BUT
editor.actionisn't immediately available afteruseEditorreturns
Key Pattern: Always set content BEFORE changing the editor key:
// CORRECT
editorContent.value = newContent
editorKey.value = newId // Editor recreates with correct defaultValue
// WRONG
editorKey.value = newId // Editor recreates with stale/empty content
editorContent.value = newContent // Too late!
Project Structure
ironpad/
├── backend/ # Rust Axum server (API only)
├── frontend/ # Vue 3 SPA
│ └── src/
│ ├── components/
│ │ ├── MilkdownEditor.vue # Wrapper component
│ │ └── MilkdownEditorCore.vue # Actual editor (key file!)
│ ├── views/
│ │ ├── NotesView.vue # Standalone notes
│ │ ├── ProjectNotesView.vue # Project-specific notes
│ │ └── TasksView.vue # Project tasks
│ └── stores/ # Pinia state management
└── data/ # Markdown files (source of truth)
Recommended Next Steps
Fix auto-save aggressiveness- DONE: UseslastSavedContentto track actual changesCreate proper README.md- DONE: See/README.md,/frontend/README.mdAdd developer documentation- DONE: See/docs/ARCHITECTURE.md,/docs/API.md- Consider adding tests - At minimum, test the content switching logic
Commands Reference
# Backend (from backend/)
cargo run # API server on :3000
# Frontend (from frontend/)
npm run dev # Dev server on :5173
npm run build # Production build
Notes
- Windows + PowerShell environment
- Files are the database (no SQL)
- Git auto-commits every 60 seconds
- See
ai-context.mdfor full feature list and API endpoints