editor: gate Load Build behind a verification dialog
Loading JSON previously called setScene blindly and crashed when the file held schema-invalid nodes (e.g. items missing `asset`). The new dialog parses the file, runs validateBuildJson in core, and surfaces structure counts (site/building/levels/walls/doors/ windows/items/slabs/ceilings/zones/scans), floor area, and a per-node Schema Details list grouped by type. Import is blocked when any hard error exists. Two schema bugs the validator surfaced are fixed here too: - SiteNode.children is now an id array like every other node (was a discriminatedUnion of full objects; three readers carried a string-or-object ternary that's now dropped). migrateNodes flattens legacy nested-object children on load. Default-scene seed and photo-to-scene MCP builder updated to pass `building.id`. - LevelNode.children now includes shelf — the editor allowed it but the schema didn't. The schema-vs-registry-as-source-of-truth discussion is captured in plans/editor-node-registry.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
42bf025cad
commit
ffc497c67a
@@ -8,6 +8,7 @@ import { GuideNode } from './guide'
|
||||
import { ItemNode } from './item'
|
||||
import { RoofNode } from './roof'
|
||||
import { ScanNode } from './scan'
|
||||
import { ShelfNode } from './shelf'
|
||||
import { SlabNode } from './slab'
|
||||
import { SpawnNode } from './spawn'
|
||||
import { StairNode } from './stair'
|
||||
@@ -32,6 +33,7 @@ export const LevelNode = BaseNode.extend({
|
||||
ScanNode.shape.id,
|
||||
GuideNode.shape.id,
|
||||
SpawnNode.shape.id,
|
||||
ShelfNode.shape.id,
|
||||
]),
|
||||
)
|
||||
.default([]),
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
import dedent from 'dedent'
|
||||
import { z } from 'zod'
|
||||
import { BaseNode, nodeType, objectId } from '../base'
|
||||
import { BuildingNode } from './building'
|
||||
import { ItemNode } from './item'
|
||||
|
||||
// 2D Polygon
|
||||
const PropertyLineData = z.object({
|
||||
@@ -33,14 +31,12 @@ export const SiteNode = BaseNode.extend({
|
||||
],
|
||||
}),
|
||||
// terrain: TerrainData,
|
||||
children: z
|
||||
.array(z.discriminatedUnion('type', [BuildingNode, ItemNode]))
|
||||
.default([BuildingNode.parse({})]),
|
||||
children: z.array(z.string()).default([]),
|
||||
}).describe(
|
||||
dedent`
|
||||
Site node - used to represent a site
|
||||
- polygon: polygon data
|
||||
- children: array of building and item nodes
|
||||
- children: array of child node ids (buildings, items)
|
||||
`,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user