Phase 5 - BYOB Backend (TASK-007A/B): - LocalSQL Adapter with full CloudStore API compatibility - QueryBuilder translates Parse-style queries to SQL - SchemaManager with PostgreSQL/Supabase export - LocalBackendServer with REST endpoints - BackendManager with IPC handlers for Electron - In-memory fallback when better-sqlite3 unavailable Phase 3 - GitHub Panel (GIT-004): - Issues tab with list/detail views - Pull Requests tab with list/detail views - GitHub API client with OAuth support - Repository info hook integration Phase 3 - Editor UX Bugfixes (TASK-013): - Legacy runtime detection banners - Read-only enforcement for legacy projects - Code editor modal close improvements - Property panel stuck state fix - Blockly node deletion and UI polish Phase 11 - Cloud Functions Planning: - Architecture documentation for workflow automation - Execution history storage schema design - Canvas overlay concept for debugging Docs: Updated LEARNINGS.md and COMMON-ISSUES.md
TASK-001D: Legacy Project Read-Only Enforcement
Overview
When users open legacy (React 17) projects in "read-only" mode, they need clear visual feedback and actual editing prevention. Currently, NodeGraphEditor.setReadOnly(true) is called, but users can still edit everything.
Problem Statement
Current Behavior:
- User clicks "Open Read-Only" on legacy project
- Project opens in editor
- User can edit nodes, connections, properties, etc. (nothing is actually blocked!)
- No visual indication that project is in special mode
- No way to start migration from within editor
Expected Behavior:
- EditorBanner appears explaining read-only mode
- Banner offers "Migrate Now" button
- All editing operations are blocked with helpful tooltips
- User can still navigate, inspect, and preview
- Clear path to migration without leaving editor
Success Criteria
- EditorBanner component created and styled
- Banner shows when
NodeGraphEditor.isReadOnly()is true - Banner has "Migrate Now" and "Learn More" buttons
- Node editing blocked (properties panel shows "Read-only mode")
- Connection creation/deletion blocked
- Node creation/deletion blocked
- Hover tooltips explain "Migrate to React 19 to edit"
- Preview/deploy still work (no editing needed)
- "Migrate Now" launches MigrationWizard successfully
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Editor (Legacy Project) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ EditorBanner (NEW) │ │
│ │ ⚠️ Legacy Project (React 17) - Read-Only Mode │ │
│ │ │ │
│ │ This project needs migration to React 19 before │ │
│ │ editing. You can inspect safely or migrate now. │ │
│ │ │ │
│ │ [Migrate Now] [Learn More] [✕ Dismiss] │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Canvas (Read-Only) │ │
│ │ • Nodes display normally │ │
│ │ • Can select and inspect │ │
│ │ • Cannot drag or delete │ │
│ │ • Hover shows: "Read-only - Migrate to edit" │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Properties Panel (Read-Only) │ │
│ │ ⚠️ Read-Only Mode - Migrate to React 19 to edit │ │
│ │ [All inputs disabled/grayed out] │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Implementation Plan
Phase 1: EditorBanner Component (2-3 hours)
Create Banner Component:
packages/noodl-editor/src/editor/src/views/EditorBanner/EditorBanner.tsxpackages/noodl-editor/src/editor/src/views/EditorBanner/EditorBanner.module.scsspackages/noodl-editor/src/editor/src/views/EditorBanner/index.ts
Banner Features:
- Fixed positioning at top of editor (above canvas, below menu bar)
- Yellow/orange warning color scheme
- Clear messaging about read-only status
- Action buttons: "Migrate Now", "Learn More", "Dismiss"
- Dismiss saves state (don't show again this session)
- Re-appears on next project open
Styling:
.EditorBanner {
position: fixed;
top: var(--menu-bar-height);
left: 0;
right: 0;
z-index: 1000;
background: var(--theme-color-warning-bg);
border-bottom: 2px solid var(--theme-color-warning);
padding: 12px 20px;
display: flex;
align-items: center;
gap: 16px;
}
Phase 2: Wire Banner to Editor (1 hour)
Integration Points:
packages/noodl-editor/src/editor/src/views/nodegrapheditor.ts- Check
this.isReadOnly()on project load - Emit event when read-only state changes
- React component listens to event and shows/hides banner
Event Pattern:
// In NodeGraphEditor
if (this.isReadOnly()) {
EventDispatcher.instance.emit('NodeGraphEditor.readOnlyModeEnabled', {
projectName: this.getProject().name,
runtimeVersion: this.getProject().runtimeVersion
});
}
Phase 3: Enforce Read-Only Restrictions (3-4 hours)
Canvas Restrictions:
- Block node dragging
- Block connection creation (mouse events)
- Block node deletion (keyboard + context menu)
- Show tooltip on hover: "Read-only mode - migrate to edit"
Properties Panel:
- Add banner at top: "⚠️ Read-Only Mode"
- Disable all input fields
- Gray out all controls
- Keep visibility/fold states working
Context Menus:
- Disable "Delete", "Duplicate", "Cut", "Paste"
- Keep "Copy", "Select All", "View", etc.
Keyboard Shortcuts:
- Block: Delete, Backspace, Ctrl+V, Ctrl+X
- Allow: Ctrl+C, Arrow keys, Zoom, Pan
Components Panel:
- Show disabled state when dragging
- Tooltip: "Cannot add nodes in read-only mode"
Phase 4: Migration Flow from Editor (1-2 hours)
"Migrate Now" Button:
- Opens MigrationWizard as dialog overlay
- Pre-fills source path from current project
- On completion:
- Save any inspection notes
- Close current project
- Open migrated project
- Remove read-only mode
- Show success toast
Implementation:
const handleMigrateNow = () => {
const currentProject = NodeGraphEditor.instance.getProject();
const sourcePath = currentProject._retainedProjectDirectory;
DialogLayerModel.instance.showDialog((close) => (
<MigrationWizard
sourcePath={sourcePath}
projectName={currentProject.name}
onComplete={(targetPath) => {
close();
// Navigate to migrated project
router.route({ to: 'editor', projectPath: targetPath });
}}
onCancel={close}
/>
));
};
Files to Create
packages/noodl-editor/src/editor/src/views/EditorBanner/
├── EditorBanner.tsx # Main banner component
├── EditorBanner.module.scss # Banner styling
└── index.ts # Exports
Files to Modify
packages/noodl-editor/src/editor/src/views/
├── nodegrapheditor.ts # Emit read-only events
└── EditorPage.tsx # Mount EditorBanner
packages/noodl-editor/src/editor/src/views/panels/propertyeditor/
└── PropertyPanel.tsx # Show read-only banner + disable inputs
packages/noodl-editor/src/editor/src/views/
├── NodeGraphEditor/ # Block editing interactions
└── ContextMenu/ # Disable destructive actions
Testing Strategy
Manual Testing
-
Banner Appearance
- Open legacy project in read-only mode
- Banner appears at top
- Correct messaging displayed
- Buttons are clickable
-
Editing Prevention
- Try to drag nodes → Blocked
- Try to create connections → Blocked
- Try to delete nodes → Blocked
- Try to edit properties → Blocked
- Try keyboard shortcuts → Blocked
-
Allowed Operations
- Navigate canvas → Works
- Select nodes → Works
- View properties → Works
- Copy nodes → Works
- Preview project → Works
-
Migration Flow
- Click "Migrate Now" → Wizard opens
- Complete migration → Opens migrated project
- Verify read-only mode gone → Can edit
Automated Tests
describe('EditorBanner', () => {
it('shows when project is read-only', () => {
// Test banner visibility
});
it('hides when dismissed', () => {
// Test dismiss button
});
it('launches migration wizard on "Migrate Now"', () => {
// Test migration flow
});
});
describe('Read-Only Enforcement', () => {
it('blocks node dragging', () => {
// Test canvas interactions
});
it('blocks property editing', () => {
// Test property panel
});
it('allows navigation and viewing', () => {
// Test allowed operations
});
});
Design Considerations
User Experience
- Progressive Disclosure: Don't overwhelm with restrictions, let user discover naturally
- Clear Messaging: Always explain WHY (legacy project) and WHAT to do (migrate)
- Non-Blocking: Allow inspection and navigation freely
- Easy Path Forward: One-click migration from banner
Visual Design
- Warning Color: Yellow/orange to indicate caution, not error
- Prominent Position: Top of editor, can't be missed
- Dismissible: User can focus on inspection without constant reminder
- Consistent: Match warning badge style from launcher
Technical Design
- Event-Driven: Banner reacts to read-only state changes
- Reusable: EditorBanner component can be used for other notifications
- Performant: No impact on editor load time
- Testable: Clear separation of concerns
Dependencies
- ✅ TASK-001C SUBTASK-A & D (Completed - provides detection + launcher UI)
- ✅ Phase 2 TASK-004 (Migration system exists)
- ✅ NodeGraphEditor.setReadOnly() (Exists, just needs enforcement)
Blocks
None - can be implemented independently
Success Metrics
- Edit Prevention: 100% of destructive operations blocked
- User Clarity: Banner message tested with 5+ users for comprehension
- Migration Conversion: Track % of read-only opens that lead to migration
- Performance: No measurable impact on editor load time (<50ms)
Future Enhancements
- Custom Dialog: Replace native
confirm()with React dialog for better UX - Inspection Mode: Add special features for read-only (compare with other version, etc.)
- Partial Migration: Allow user to migrate just certain components
- Preview Comparison: Show before/after preview of migration changes
Notes
Why This is Important
Users who choose "Open Read-Only" expect:
- Safety: Can't accidentally break their legacy project
- Clarity: Understand why they can't edit
- Path Forward: Easy way to migrate when ready
Without enforcement, "read-only" is just a label that doesn't prevent damage.
Technical Challenges
- Event Blocking: Need to intercept at multiple levels (mouse, keyboard, API)
- UI State: Many components need to know about read-only mode
- Migration Context: Need to maintain project path/state during migration
Reference Implementation
Look at how Figma handles "View-only" mode:
- Clear banner at top
- Disabled editing with tooltips
- Easy upgrade path
- Preview still works
Created: January 13, 2026
Status: 📋 Ready for Implementation
Priority: High - Blocks legacy project safety
Estimated Time: 6-9 hours