mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-11 23:02:56 +01:00
Finished task 1. Added task for backwards compatibility on existing Noodl projects
This commit is contained in:
@@ -1,601 +0,0 @@
|
||||
# Cline Development Guidelines for OpenNoodl
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides guidelines for AI-assisted development on the OpenNoodl codebase using Cline in VSCode. Follow these guidelines to ensure consistent, well-documented, and testable contributions.
|
||||
|
||||
---
|
||||
|
||||
## 1. Before Starting Any Task
|
||||
|
||||
### 1.1 Understand the Context
|
||||
|
||||
```bash
|
||||
# Always check which branch you're on
|
||||
git branch
|
||||
|
||||
# Check for uncommitted changes
|
||||
git status
|
||||
|
||||
# Review recent commits
|
||||
git log --oneline -10
|
||||
```
|
||||
|
||||
### 1.2 Read Relevant Documentation
|
||||
|
||||
Before modifying any file, understand its purpose:
|
||||
|
||||
1. Check for README files in the package
|
||||
2. Read JSDoc comments on functions
|
||||
3. Look for related test files
|
||||
4. Search for usage patterns: `grep -r "functionName" packages/`
|
||||
|
||||
### 1.3 Identify Dependencies
|
||||
|
||||
```bash
|
||||
# Check what imports a file
|
||||
grep -r "from.*filename" packages/
|
||||
|
||||
# Check what the file imports
|
||||
head -50 path/to/file.ts | grep "import"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Code Style Requirements
|
||||
|
||||
### 2.1 TypeScript Standards
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Explicit types
|
||||
interface NodeProps {
|
||||
id: string;
|
||||
type: NodeType;
|
||||
connections: Connection[];
|
||||
}
|
||||
|
||||
function processNode(node: NodeProps): ProcessedNode {
|
||||
// ...
|
||||
}
|
||||
|
||||
// ❌ BAD: Implicit any
|
||||
function processNode(node) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// ❌ BAD: Using TSFixme
|
||||
function processNode(node: TSFixme): TSFixme {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 React Component Standards
|
||||
|
||||
```tsx
|
||||
// ✅ GOOD: Functional component with types
|
||||
interface ButtonProps {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export function Button({ label, onClick, disabled = false }: ButtonProps) {
|
||||
return (
|
||||
<button onClick={onClick} disabled={disabled}>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
// ❌ BAD: Class component (unless necessary for lifecycle)
|
||||
class Button extends React.Component {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 Import Organization
|
||||
|
||||
```typescript
|
||||
// 1. External packages (alphabetical)
|
||||
import classNames from 'classnames';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
// 2. Internal packages (alphabetical by alias)
|
||||
import { IconName } from '@noodl-core-ui/components/common/Icon';
|
||||
import { NodeGraphModel } from '@noodl-models/nodegraphmodel';
|
||||
import { KeyCode } from '@noodl-utils/keyboard/KeyCode';
|
||||
|
||||
// 3. Relative imports (by depth, then alphabetical)
|
||||
import { localHelper } from './helpers';
|
||||
import css from './Component.module.scss';
|
||||
```
|
||||
|
||||
### 2.4 Naming Conventions
|
||||
|
||||
| Type | Convention | Example |
|
||||
|------|------------|---------|
|
||||
| Components | PascalCase | `NodeEditor.tsx` |
|
||||
| Hooks | camelCase, use prefix | `useNodeSelection.ts` |
|
||||
| Utils | camelCase | `formatNodeName.ts` |
|
||||
| Constants | UPPER_SNAKE | `MAX_CONNECTIONS` |
|
||||
| CSS Modules | kebab-case | `node-editor.module.scss` |
|
||||
| Test files | Same + .test | `NodeEditor.test.tsx` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Documentation Requirements
|
||||
|
||||
### 3.1 File Headers
|
||||
|
||||
Every new file should have a header comment:
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* NodeProcessor
|
||||
*
|
||||
* Handles the processing of node graph updates and manages
|
||||
* the execution order of connected nodes.
|
||||
*
|
||||
* @module noodl-runtime
|
||||
* @since 1.2.0
|
||||
*/
|
||||
```
|
||||
|
||||
### 3.2 Function Documentation
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Processes a node and propagates changes to connected nodes.
|
||||
*
|
||||
* @param node - The node to process
|
||||
* @param context - The execution context
|
||||
* @param options - Processing options
|
||||
* @param options.force - Force re-evaluation even if inputs unchanged
|
||||
* @returns The processed output values
|
||||
* @throws {NodeProcessingError} If the node definition is invalid
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const output = processNode(myNode, context, { force: true });
|
||||
* console.log(output.value);
|
||||
* ```
|
||||
*/
|
||||
function processNode(
|
||||
node: NodeInstance,
|
||||
context: ExecutionContext,
|
||||
options: ProcessOptions = {}
|
||||
): NodeOutput {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Complex Logic Comments
|
||||
|
||||
```typescript
|
||||
// Calculate the topological sort order for node evaluation.
|
||||
// This ensures nodes are processed after their dependencies.
|
||||
// Uses Kahn's algorithm for O(V+E) complexity.
|
||||
const sortedNodes = topologicalSort(nodes, connections);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Testing Requirements
|
||||
|
||||
### 4.1 Test File Location
|
||||
|
||||
Tests should be co-located or in a parallel `tests/` directory:
|
||||
|
||||
```
|
||||
// Option A: Co-located
|
||||
components/
|
||||
├── Button/
|
||||
│ ├── Button.tsx
|
||||
│ ├── Button.test.tsx
|
||||
│ └── Button.module.scss
|
||||
|
||||
// Option B: Parallel (current pattern in noodl-editor)
|
||||
packages/noodl-editor/
|
||||
├── src/
|
||||
│ └── components/Button.tsx
|
||||
└── tests/
|
||||
└── components/Button.test.ts
|
||||
```
|
||||
|
||||
### 4.2 Test Structure
|
||||
|
||||
```typescript
|
||||
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
|
||||
describe('useNodeSelection', () => {
|
||||
// Setup
|
||||
let mockContext: NodeGraphContext;
|
||||
|
||||
beforeEach(() => {
|
||||
mockContext = createMockContext();
|
||||
});
|
||||
|
||||
// Group related tests
|
||||
describe('when selecting a single node', () => {
|
||||
it('should update selection state', () => {
|
||||
const { result } = renderHook(() => useNodeSelection(mockContext));
|
||||
|
||||
act(() => {
|
||||
result.current.selectNode('node-1');
|
||||
});
|
||||
|
||||
expect(result.current.selectedNodes).toContain('node-1');
|
||||
});
|
||||
|
||||
it('should clear previous selection by default', () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
|
||||
describe('when multi-selecting nodes', () => {
|
||||
// ...
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 4.3 What to Test
|
||||
|
||||
| Priority | What to Test |
|
||||
|----------|--------------|
|
||||
| High | Utility functions |
|
||||
| High | Data transformations |
|
||||
| High | State management logic |
|
||||
| Medium | React hooks |
|
||||
| Medium | Component behavior |
|
||||
| Low | Pure UI rendering |
|
||||
|
||||
---
|
||||
|
||||
## 5. Git Workflow
|
||||
|
||||
### 5.1 Branch Naming
|
||||
|
||||
```bash
|
||||
# Features
|
||||
git checkout -b feature/add-vercel-deployment
|
||||
|
||||
# Bug fixes
|
||||
git checkout -b fix/page-router-scroll
|
||||
|
||||
# Refactoring
|
||||
git checkout -b refactor/remove-tsfixme-panels
|
||||
|
||||
# Documentation
|
||||
git checkout -b docs/update-node-api
|
||||
```
|
||||
|
||||
### 5.2 Commit Messages
|
||||
|
||||
Follow conventional commits:
|
||||
|
||||
```bash
|
||||
# Format: type(scope): description
|
||||
|
||||
# Features
|
||||
git commit -m "feat(editor): add breakpoint support for node connections"
|
||||
|
||||
# Bug fixes
|
||||
git commit -m "fix(viewer): resolve scroll position reset in nested Page Router"
|
||||
|
||||
# Refactoring
|
||||
git commit -m "refactor(runtime): replace TSFixme with proper types in node processor"
|
||||
|
||||
# Documentation
|
||||
git commit -m "docs(api): add JSDoc to all public node methods"
|
||||
|
||||
# Tests
|
||||
git commit -m "test(editor): add unit tests for node selection hook"
|
||||
|
||||
# Chores
|
||||
git commit -m "chore(deps): update react to 19.0.0"
|
||||
```
|
||||
|
||||
### 5.3 Commit Frequency
|
||||
|
||||
- Commit after each logical change
|
||||
- Don't combine unrelated changes
|
||||
- Commit working states (tests should pass)
|
||||
|
||||
---
|
||||
|
||||
## 6. Codebase Navigation
|
||||
|
||||
### 6.1 Key Directories
|
||||
|
||||
```
|
||||
packages/
|
||||
├── noodl-editor/
|
||||
│ ├── src/
|
||||
│ │ ├── editor/src/
|
||||
│ │ │ ├── models/ # Data models (ProjectModel, NodeGraph, etc.)
|
||||
│ │ │ ├── views/ # UI components and views
|
||||
│ │ │ ├── utils/ # Helper utilities
|
||||
│ │ │ ├── store/ # State stores (AI Assistant, etc.)
|
||||
│ │ │ └── pages/ # Page-level components
|
||||
│ │ ├── main/ # Electron main process
|
||||
│ │ └── shared/ # Shared utilities
|
||||
│ └── tests/ # Test files
|
||||
│
|
||||
├── noodl-runtime/
|
||||
│ └── src/
|
||||
│ ├── nodes/ # Runtime node definitions
|
||||
│ └── nodecontext.js # Execution context
|
||||
│
|
||||
├── noodl-viewer-react/
|
||||
│ └── src/
|
||||
│ └── nodes/ # React-based visual nodes
|
||||
│
|
||||
└── noodl-core-ui/
|
||||
└── src/
|
||||
└── components/ # Shared UI components
|
||||
```
|
||||
|
||||
### 6.2 Finding Things
|
||||
|
||||
```bash
|
||||
# Find a component
|
||||
find packages/ -name "*NodeEditor*" -type f
|
||||
|
||||
# Find where something is imported
|
||||
grep -r "import.*from.*NodeEditor" packages/
|
||||
|
||||
# Find where a function is called
|
||||
grep -r "processNode(" packages/ --include="*.ts" --include="*.tsx"
|
||||
|
||||
# Find all TODO comments
|
||||
grep -rn "TODO\|FIXME" packages/noodl-editor/src
|
||||
|
||||
# Find test files
|
||||
find packages/ -name "*.test.ts" -o -name "*.spec.ts"
|
||||
```
|
||||
|
||||
### 6.3 Understanding Data Flow
|
||||
|
||||
1. **User Action** → `views/` components capture events
|
||||
2. **State Update** → `models/` handle business logic
|
||||
3. **Runtime Sync** → `ViewerConnection` sends to preview
|
||||
4. **Persistence** → `ProjectModel` saves to disk
|
||||
|
||||
---
|
||||
|
||||
## 7. Common Patterns
|
||||
|
||||
### 7.1 Event Handling Pattern
|
||||
|
||||
```typescript
|
||||
// Models use EventDispatcher for pub/sub
|
||||
import { EventDispatcher } from '../../../shared/utils/EventDispatcher';
|
||||
|
||||
class MyModel extends EventDispatcher {
|
||||
doSomething() {
|
||||
// ... logic
|
||||
this.notifyListeners('updated', { data: result });
|
||||
}
|
||||
}
|
||||
|
||||
// Usage
|
||||
const model = new MyModel();
|
||||
model.on('updated', (data) => {
|
||||
console.log('Model updated:', data);
|
||||
});
|
||||
```
|
||||
|
||||
### 7.2 React Hook Pattern
|
||||
|
||||
```typescript
|
||||
// Custom hook for model subscription
|
||||
function useModel<T>(model: EventDispatcher, event: string): T {
|
||||
const [state, setState] = useState<T>(model.getState());
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (newState: T) => setState(newState);
|
||||
model.on(event, handler);
|
||||
return () => model.off(event, handler);
|
||||
}, [model, event]);
|
||||
|
||||
return state;
|
||||
}
|
||||
```
|
||||
|
||||
### 7.3 Node Definition Pattern
|
||||
|
||||
```javascript
|
||||
// In noodl-runtime/src/nodes/
|
||||
const MyNode = {
|
||||
name: 'My.Custom.Node',
|
||||
displayName: 'My Custom Node',
|
||||
category: 'Custom',
|
||||
|
||||
inputs: {
|
||||
inputValue: {
|
||||
type: 'string',
|
||||
displayName: 'Input Value',
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
outputValue: {
|
||||
type: 'string',
|
||||
displayName: 'Output Value'
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
setInputValue(value) {
|
||||
this._internal.inputValue = value;
|
||||
this.flagOutputDirty('outputValue');
|
||||
}
|
||||
},
|
||||
|
||||
getOutputValue(name) {
|
||||
if (name === 'outputValue') {
|
||||
return this._internal.inputValue.toUpperCase();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Error Handling
|
||||
|
||||
### 8.1 User-Facing Errors
|
||||
|
||||
```typescript
|
||||
import { ToastLayer } from '../views/ToastLayer/ToastLayer';
|
||||
|
||||
try {
|
||||
await riskyOperation();
|
||||
} catch (error) {
|
||||
// Log for debugging
|
||||
console.error('Operation failed:', error);
|
||||
|
||||
// Show user-friendly message
|
||||
ToastLayer.showError('Unable to complete operation. Please try again.');
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 Developer Errors
|
||||
|
||||
```typescript
|
||||
// Use assertions for developer errors
|
||||
function processNode(node: NodeInstance) {
|
||||
if (!node.id) {
|
||||
throw new Error(`processNode: node.id is required`);
|
||||
}
|
||||
|
||||
if (!node.definition) {
|
||||
throw new Error(`processNode: node "${node.id}" has no definition`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8.3 Graceful Degradation
|
||||
|
||||
```typescript
|
||||
function getNodeIcon(node: NodeInstance): string {
|
||||
try {
|
||||
return node.definition.icon || 'default-icon';
|
||||
} catch {
|
||||
console.warn(`Could not get icon for node ${node.id}`);
|
||||
return 'default-icon';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Performance Considerations
|
||||
|
||||
### 9.1 Avoid Unnecessary Re-renders
|
||||
|
||||
```tsx
|
||||
// ✅ GOOD: Memoized callback
|
||||
const handleClick = useCallback(() => {
|
||||
onNodeSelect(node.id);
|
||||
}, [node.id, onNodeSelect]);
|
||||
|
||||
// ✅ GOOD: Memoized expensive computation
|
||||
const sortedNodes = useMemo(() => {
|
||||
return topologicalSort(nodes);
|
||||
}, [nodes]);
|
||||
|
||||
// ❌ BAD: New function on every render
|
||||
<Button onClick={() => onNodeSelect(node.id)} />
|
||||
```
|
||||
|
||||
### 9.2 Lazy Loading
|
||||
|
||||
```tsx
|
||||
// Lazy load heavy components
|
||||
const CodeEditor = React.lazy(() => import('./CodeEditor'));
|
||||
|
||||
function EditorPanel() {
|
||||
return (
|
||||
<Suspense fallback={<LoadingSpinner />}>
|
||||
<CodeEditor />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 9.3 Batch Updates
|
||||
|
||||
```typescript
|
||||
// Batch multiple state updates
|
||||
import { unstable_batchedUpdates } from 'react-dom';
|
||||
|
||||
unstable_batchedUpdates(() => {
|
||||
setSelection(newSelection);
|
||||
setHighlight(newHighlight);
|
||||
setZoom(newZoom);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Checklist Before Submitting
|
||||
|
||||
### Code Quality
|
||||
- [ ] No `TSFixme` types added
|
||||
- [ ] All new functions have JSDoc comments
|
||||
- [ ] Complex logic has inline comments
|
||||
- [ ] No console.log statements (except errors/warnings)
|
||||
- [ ] No unused imports or variables
|
||||
|
||||
### Testing
|
||||
- [ ] Unit tests for new utility functions
|
||||
- [ ] Integration tests for new features
|
||||
- [ ] Existing tests still pass
|
||||
- [ ] Manual testing completed
|
||||
|
||||
### Documentation
|
||||
- [ ] README updated if needed
|
||||
- [ ] JSDoc added to public APIs
|
||||
- [ ] Comments explain "why", not "what"
|
||||
|
||||
### Git
|
||||
- [ ] Meaningful commit messages
|
||||
- [ ] No unrelated changes in commits
|
||||
- [ ] Branch named correctly
|
||||
- [ ] Based on latest main branch
|
||||
|
||||
### Performance
|
||||
- [ ] No obvious performance regressions
|
||||
- [ ] Large lists use virtualization
|
||||
- [ ] Expensive computations are memoized
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Commands
|
||||
|
||||
```bash
|
||||
# Development
|
||||
npm run dev # Start editor with hot reload
|
||||
npm run test:editor # Run tests
|
||||
npm run build:editor # Production build
|
||||
|
||||
# Code Quality
|
||||
npx eslint packages/noodl-editor/src --fix
|
||||
npx prettier --write "packages/**/*.{ts,tsx}"
|
||||
npx tsc --noEmit # Type check
|
||||
|
||||
# Debugging
|
||||
DEBUG=* npm run dev # Verbose logging
|
||||
npm run test:editor -- --verbose
|
||||
|
||||
# Finding Issues
|
||||
grep -r "TSFixme" packages/ # Find type escapes
|
||||
grep -r "any" packages/ --include="*.ts" | head -20
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: December 2024*
|
||||
@@ -4,112 +4,136 @@ Track all changes made during this task. Update this file as you work.
|
||||
|
||||
---
|
||||
|
||||
## [Date] - [Your Name/Handle]
|
||||
## [2025-06-12] - Cline (AI-assisted)
|
||||
|
||||
### Summary
|
||||
[To be filled in as work progresses]
|
||||
Fixed React 19 TypeScript compatibility errors that were preventing the build from completing. The previous developer updated dependencies but did not address all the TypeScript compatibility issues with the new `@types/react` package.
|
||||
|
||||
### Starting Point
|
||||
- Based on branch: `12-upgrade-dependencies`
|
||||
- Previous work by: [previous developer]
|
||||
- Previous work by: previous developer
|
||||
- Previous commits include:
|
||||
- Package.json dependency updates
|
||||
- Package.json dependency updates (React 17 → 19)
|
||||
- "Update rendering to use non-deprecated react-dom calls"
|
||||
|
||||
---
|
||||
|
||||
## Dependency Fixes
|
||||
## React 19 TypeScript Fixes
|
||||
|
||||
### Package: [package-name]
|
||||
- **Issue**: [What was wrong]
|
||||
- **Fix**: [What was changed]
|
||||
- **File**: `path/to/package.json`
|
||||
### Issue 1: Unused `@ts-expect-error` directives
|
||||
React 19's types fixed some underlying issues that were previously suppressed with `@ts-expect-error`. These now cause errors when the underlying issue no longer exists.
|
||||
|
||||
---
|
||||
### Issue 2: `useRef()` requires explicit type parameter
|
||||
In React 19's types, `useRef()` without a type parameter returns `RefObject<unknown>`, which is not assignable to more specific ref types.
|
||||
|
||||
## React 19 Migration
|
||||
**Fix**: Changed `useRef()` to `useRef<HTMLDivElement>(null)`
|
||||
|
||||
### File: [filename]
|
||||
- **Before**: `ReactDOM.render(<App />, element)`
|
||||
- **After**: `createRoot(element).render(<App />)`
|
||||
- **Notes**: [Any relevant context]
|
||||
### Issue 3: `JSX` namespace moved
|
||||
In React 19, `JSX` is no longer a global namespace. It must be accessed as `React.JSX`.
|
||||
|
||||
---
|
||||
**Fix**: Changed `keyof JSX.IntrinsicElements` to `keyof React.JSX.IntrinsicElements`
|
||||
|
||||
## react-instantsearch Migration
|
||||
### Issue 4: `ReactFragment` export removed
|
||||
React 19 no longer exports `ReactFragment`. Use `Iterable<React.ReactNode>` instead.
|
||||
|
||||
### File: HelpCenter.tsx
|
||||
- **Before**: `import { ... } from 'react-instantsearch-hooks-web'`
|
||||
- **After**: `import { ... } from 'react-instantsearch'`
|
||||
- **API Changes**: [List any API differences encountered]
|
||||
### Issue 5: `children` not implicitly included in props
|
||||
React 19 no longer implicitly includes `children` in component props. It must be explicitly declared.
|
||||
|
||||
**Fix**: Added `children?: React.ReactNode` to component prop interfaces.
|
||||
|
||||
### Issue 6: `ReactDOM.findDOMNode` removed
|
||||
React 19 removed the deprecated `findDOMNode` API.
|
||||
|
||||
**Fix**: Access DOM elements directly from refs rather than using `findDOMNode`.
|
||||
|
||||
---
|
||||
|
||||
## Build Fixes
|
||||
|
||||
### Error: [Error message]
|
||||
- **Cause**: [Why it happened]
|
||||
- **Fix**: [What was changed]
|
||||
- **File**: `path/to/file`
|
||||
### Error: TS2578: Unused '@ts-expect-error' directive
|
||||
- **Cause**: React 19 types fixed the type inference for `React.cloneElement()`
|
||||
- **Fix**: Removed the `@ts-expect-error` comment
|
||||
- **Files**:
|
||||
- `packages/noodl-core-ui/src/components/layout/Columns/Columns.tsx`
|
||||
- `packages/noodl-viewer-react/src/components/visual/Columns/Columns.tsx`
|
||||
|
||||
---
|
||||
### Error: TS2554: Expected 1 arguments, but got 0 (useRef)
|
||||
- **Cause**: React 19's types require an initial value for `useRef()`
|
||||
- **Fix**: Added type parameter and null initial value: `useRef<HTMLDivElement>(null)`
|
||||
- **Files**:
|
||||
- `packages/noodl-core-ui/src/components/app/SideNavigation/SideNavigation.tsx`
|
||||
- `packages/noodl-core-ui/src/components/popups/ContextMenu/ContextMenu.tsx`
|
||||
|
||||
## Build Optimizations
|
||||
### Error: TS2322: RefObject<unknown> not assignable to RefObject<HTMLElement>
|
||||
- **Cause**: Untyped `useRef()` returns `RefObject<unknown>`
|
||||
- **Fix**: Same as above - add explicit type parameter
|
||||
- **Files**: Same as above
|
||||
|
||||
### Optimization: [Name]
|
||||
- **Before**: Build time X seconds
|
||||
- **After**: Build time Y seconds
|
||||
- **Change**: [What was optimized]
|
||||
### Error: TS2305: Module 'react' has no exported member 'ReactFragment'
|
||||
- **Cause**: `ReactFragment` was removed in React 19
|
||||
- **Fix**: Replaced with `Iterable<React.ReactNode>`
|
||||
- **File**: `packages/noodl-viewer-react/src/types.ts`
|
||||
|
||||
### Error: TS2503: Cannot find namespace 'JSX'
|
||||
- **Cause**: `JSX` is no longer a global namespace in React 19
|
||||
- **Fix**: Changed `JSX.IntrinsicElements` to `React.JSX.IntrinsicElements`
|
||||
- **Files**:
|
||||
- `packages/noodl-viewer-react/src/components/visual/Group/Group.tsx`
|
||||
- `packages/noodl-viewer-react/src/components/visual/Text/Text.tsx`
|
||||
|
||||
### Error: TS2339: Property 'children' does not exist on type
|
||||
- **Cause**: React 19 no longer implicitly includes `children` in props
|
||||
- **Fix**: Added `children?: React.ReactNode` to component interfaces
|
||||
- **Files**:
|
||||
- `packages/noodl-viewer-react/src/components/visual/Drag/Drag.tsx`
|
||||
- `packages/noodl-viewer-react/src/components/visual/Group/Group.tsx`
|
||||
|
||||
### Error: Property 'findDOMNode' does not exist on ReactDOM
|
||||
- **Cause**: `findDOMNode` removed from React 19
|
||||
- **Fix**: Access DOM element directly from ref instead of using findDOMNode
|
||||
- **File**: `packages/noodl-viewer-react/src/components/visual/Group/Group.tsx`
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
<!-- Update this list as you make changes -->
|
||||
|
||||
- [ ] `package.json` (root)
|
||||
- [ ] `packages/noodl-editor/package.json`
|
||||
- [ ] `packages/noodl-core-ui/package.json`
|
||||
- [ ] `packages/noodl-viewer-react/package.json`
|
||||
- [ ] `packages/noodl-editor/src/editor/src/views/HelpCenter/HelpCenter.tsx`
|
||||
- [ ] [Add more as needed]
|
||||
- [x] `packages/noodl-core-ui/src/components/layout/Columns/Columns.tsx`
|
||||
- [x] `packages/noodl-core-ui/src/components/app/SideNavigation/SideNavigation.tsx`
|
||||
- [x] `packages/noodl-core-ui/src/components/popups/ContextMenu/ContextMenu.tsx`
|
||||
- [x] `packages/noodl-viewer-react/src/types.ts`
|
||||
- [x] `packages/noodl-viewer-react/src/components/visual/Columns/Columns.tsx`
|
||||
- [x] `packages/noodl-viewer-react/src/components/visual/Drag/Drag.tsx`
|
||||
- [x] `packages/noodl-viewer-react/src/components/visual/Group/Group.tsx`
|
||||
- [x] `packages/noodl-viewer-react/src/components/visual/Text/Text.tsx`
|
||||
|
||||
---
|
||||
|
||||
## Files Created
|
||||
<!-- List any new files created -->
|
||||
|
||||
- None expected for this task
|
||||
- None
|
||||
|
||||
---
|
||||
|
||||
## Files Deleted
|
||||
<!-- List any files removed -->
|
||||
|
||||
- None expected for this task
|
||||
- None
|
||||
|
||||
---
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- React 19 requires Node.js 18+ (documented in root package.json engines)
|
||||
- [Add any other breaking changes discovered]
|
||||
- `findDOMNode` usage removed - code now accesses refs directly
|
||||
|
||||
---
|
||||
|
||||
## Testing Notes
|
||||
|
||||
### Automated Tests
|
||||
- `npm run test:editor`: [PASS/FAIL] - [Notes]
|
||||
- `npm run test:platform`: [PASS/FAIL] - [Notes]
|
||||
- `npx tsc --noEmit`: [PASS/FAIL] - [Notes]
|
||||
- `npm run dev`: **PASS** - All three packages (Editor, Viewer, Cloud) compile successfully
|
||||
|
||||
### Manual Tests
|
||||
- Dev server start: [PASS/FAIL]
|
||||
- Create project: [PASS/FAIL]
|
||||
- Node operations: [PASS/FAIL]
|
||||
- Preview: [PASS/FAIL]
|
||||
- Help Center search: [PASS/FAIL]
|
||||
- Hot reload: [PASS/FAIL]
|
||||
- Dev server start: **PASS** - Editor launches, Viewer compiles, Cloud compiles
|
||||
|
||||
---
|
||||
|
||||
@@ -117,24 +141,20 @@ Track all changes made during this task. Update this file as you work.
|
||||
|
||||
<!-- Document any issues discovered that aren't fixed in this task -->
|
||||
|
||||
1. [Issue description] - [Will be addressed in TASK-XXX]
|
||||
1. Deprecation warnings for Sass legacy JS API - Non-blocking, can be addressed in future task
|
||||
2. Deprecation warning for `Buffer()` - Non-blocking, comes from dependency
|
||||
|
||||
---
|
||||
|
||||
## Follow-up Tasks
|
||||
|
||||
<!-- Note any work that should be done in future tasks -->
|
||||
|
||||
1. [Follow-up item] - Suggested for TASK-XXX
|
||||
1. Consider updating Sass configuration to use modern API - Future task
|
||||
2. Review `scrollToElement` functionality to ensure it works correctly with the new ref-based approach - Manual testing needed
|
||||
|
||||
---
|
||||
|
||||
## Final Summary
|
||||
|
||||
[To be completed when task is done]
|
||||
|
||||
**Total files modified**: X
|
||||
**Total lines changed**: +X / -Y
|
||||
**Build time**: Before X sec → After Y sec
|
||||
**Tests**: All passing / X failures
|
||||
**Confidence**: X/10
|
||||
**Total files modified**: 8
|
||||
**Build status**: All packages compiling successfully (was 95 errors, now 0)
|
||||
**Confidence**: 8/10 (code compiles, but manual testing of `scrollToElement` functionality recommended)
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
# TASK-002 Changelog: Legacy Project Migration
|
||||
|
||||
---
|
||||
|
||||
## [2025-01-XX] - Task Created
|
||||
|
||||
### Summary
|
||||
Task documentation created for legacy project migration and backward compatibility system.
|
||||
|
||||
### Files Created
|
||||
- `dev-docs/tasks/phase-1/TASK-002-legacy-project-migration/README.md` - Full task specification
|
||||
- `dev-docs/tasks/phase-1/TASK-002-legacy-project-migration/CHECKLIST.md` - Implementation checklist
|
||||
- `dev-docs/tasks/phase-1/TASK-002-legacy-project-migration/CHANGELOG.md` - This file
|
||||
- `dev-docs/tasks/phase-1/TASK-002-legacy-project-migration/NOTES.md` - Working notes
|
||||
|
||||
### Notes
|
||||
- This task depends on TASK-001 (Dependency Updates) being complete or in progress
|
||||
- Critical for ensuring existing Noodl users can migrate their production projects
|
||||
- Scope includes CLI tool, migration engine, and editor integration
|
||||
|
||||
---
|
||||
|
||||
## Template for Future Entries
|
||||
|
||||
```markdown
|
||||
## [YYYY-MM-DD] - [Phase/Step Name]
|
||||
|
||||
### Summary
|
||||
[Brief description of what was accomplished]
|
||||
|
||||
### Files Created
|
||||
- `path/to/file.ts` - [Purpose]
|
||||
|
||||
### Files Modified
|
||||
- `path/to/file.ts` - [What changed and why]
|
||||
|
||||
### Files Deleted
|
||||
- `path/to/file.ts` - [Why removed]
|
||||
|
||||
### Breaking Changes
|
||||
- [Any breaking changes and migration path]
|
||||
|
||||
### Testing Notes
|
||||
- [What was tested]
|
||||
- [Any edge cases discovered]
|
||||
|
||||
### Known Issues
|
||||
- [Any remaining issues or follow-up needed]
|
||||
|
||||
### Next Steps
|
||||
- [What needs to be done next]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Progress Summary
|
||||
|
||||
| Phase | Status | Date Started | Date Completed |
|
||||
|-------|--------|--------------|----------------|
|
||||
| Phase 1: Research & Discovery | Not Started | - | - |
|
||||
| Phase 2: Version Detection | Not Started | - | - |
|
||||
| Phase 3: Migration Engine | Not Started | - | - |
|
||||
| Phase 4: Individual Migrations | Not Started | - | - |
|
||||
| Phase 5: Backup System | Not Started | - | - |
|
||||
| Phase 6: CLI Tool | Not Started | - | - |
|
||||
| Phase 7: Editor Integration | Not Started | - | - |
|
||||
| Phase 8: Validation & Testing | Not Started | - | - |
|
||||
| Phase 9: Documentation | Not Started | - | - |
|
||||
| Phase 10: Completion | Not Started | - | - |
|
||||
@@ -0,0 +1,330 @@
|
||||
# TASK-002 Checklist: Legacy Project Migration
|
||||
|
||||
## Prerequisites
|
||||
- [ ] Read README.md completely
|
||||
- [ ] Understand the scope and success criteria
|
||||
- [ ] Ensure TASK-001 (Dependency Updates) is complete or in progress
|
||||
- [ ] Create branch: `git checkout -b task/002-legacy-project-migration`
|
||||
- [ ] Verify build works: `npm run build:editor`
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Research & Discovery
|
||||
|
||||
### Project Format Analysis
|
||||
- [ ] Locate sample Noodl projects (old versions)
|
||||
- [ ] Document the folder structure of a `.noodl` project
|
||||
- [ ] Identify all JSON file types within projects
|
||||
- [ ] Document schema for each file type
|
||||
- [ ] Check for existing version metadata in project files
|
||||
- [ ] Update NOTES.md with findings
|
||||
|
||||
### Node Definition Analysis
|
||||
- [ ] Catalog all node types in `packages/noodl-runtime/src/nodes/`
|
||||
- [ ] Document input/output schemas for nodes
|
||||
- [ ] Identify any deprecated node types
|
||||
- [ ] Note any node API changes over versions
|
||||
- [ ] Update NOTES.md with findings
|
||||
|
||||
### Breaking Changes Audit
|
||||
- [ ] Review TASK-001 dependency update list
|
||||
- [ ] For each updated dependency, identify breaking changes:
|
||||
- [ ] React 17 → 19 impacts
|
||||
- [ ] react-instantsearch changes
|
||||
- [ ] Other dependency changes
|
||||
- [ ] Map breaking changes to project file impact
|
||||
- [ ] Create comprehensive migration requirements list
|
||||
- [ ] Update NOTES.md with findings
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Version Detection System
|
||||
|
||||
### Design
|
||||
- [ ] Define `ProjectVersion` interface
|
||||
- [ ] Define version detection strategy
|
||||
- [ ] Document how to infer version from project structure
|
||||
|
||||
### Implementation
|
||||
- [ ] Create `packages/noodl-editor/src/editor/src/utils/migration/` folder
|
||||
- [ ] Create `version-detect.ts` module
|
||||
- [ ] Implement explicit version metadata check
|
||||
- [ ] Implement file structure inference
|
||||
- [ ] Implement node usage pattern inference
|
||||
- [ ] Add fallback for "unknown/legacy" projects
|
||||
|
||||
### Testing
|
||||
- [ ] Write unit tests for version detection
|
||||
- [ ] Test with sample projects from different versions
|
||||
- [ ] Document in CHANGELOG.md
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Migration Engine Core
|
||||
|
||||
### Design
|
||||
- [ ] Define `Migration` interface
|
||||
- [ ] Define `MigrationResult` interface
|
||||
- [ ] Design migration path calculation algorithm
|
||||
- [ ] Document migration registration pattern
|
||||
|
||||
### Implementation
|
||||
- [ ] Create `migration-engine.ts` module
|
||||
- [ ] Implement `MigrationEngine` class
|
||||
- [ ] Implement `registerMigration()` method
|
||||
- [ ] Implement `getMigrationPath()` method
|
||||
- [ ] Implement `migrateProject()` method
|
||||
- [ ] Implement rollback capability
|
||||
- [ ] Add progress reporting hooks
|
||||
|
||||
### Testing
|
||||
- [ ] Write unit tests for migration engine
|
||||
- [ ] Test migration path calculation
|
||||
- [ ] Test rollback functionality
|
||||
- [ ] Document in CHANGELOG.md
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Individual Migrations
|
||||
|
||||
### Migration: React 17 → 19 Patterns
|
||||
- [ ] Identify all React-specific patterns in project files
|
||||
- [ ] Create `v17-to-v19-react.ts` migration
|
||||
- [ ] Write migration transform logic
|
||||
- [ ] Write validation logic
|
||||
- [ ] Write unit tests
|
||||
|
||||
### Migration: Node Format Changes (if needed)
|
||||
- [ ] Identify node format changes between versions
|
||||
- [ ] Create `node-format-update.ts` migration
|
||||
- [ ] Write migration transform logic
|
||||
- [ ] Write validation logic
|
||||
- [ ] Write unit tests
|
||||
|
||||
### Migration: Connection Schema (if needed)
|
||||
- [ ] Identify connection schema changes
|
||||
- [ ] Create `connection-schema.ts` migration
|
||||
- [ ] Write migration transform logic
|
||||
- [ ] Write validation logic
|
||||
- [ ] Write unit tests
|
||||
|
||||
### Additional Migrations (as discovered)
|
||||
- [ ] Document each new migration needed
|
||||
- [ ] Implement migrations as needed
|
||||
- [ ] Write tests for each
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Backup System
|
||||
|
||||
### Implementation
|
||||
- [ ] Create `backup.ts` utility module
|
||||
- [ ] Implement `backupProject()` function
|
||||
- [ ] Implement `restoreFromBackup()` function
|
||||
- [ ] Implement backup verification (checksums)
|
||||
- [ ] Implement backup cleanup/rotation
|
||||
|
||||
### Testing
|
||||
- [ ] Test backup creates valid copy
|
||||
- [ ] Test restore works correctly
|
||||
- [ ] Test with large projects
|
||||
- [ ] Document in CHANGELOG.md
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: CLI Tool
|
||||
|
||||
### Package Setup
|
||||
- [ ] Create `packages/noodl-cli/` directory structure
|
||||
- [ ] Create `package.json` with dependencies
|
||||
- [ ] Create `tsconfig.json`
|
||||
- [ ] Set up build scripts
|
||||
- [ ] Add to root workspace configuration
|
||||
|
||||
### Commands Implementation
|
||||
- [ ] Implement `validate` command
|
||||
- [ ] Parse project path argument
|
||||
- [ ] Run version detection
|
||||
- [ ] Report findings
|
||||
- [ ] Return exit code
|
||||
- [ ] Implement `upgrade` command
|
||||
- [ ] Parse arguments (project path, options)
|
||||
- [ ] Create backup
|
||||
- [ ] Run migrations
|
||||
- [ ] Report results
|
||||
- [ ] Implement `batch-upgrade` command
|
||||
- [ ] Parse folder argument
|
||||
- [ ] Discover all projects
|
||||
- [ ] Process each project
|
||||
- [ ] Generate summary report
|
||||
- [ ] Implement `report` command
|
||||
- [ ] Analyze project
|
||||
- [ ] Generate markdown report
|
||||
- [ ] Output to stdout
|
||||
|
||||
### CLI UX
|
||||
- [ ] Add help messages for all commands
|
||||
- [ ] Add `--dry-run` option
|
||||
- [ ] Add `--verbose` option
|
||||
- [ ] Add `--no-backup` option (with warning)
|
||||
- [ ] Add progress indicators
|
||||
- [ ] Add colored output
|
||||
|
||||
### Testing
|
||||
- [ ] Write integration tests for CLI
|
||||
- [ ] Test each command
|
||||
- [ ] Test error handling
|
||||
- [ ] Document in CHANGELOG.md
|
||||
|
||||
### Documentation
|
||||
- [ ] Create CLI README.md
|
||||
- [ ] Document all commands and options
|
||||
- [ ] Add usage examples
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Editor Integration
|
||||
|
||||
### Migration Dialog UI
|
||||
- [ ] Design migration dialog mockup
|
||||
- [ ] Create `MigrationDialog/` component folder
|
||||
- [ ] Implement `MigrationDialog.tsx`
|
||||
- [ ] Implement `MigrationDialog.module.scss`
|
||||
- [ ] Add progress indicator
|
||||
- [ ] Add backup confirmation
|
||||
- [ ] Add cancel option
|
||||
|
||||
### Project Loading Integration
|
||||
- [ ] Locate project loading code (likely `projectmodel.js`)
|
||||
- [ ] Add version detection on project open
|
||||
- [ ] Add migration check logic
|
||||
- [ ] Trigger migration dialog when needed
|
||||
- [ ] Handle user choices (migrate/cancel)
|
||||
- [ ] Show progress during migration
|
||||
- [ ] Handle migration errors gracefully
|
||||
|
||||
### Testing
|
||||
- [ ] Test opening legacy project triggers dialog
|
||||
- [ ] Test migration completes successfully
|
||||
- [ ] Test cancellation works
|
||||
- [ ] Test error handling
|
||||
- [ ] Manual testing scenarios
|
||||
- [ ] Document in CHANGELOG.md
|
||||
|
||||
---
|
||||
|
||||
## Phase 8: Validation & Testing
|
||||
|
||||
### Test Project Corpus
|
||||
- [ ] Collect/create minimal test project
|
||||
- [ ] Collect/create complex test project
|
||||
- [ ] Collect/create project with deprecated nodes
|
||||
- [ ] Collect/create project with custom JavaScript
|
||||
- [ ] Collect/create project from each known version
|
||||
- [ ] Document all test projects
|
||||
|
||||
### Integration Testing
|
||||
- [ ] Run CLI migration on all test projects
|
||||
- [ ] Verify each migrated project opens correctly
|
||||
- [ ] Verify node graphs render correctly
|
||||
- [ ] Verify connections work correctly
|
||||
- [ ] Verify preview runs correctly
|
||||
- [ ] Document any failures
|
||||
|
||||
### Edge Cases
|
||||
- [ ] Test with corrupted project files
|
||||
- [ ] Test with missing files
|
||||
- [ ] Test with extremely large projects
|
||||
- [ ] Test with read-only filesystem
|
||||
- [ ] Test interrupted migration (power loss scenario)
|
||||
- [ ] Document findings
|
||||
|
||||
---
|
||||
|
||||
## Phase 9: Documentation
|
||||
|
||||
### User Documentation
|
||||
- [ ] Create migration guide for users
|
||||
- [ ] Document what changes during migration
|
||||
- [ ] Document how to manually fix issues
|
||||
- [ ] Add FAQ section
|
||||
- [ ] Add troubleshooting guide
|
||||
|
||||
### Developer Documentation
|
||||
- [ ] Document migration engine architecture
|
||||
- [ ] Document how to add new migrations
|
||||
- [ ] Document testing procedures
|
||||
- [ ] Update NOTES.md with learnings
|
||||
|
||||
### Update Existing Docs
|
||||
- [ ] Update main README if needed
|
||||
- [ ] Update dev-docs if needed
|
||||
- [ ] Link to this task from relevant docs
|
||||
|
||||
---
|
||||
|
||||
## Phase 10: Completion
|
||||
|
||||
### Final Validation
|
||||
- [ ] All success criteria from README.md met
|
||||
- [ ] All unit tests pass
|
||||
- [ ] All integration tests pass
|
||||
- [ ] Manual testing complete
|
||||
- [ ] No TypeScript errors: `npx tsc --noEmit`
|
||||
- [ ] No console warnings/errors
|
||||
|
||||
### Cleanup
|
||||
- [ ] Remove any debug code
|
||||
- [ ] Remove any TODO comments (or convert to issues)
|
||||
- [ ] Clean up NOTES.md
|
||||
- [ ] Finalize CHANGELOG.md
|
||||
|
||||
### Submission
|
||||
- [ ] Self-review all changes
|
||||
- [ ] Create pull request
|
||||
- [ ] Update task status
|
||||
- [ ] Notify stakeholders
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Key Files
|
||||
```
|
||||
packages/noodl-cli/ # CLI tool package
|
||||
packages/noodl-editor/src/editor/src/utils/migration/
|
||||
├── version-detect.ts # Version detection
|
||||
├── migration-engine.ts # Core engine
|
||||
├── backup.ts # Backup utilities
|
||||
└── migrations/ # Individual migrations
|
||||
├── index.ts
|
||||
├── v17-to-v19-react.ts
|
||||
└── ...
|
||||
packages/noodl-editor/src/editor/src/views/MigrationDialog/
|
||||
├── MigrationDialog.tsx
|
||||
└── MigrationDialog.module.scss
|
||||
```
|
||||
|
||||
### Useful Commands
|
||||
```bash
|
||||
# Build editor
|
||||
npm run build:editor
|
||||
|
||||
# Run tests
|
||||
npm run test:editor
|
||||
|
||||
# Type check
|
||||
npx tsc --noEmit
|
||||
|
||||
# Search for patterns
|
||||
grep -r "pattern" packages/ --include="*.ts"
|
||||
|
||||
# Run CLI locally
|
||||
node packages/noodl-cli/bin/noodl-migrate.js validate ./test-project
|
||||
```
|
||||
|
||||
### Emergency Rollback
|
||||
If migration breaks something:
|
||||
1. Restore from backup folder
|
||||
2. Disable migration in project loading code
|
||||
3. Document the issue in NOTES.md
|
||||
@@ -0,0 +1,217 @@
|
||||
# TASK-002 Working Notes: Legacy Project Migration
|
||||
|
||||
## Research Findings
|
||||
|
||||
### Project File Structure
|
||||
> Document findings about Noodl project structure here
|
||||
|
||||
**TODO:** Analyze sample .noodl project folders
|
||||
|
||||
```
|
||||
Expected structure (to be verified):
|
||||
my-project/
|
||||
├── project.json # Project metadata
|
||||
├── components/ # Component definitions
|
||||
│ └── component-name/
|
||||
│ └── component.json
|
||||
├── pages/ # Page definitions
|
||||
├── styles/ # Style definitions
|
||||
└── assets/ # Project assets (if any)
|
||||
```
|
||||
|
||||
### Known Version Indicators
|
||||
> Document where version information is stored
|
||||
|
||||
**TODO:** Check these locations for version metadata:
|
||||
- [ ] `project.json` root object
|
||||
- [ ] File header comments
|
||||
- [ ] Metadata fields in component files
|
||||
- [ ] Any `.noodl-version` or similar files
|
||||
|
||||
### Node Definition Changes
|
||||
> Track changes to node definitions across versions
|
||||
|
||||
| Node Type | Old API | New API | Version Changed |
|
||||
|-----------|---------|---------|-----------------|
|
||||
| TBD | TBD | TBD | TBD |
|
||||
|
||||
---
|
||||
|
||||
## Breaking Changes Map
|
||||
|
||||
### From TASK-001 Dependency Updates
|
||||
|
||||
#### React 17 → 19
|
||||
| Change | Impact on Projects | Migration Strategy |
|
||||
|--------|-------------------|-------------------|
|
||||
| `ReactDOM.render()` deprecated | May affect stored render patterns | TBD |
|
||||
| New Suspense behavior | May affect loading states | TBD |
|
||||
| Concurrent features | May affect event handling | TBD |
|
||||
|
||||
#### react-instantsearch-hooks-web → react-instantsearch
|
||||
| Change | Impact on Projects | Migration Strategy |
|
||||
|--------|-------------------|-------------------|
|
||||
| Package rename | Import paths | N/A (editor code only) |
|
||||
| API changes | TBD | TBD |
|
||||
|
||||
#### Other Dependencies
|
||||
> Add findings here as TASK-001 progresses
|
||||
|
||||
---
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### Migration Engine Architecture
|
||||
|
||||
**Decision:** [TBD]
|
||||
**Alternatives Considered:**
|
||||
1. Option A: ...
|
||||
2. Option B: ...
|
||||
**Rationale:** ...
|
||||
|
||||
### Backup Strategy
|
||||
|
||||
**Decision:** [TBD]
|
||||
**Options:**
|
||||
1. In-place backup (`.backup` folder in project)
|
||||
2. External backup location (user-configurable)
|
||||
3. Timestamped copies
|
||||
**Rationale:** ...
|
||||
|
||||
### CLI Tool Location
|
||||
|
||||
**Decision:** [TBD]
|
||||
**Options:**
|
||||
1. New `packages/noodl-cli/` package
|
||||
2. Add to existing `packages/noodl-platform-node/`
|
||||
3. Scripts in `scripts/` directory
|
||||
**Rationale:** ...
|
||||
|
||||
---
|
||||
|
||||
## Questions & Answers
|
||||
|
||||
### Q: Where is project version stored?
|
||||
**A:** [TBD - needs research]
|
||||
|
||||
### Q: What's the oldest supported Noodl version?
|
||||
**A:** [TBD - needs community input]
|
||||
|
||||
### Q: Do we have sample legacy projects for testing?
|
||||
**A:** [TBD - need to source these]
|
||||
|
||||
### Q: Should migration be automatic or opt-in?
|
||||
**A:** [TBD - needs UX decision]
|
||||
|
||||
---
|
||||
|
||||
## Gotchas & Surprises
|
||||
> Document unexpected discoveries here
|
||||
|
||||
### [Discovery 1]
|
||||
- **Date:** TBD
|
||||
- **Finding:** ...
|
||||
- **Impact:** ...
|
||||
- **Resolution:** ...
|
||||
|
||||
---
|
||||
|
||||
## Debug Log
|
||||
|
||||
### Research Phase
|
||||
```
|
||||
[Date/Time] - Starting project format analysis
|
||||
- Trying: ...
|
||||
- Result: ...
|
||||
- Next: ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Useful References
|
||||
|
||||
### Codebase Locations
|
||||
```bash
|
||||
# Project loading code
|
||||
packages/noodl-editor/src/editor/src/models/projectmodel.js
|
||||
|
||||
# Node definitions
|
||||
packages/noodl-runtime/src/nodes/
|
||||
|
||||
# Runtime context
|
||||
packages/noodl-runtime/src/nodecontext.js
|
||||
|
||||
# Viewer React components
|
||||
packages/noodl-viewer-react/src/nodes/
|
||||
```
|
||||
|
||||
### Search Commands
|
||||
```bash
|
||||
# Find project loading logic
|
||||
grep -r "loadProject\|openProject" packages/noodl-editor/ --include="*.ts" --include="*.js"
|
||||
|
||||
# Find version references
|
||||
grep -r "version" packages/noodl-editor/src/editor/src/models/ --include="*.ts" --include="*.js"
|
||||
|
||||
# Find serialization logic
|
||||
grep -r "serialize\|deserialize\|toJSON\|fromJSON" packages/ --include="*.ts" --include="*.js"
|
||||
```
|
||||
|
||||
### External Documentation
|
||||
- React 19 Migration: https://react.dev/blog/2024/04/25/react-19
|
||||
- react-instantsearch v7: https://www.algolia.com/doc/guides/building-search-ui/upgrade-guides/react/
|
||||
|
||||
---
|
||||
|
||||
## Community Feedback
|
||||
> Collect feedback from Noodl users about migration concerns
|
||||
|
||||
### User Concerns
|
||||
1. [TBD]
|
||||
|
||||
### User Requests
|
||||
1. [TBD]
|
||||
|
||||
### Known Legacy Projects in the Wild
|
||||
1. [TBD - need to identify common project patterns]
|
||||
|
||||
---
|
||||
|
||||
## Test Project Inventory
|
||||
|
||||
| Name | Version | Complexity | Contains | Location |
|
||||
|------|---------|------------|----------|----------|
|
||||
| TBD | TBD | TBD | TBD | TBD |
|
||||
|
||||
---
|
||||
|
||||
## Migration Algorithm Pseudocode
|
||||
|
||||
```
|
||||
function migrateProject(projectPath):
|
||||
1. detectVersion(projectPath)
|
||||
2. if currentVersion >= targetVersion:
|
||||
return SUCCESS (no migration needed)
|
||||
3. migrationPath = calculateMigrationPath(currentVersion, targetVersion)
|
||||
4. if migrationPath.length == 0:
|
||||
return ERROR (no migration path)
|
||||
5. backup = createBackup(projectPath)
|
||||
6. for migration in migrationPath:
|
||||
result = migration.execute(projectPath)
|
||||
if result.failed:
|
||||
restoreBackup(backup)
|
||||
return ERROR (migration failed)
|
||||
updateVersionMetadata(projectPath, migration.toVersion)
|
||||
7. validate(projectPath)
|
||||
8. return SUCCESS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Open Items
|
||||
|
||||
- [ ] Get access to legacy Noodl projects for testing
|
||||
- [ ] Confirm oldest version we need to support
|
||||
- [ ] Determine if cloud configurations need migration
|
||||
- [ ] Design migration dialog UX
|
||||
- [ ] Decide on CLI package location and build strategy
|
||||
@@ -0,0 +1,421 @@
|
||||
# TASK-002: Legacy Project Migration & Backward Compatibility
|
||||
|
||||
## Metadata
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| **ID** | TASK-002 |
|
||||
| **Phase** | Phase 1 - Foundation |
|
||||
| **Priority** | 🔴 Critical |
|
||||
| **Difficulty** | 🔴 Hard |
|
||||
| **Estimated Time** | 5-7 days |
|
||||
| **Prerequisites** | TASK-001 (Dependency Updates) |
|
||||
| **Branch** | `task/002-legacy-project-migration` |
|
||||
|
||||
## Objective
|
||||
|
||||
Develop a robust migration system that ensures all existing Noodl projects created with older versions of the editor (and older dependency versions) can be imported into the updated OpenNoodl editor without breaking changes or data loss.
|
||||
|
||||
## Background
|
||||
|
||||
### Why This Task Is Critical
|
||||
|
||||
Many Noodl users have **production projects** that they've built over months or years using previous versions of the Noodl editor. These projects may rely on:
|
||||
|
||||
- Older React version behavior (React 17 and earlier)
|
||||
- Deprecated node APIs
|
||||
- Legacy project file formats
|
||||
- Older dependency APIs (e.g., react-instantsearch-hooks-web vs react-instantsearch)
|
||||
- Previous runtime behaviors
|
||||
|
||||
When we update dependencies in TASK-001 (React 17 → 19, etc.), we risk breaking these existing projects. **This is unacceptable** for our user base. A user should be able to:
|
||||
|
||||
1. Install the new OpenNoodl editor
|
||||
2. Open their 3-year-old Noodl project
|
||||
3. Have it work exactly as before (or with minimal guided fixes)
|
||||
|
||||
### The Stakes
|
||||
|
||||
- Users have business-critical applications built in Noodl
|
||||
- Some users may have hundreds of hours invested in their projects
|
||||
- Breaking backward compatibility could permanently lose users
|
||||
- Our credibility as a fork depends on being a seamless upgrade path
|
||||
|
||||
### How This Fits Into The Bigger Picture
|
||||
|
||||
This task ensures TASK-001 (dependency updates) doesn't create orphaned projects. It's a safety net that must be in place before we can confidently ship updated dependencies.
|
||||
|
||||
## Current State
|
||||
|
||||
### What We Know
|
||||
- Projects are stored as JSON files (graph definitions, components, etc.)
|
||||
- The runtime interprets these files at runtime
|
||||
- Different Noodl versions may have different:
|
||||
- Node definitions
|
||||
- Property types
|
||||
- Connection formats
|
||||
- Metadata schemas
|
||||
|
||||
### What We Don't Know Yet
|
||||
- Exactly which project format versions exist in the wild
|
||||
- How many breaking changes exist between versions
|
||||
- Which node APIs have changed over time
|
||||
- Whether there's existing version metadata in project files
|
||||
|
||||
### Research Needed
|
||||
- [ ] Analyze project file structure
|
||||
- [ ] Document all project file schemas
|
||||
- [ ] Compare old vs new node definitions
|
||||
- [ ] Identify all breaking changes from dependency updates
|
||||
|
||||
## Desired State
|
||||
|
||||
After this task is complete:
|
||||
|
||||
1. **Seamless Import**: Users can open any legacy Noodl project in the new editor
|
||||
2. **Auto-Migration**: Projects are automatically upgraded to the new format when opened
|
||||
3. **CLI Tool**: A command-line utility exists for batch migration and validation
|
||||
4. **No Breaking Changes**: All existing node connections and logic work as before
|
||||
5. **Clear Warnings**: If manual intervention is needed, users see clear guidance
|
||||
6. **Backup Safety**: Original projects are backed up before migration
|
||||
7. **Validation**: A test suite verifies migration works with sample projects
|
||||
|
||||
## Scope
|
||||
|
||||
### In Scope
|
||||
- [ ] Document all Noodl project file formats
|
||||
- [ ] Create a version detection system for projects
|
||||
- [ ] Build a migration engine for auto-upgrading projects
|
||||
- [ ] Develop a CLI tool for import/validation of legacy projects
|
||||
- [ ] Create migration handlers for known breaking changes
|
||||
- [ ] Build a validation test suite with sample projects
|
||||
- [ ] Add user-facing warnings and guidance for edge cases
|
||||
- [ ] Implement automatic backup before migration
|
||||
|
||||
### Out of Scope
|
||||
- Creating new node types (that's feature work)
|
||||
- Fixing bugs in legacy projects (that's user responsibility)
|
||||
- Supporting unofficial Noodl forks
|
||||
- Migrating cloud/backend configurations (separate concern)
|
||||
|
||||
## Technical Approach
|
||||
|
||||
### Phase 1: Research & Analysis
|
||||
|
||||
#### Key Areas to Investigate
|
||||
|
||||
| Area | Files to Examine | Goal |
|
||||
|------|------------------|------|
|
||||
| Project Structure | Sample `.noodl` project folders | Understand file organization |
|
||||
| Graph Format | `*.json` graph files | Document schema |
|
||||
| Node Definitions | `packages/noodl-runtime/src/nodes/` | Map all node types |
|
||||
| Component Format | Component JSON files | Document structure |
|
||||
| Metadata | Project metadata files | Find version indicators |
|
||||
|
||||
#### Questions to Answer
|
||||
1. Where is project version stored? (if at all)
|
||||
2. What changed between Noodl releases?
|
||||
3. Which nodes have breaking API changes?
|
||||
4. What React 17 → 19 patterns affect project files?
|
||||
|
||||
### Phase 2: Version Detection System
|
||||
|
||||
Create a system to identify what version of Noodl created a project:
|
||||
|
||||
```typescript
|
||||
interface ProjectVersion {
|
||||
editorVersion: string; // e.g., "2.8.0"
|
||||
formatVersion: string; // e.g., "1.2"
|
||||
runtimeVersion: string; // e.g., "1.0.0"
|
||||
detectedFeatures: string[]; // Feature flags found
|
||||
}
|
||||
|
||||
function detectProjectVersion(projectPath: string): ProjectVersion {
|
||||
// 1. Check explicit version metadata
|
||||
// 2. Infer from file structure
|
||||
// 3. Infer from node usage patterns
|
||||
// 4. Default to "unknown/legacy"
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: Migration Engine
|
||||
|
||||
Build a pluggable migration system:
|
||||
|
||||
```typescript
|
||||
interface Migration {
|
||||
id: string;
|
||||
fromVersion: string;
|
||||
toVersion: string;
|
||||
description: string;
|
||||
migrate: (project: ProjectData) => ProjectData;
|
||||
validate: (project: ProjectData) => ValidationResult;
|
||||
}
|
||||
|
||||
class MigrationEngine {
|
||||
private migrations: Migration[] = [];
|
||||
|
||||
registerMigration(migration: Migration): void;
|
||||
getMigrationPath(from: string, to: string): Migration[];
|
||||
migrateProject(project: ProjectData, targetVersion: string): MigrationResult;
|
||||
}
|
||||
```
|
||||
|
||||
#### Known Migrations Needed
|
||||
|
||||
| From | To | Migration |
|
||||
|------|-----|-----------|
|
||||
| React 17 patterns | React 19 | Update any stored component patterns |
|
||||
| Old node format | New node format | Transform node definitions |
|
||||
| Legacy connections | New connections | Update connection schema |
|
||||
|
||||
### Phase 4: CLI Tool
|
||||
|
||||
Create a command-line tool for migration:
|
||||
|
||||
```bash
|
||||
# Validate a project without modifying it
|
||||
noodl-migrate validate ./my-project
|
||||
|
||||
# Migrate a project (creates backup first)
|
||||
noodl-migrate upgrade ./my-project
|
||||
|
||||
# Migrate with specific target version
|
||||
noodl-migrate upgrade ./my-project --to-version 3.0
|
||||
|
||||
# Batch migrate multiple projects
|
||||
noodl-migrate batch-upgrade ./projects-folder
|
||||
|
||||
# Generate migration report
|
||||
noodl-migrate report ./my-project > migration-report.md
|
||||
```
|
||||
|
||||
#### CLI Implementation Location
|
||||
|
||||
```
|
||||
packages/noodl-cli/
|
||||
├── package.json
|
||||
├── bin/
|
||||
│ └── noodl-migrate.js
|
||||
├── src/
|
||||
│ ├── commands/
|
||||
│ │ ├── validate.ts
|
||||
│ │ ├── upgrade.ts
|
||||
│ │ ├── batch-upgrade.ts
|
||||
│ │ └── report.ts
|
||||
│ ├── migrations/
|
||||
│ │ ├── index.ts
|
||||
│ │ ├── v17-to-v19-react.ts
|
||||
│ │ ├── legacy-node-format.ts
|
||||
│ │ └── ...
|
||||
│ └── utils/
|
||||
│ ├── backup.ts
|
||||
│ ├── version-detect.ts
|
||||
│ └── validation.ts
|
||||
└── tests/
|
||||
└── ...
|
||||
```
|
||||
|
||||
### Phase 5: Editor Integration
|
||||
|
||||
Integrate migration into the editor's project opening flow:
|
||||
|
||||
```typescript
|
||||
// In project loading code
|
||||
async function openProject(projectPath: string): Promise<Project> {
|
||||
const version = detectProjectVersion(projectPath);
|
||||
|
||||
if (needsMigration(version)) {
|
||||
const result = await showMigrationDialog(projectPath, version);
|
||||
|
||||
if (result === 'migrate') {
|
||||
await backupProject(projectPath);
|
||||
await migrateProject(projectPath);
|
||||
} else if (result === 'cancel') {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return loadProject(projectPath);
|
||||
}
|
||||
```
|
||||
|
||||
### Key Files to Create
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `packages/noodl-cli/` | New package for CLI tool |
|
||||
| `packages/noodl-editor/src/editor/src/utils/migration/` | Migration engine |
|
||||
| `packages/noodl-editor/src/editor/src/utils/migration/migrations/` | Individual migrations |
|
||||
| `packages/noodl-editor/src/editor/src/views/MigrationDialog/` | UI for migration prompts |
|
||||
|
||||
### Key Files to Modify
|
||||
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `packages/noodl-editor/src/editor/src/models/projectmodel.js` | Add migration check on load |
|
||||
| Various node definitions | Document version requirements |
|
||||
| `package.json` (root) | Add noodl-cli workspace |
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Step 1: Project Format Research (Day 1)
|
||||
|
||||
1. Collect sample projects from different Noodl versions
|
||||
2. Document JSON schema for each file type
|
||||
3. Identify version indicators in existing projects
|
||||
4. Create comprehensive format documentation
|
||||
5. Document in NOTES.md
|
||||
|
||||
### Step 2: Breaking Changes Audit (Day 1-2)
|
||||
|
||||
1. List all dependency updates from TASK-001
|
||||
2. For each update, identify breaking changes
|
||||
3. Map breaking changes to project file impact
|
||||
4. Create migration requirement list
|
||||
5. Update README with findings
|
||||
|
||||
### Step 3: Version Detection System (Day 2)
|
||||
|
||||
1. Create `ProjectVersion` type definitions
|
||||
2. Implement version detection logic
|
||||
3. Add fallback for unknown/legacy projects
|
||||
4. Write unit tests for detection
|
||||
5. Document in CHANGELOG.md
|
||||
|
||||
### Step 4: Migration Engine Core (Day 3)
|
||||
|
||||
1. Design migration interface
|
||||
2. Implement `MigrationEngine` class
|
||||
3. Create migration registration system
|
||||
4. Build migration path calculator
|
||||
5. Add rollback capability
|
||||
6. Write unit tests
|
||||
|
||||
### Step 5: Individual Migrations (Day 3-4)
|
||||
|
||||
1. Create migration for React 17 → 19 patterns
|
||||
2. Create migration for node format changes
|
||||
3. Create migration for connection schema changes
|
||||
4. Create migration for each identified breaking change
|
||||
5. Write tests for each migration
|
||||
|
||||
### Step 6: CLI Tool (Day 4-5)
|
||||
|
||||
1. Create `noodl-cli` package structure
|
||||
2. Implement `validate` command
|
||||
3. Implement `upgrade` command
|
||||
4. Implement `batch-upgrade` command
|
||||
5. Implement `report` command
|
||||
6. Add backup functionality
|
||||
7. Write CLI tests
|
||||
8. Create user documentation
|
||||
|
||||
### Step 7: Editor Integration (Day 5-6)
|
||||
|
||||
1. Create MigrationDialog component
|
||||
2. Add migration check to project loading
|
||||
3. Implement automatic backup
|
||||
4. Add migration progress UI
|
||||
5. Handle edge cases and errors
|
||||
6. Manual testing
|
||||
|
||||
### Step 8: Validation & Testing (Day 6-7)
|
||||
|
||||
1. Create test project corpus (various versions)
|
||||
2. Run migration on all test projects
|
||||
3. Verify migrated projects work correctly
|
||||
4. Fix any discovered issues
|
||||
5. Document edge cases
|
||||
|
||||
## Testing Plan
|
||||
|
||||
### Unit Tests
|
||||
- [ ] Version detection correctly identifies project versions
|
||||
- [ ] Migration engine calculates correct migration paths
|
||||
- [ ] Each individual migration transforms data correctly
|
||||
- [ ] Backup system creates valid copies
|
||||
- [ ] Rollback restores original state
|
||||
|
||||
### Integration Tests
|
||||
- [ ] CLI tool works end-to-end
|
||||
- [ ] Editor integration opens legacy projects
|
||||
- [ ] Migration dialog flows work correctly
|
||||
- [ ] Batch migration handles multiple projects
|
||||
|
||||
### Manual Testing Scenarios
|
||||
- [ ] Open a project from Noodl 2.0
|
||||
- [ ] Open a project from Noodl 2.5
|
||||
- [ ] Open a project from the last official release
|
||||
- [ ] Open a project with complex node graphs
|
||||
- [ ] Open a project with custom components
|
||||
- [ ] Verify all nodes still work after migration
|
||||
- [ ] Verify all connections still work
|
||||
- [ ] Verify preview renders correctly
|
||||
- [ ] Test CLI on real legacy projects
|
||||
|
||||
### Test Project Corpus
|
||||
|
||||
Create or collect test projects representing:
|
||||
- [ ] Minimal project (single page)
|
||||
- [ ] Complex project (multiple pages, components)
|
||||
- [ ] Project using deprecated nodes
|
||||
- [ ] Project with custom JavaScript
|
||||
- [ ] Project with cloud functions
|
||||
- [ ] Project from each known Noodl version
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] Any legacy Noodl project can be opened in the new editor
|
||||
- [ ] Migration happens automatically without data loss
|
||||
- [ ] CLI tool successfully migrates 100% of test corpus
|
||||
- [ ] Users receive clear guidance if manual action needed
|
||||
- [ ] Original projects are backed up before modification
|
||||
- [ ] All migrated projects pass validation
|
||||
- [ ] No runtime errors in migrated projects
|
||||
- [ ] Documentation explains the migration process
|
||||
|
||||
## Risks & Mitigations
|
||||
|
||||
| Risk | Impact | Probability | Mitigation |
|
||||
|------|--------|-------------|------------|
|
||||
| Unknown project formats exist | High | Medium | Comprehensive testing, graceful fallbacks |
|
||||
| Some migrations are impossible | High | Low | Document limitations, provide manual guides |
|
||||
| Performance issues with large projects | Medium | Medium | Streaming migration, progress indicators |
|
||||
| Users don't understand prompts | Medium | Medium | Clear UX, detailed documentation |
|
||||
| Edge cases cause data corruption | Critical | Low | Always backup first, validation checks |
|
||||
| Can't find sample legacy projects | Medium | Medium | Reach out to community, create synthetic tests |
|
||||
|
||||
## Rollback Plan
|
||||
|
||||
If migration causes issues:
|
||||
|
||||
1. **User-level**: Restore from automatic backup
|
||||
2. **System-level**: Revert migration code, keep projects in legacy mode
|
||||
3. **Feature flag**: Add ability to disable auto-migration
|
||||
4. **Support path**: Document manual migration steps for edge cases
|
||||
|
||||
## Open Questions
|
||||
|
||||
1. Do we have access to legacy Noodl projects for testing?
|
||||
2. Is there documentation of past Noodl version changes?
|
||||
3. Should we support projects from unofficial Noodl forks?
|
||||
4. What's the oldest Noodl version we need to support?
|
||||
5. Should the CLI be a separate npm package or bundled?
|
||||
|
||||
## References
|
||||
|
||||
- TASK-001: Dependency Updates (lists breaking changes)
|
||||
- Noodl project file documentation (if exists)
|
||||
- React 19 migration guide
|
||||
- Community feedback on pain points
|
||||
|
||||
## Notes for Future Developers
|
||||
|
||||
This task is **foundational** for OpenNoodl's success. Take the time to:
|
||||
- Document everything you discover
|
||||
- Be conservative with assumptions
|
||||
- Test with real-world projects when possible
|
||||
- Err on the side of not breaking things
|
||||
|
||||
If you're ever unsure whether a change might break legacy projects, **don't make it** without adding a migration path first.
|
||||
Reference in New Issue
Block a user