Files
OpenNoodl/dev-docs/tasks/phase-10-ai-powered-development/PROGRESS-dishant.md
dishant-kumar-thakur d54e2a55a0 feat(phase-10): STRUCT-003 import engine core
Task: STRUCT-003
Branch: cline-dev-dishant
Cross-branch notes: none -- no shared dependencies with Richard phase 9/6 work

- ProjectImporter class (pure, filesystem-agnostic)
- Converts v2 multi-file format back to legacy project.json
- unflattenNodes: reconstructs recursive tree from flat NodeV2 array (two-pass)
- toLegacyName: uses preserved component.path for perfect round-trip fidelity
- Metadata merge: routes/styles merged back into project.metadata
- stateParameters -> stateParamaters reversal (legacy typo preserved)
- Non-fatal warnings: component failures collected, not thrown
- 55 unit tests in tests/io/ProjectImporter.test.ts
  - unflattenNodes: 11 cases
  - toLegacyName: 4 cases
  - ProjectImporter.import(): 20 cases
  - Round-trip (export -> import): 20 cases
- Updated tests/io/index.ts to export importer tests
- Updated PROGRESS-dishant.md: STRUCT-001/002/003 all marked complete
2026-02-19 01:07:22 +05:30

6.9 KiB

Phase 10A AI-Powered Development: Dishant Progress

Developer: Dishant Branch: cline-dev-dishant Last Updated: 2026-02-19


Task Status

Task ID Title Status Notes
STRUCT-001 JSON Schema Definition COMPLETE 8 schemas + validator + tests (33/33 pass)
STRUCT-002 Export Engine Core COMPLETE ProjectExporter + 50 unit tests
STRUCT-003 Import Engine Core COMPLETE ProjectImporter + 55 unit tests incl. round-trip validation
STRUCT-004 Editor Format Detection TODO Unblocked by STRUCT-003
STRUCT-005 Lazy Loading TODO Unblocked by STRUCT-004
STRUCT-006 Save Logic TODO Unblocked by STRUCT-005
STRUCT-007 Migration Wizard UI TODO Unblocked by STRUCT-006
STRUCT-008 Testing and Validation TODO Unblocked by STRUCT-007
STRUCT-009 Documentation TODO Unblocked by STRUCT-008

STRUCT-001 JSON Schema Definition COMPLETE

Completed: 2026-02-18

What was built

All files under packages/noodl-editor/src/editor/src/schemas/:

File Schema ID Describes
project-v2.schema.json https://opennoodl.dev/schemas/project-v2.json Root project metadata
component.schema.json https://opennoodl.dev/schemas/component-v2.json Component metadata
nodes.schema.json https://opennoodl.dev/schemas/nodes-v2.json Node graph definitions
connections.schema.json https://opennoodl.dev/schemas/connections-v2.json Connection/wire definitions
registry.schema.json https://opennoodl.dev/schemas/registry-v2.json Component index
routes.schema.json https://opennoodl.dev/schemas/routes-v2.json URL route definitions
styles.schema.json https://opennoodl.dev/schemas/styles-v2.json Global styles + variants
model.schema.json https://opennoodl.dev/schemas/model-v2.json Backend data model definitions
  • validator.ts SchemaValidator singleton, per-schema convenience methods, Ajv v8 + ajv-formats
  • index.ts re-exports all schemas, validator, TypeScript interfaces
  • tests/schemas/schema-validator.test.ts 33 test cases, all passing

Key decisions

  • additionalProperties: true on nodes/connections open-ended by design
  • Port type is oneOf [string, object] Noodl uses both formats
  • strict: false on Ajv schemas use description in definitions
  • require() for ajv-formats avoids TS type conflict

STRUCT-002 Export Engine Core COMPLETE

Completed: 2026-02-19

What was built

File Purpose
packages/noodl-editor/src/editor/src/io/ProjectExporter.ts Core exporter class + legacy types + helpers
packages/noodl-editor/tests/io/ProjectExporter.test.ts 50 unit tests
packages/noodl-editor/tests/io/index.ts Test barrel export

Architecture

ProjectExporter is pure no filesystem access. Takes LegacyProject, returns ExportResult { files[], stats }.

Output layout:

nodegx.project.json
nodegx.routes.json        (conditional)
nodegx.styles.json        (conditional)
components/
  _registry.json
  Header/
    component.json
    nodes.json
    connections.json

Key decisions

  1. Pure/filesystem-agnostic caller writes files
  2. Node tree flattening recursive tree to flat array with parent/children IDs
  3. Styles/routes files conditional only produced when content exists
  4. Legacy stateParamaters typo normalised to stateParameters
  5. Metadata split styles/routes extracted, rest stays in project file
  6. Original legacy path preserved in component.json for round-trip fidelity
  7. Empty parameters: {} omitted from output

STRUCT-003 Import Engine Core COMPLETE

Completed: 2026-02-19

What was built

File Purpose
packages/noodl-editor/src/editor/src/io/ProjectImporter.ts Core importer class + helpers
packages/noodl-editor/tests/io/ProjectImporter.test.ts 55 unit tests incl. round-trip

Architecture

ProjectImporter is pure no filesystem access. Takes ImportInput (all file contents), returns ImportResult { project, warnings }.

ImportInput {
  project: ProjectV2File        (nodegx.project.json)
  registry: RegistryV2File      (components/_registry.json)
  routes?: RoutesV2File         (nodegx.routes.json)
  styles?: StylesV2File         (nodegx.styles.json)
  components: Record<path, { component, nodes, connections }>
}

Key functions exported

Function Purpose
unflattenNodes(flat) Reconstructs recursive legacy node tree from flat NodeV2 array
toLegacyName(componentFile, registryPath) Converts v2 path back to legacy name (uses preserved path field)

Key decisions

  1. Pure/filesystem-agnostic symmetric with ProjectExporter
  2. unflattenNodes two-pass: build map, then wire children in order
  3. toLegacyName prefers component.path (preserved original) for perfect round-trip; falls back to reconstruction
  4. stateParameters stateParamaters reversal restores legacy typo
  5. Metadata merge routes/styles merged back into project.metadata
  6. Non-fatal warnings component failures collected, not thrown
  7. Round-trip validated 20 round-trip tests covering all data types

Test coverage (55 tests)

  • unflattenNodes 11 cases (empty, single, parent-child, deep nesting, order, field restoration)
  • toLegacyName 4 cases (path field, fallback, root, cloud)
  • ProjectImporter.import() 20 cases (basic, metadata, variants, components, nodes)
  • Round-trip (export import) 20 cases (all data types, edge cases)

Cross-branch note for Richard

No shared dependencies with Phase 9/6 work. STRUCT-003 is self-contained in packages/noodl-editor/src/editor/src/io/ and packages/noodl-editor/tests/io/. No cherry-pick needed.


Decisions and Learnings

  • [2026-02-18] Ajv v8 + ajv-formats: use require() for ajv-formats to avoid TS type conflict with root-level ajv-formats package
  • [2026-02-19] Legacy stateParamaters typo (missing 'e') is real must be preserved in round-trip. Exporter normalises to stateParameters, importer reverses it.
  • [2026-02-19] component.path field is the key to perfect round-trip fidelity always preserve the original legacy name in the v2 component file
  • [2026-02-19] unflattenNodes needs two passes first build the node map, then wire children in order using the children ID array