@@ -754,6 +754,12 @@ const useGraphStore = create(saveCoordinatorMiddleware((set, get, api) => {
754754 }
755755 } ) ;
756756
757+ // Validate: don't create empty definition graphs
758+ if ( memberInstances . length === 0 ) {
759+ console . warn ( `[convertGroupToNodeGroup] Group ${ groupId } has no valid members. Aborting conversion to prevent empty definition.` ) ;
760+ return ;
761+ }
762+
757763 memberInstances . forEach ( ( { instId, instance } ) => {
758764 const newInstId = uuidv4 ( ) ;
759765 instanceIdMap . set ( instId , newInstId ) ;
@@ -1448,6 +1454,16 @@ const useGraphStore = create(saveCoordinatorMiddleware((set, get, api) => {
14481454 // Delete the instance
14491455 graph . instances . delete ( instanceId ) ;
14501456
1457+ // Clean up group membership - remove this instance from any groups it belongs to
1458+ if ( graph . groups ) {
1459+ for ( const [ groupId , group ] of graph . groups . entries ( ) ) {
1460+ if ( group . memberInstanceIds ?. includes ( instanceId ) ) {
1461+ group . memberInstanceIds = group . memberInstanceIds . filter ( id => id !== instanceId ) ;
1462+ console . log ( `[removeNodeInstance] Removed instance ${ instanceId } from group ${ groupId } ` ) ;
1463+ }
1464+ }
1465+ }
1466+
14511467 // Ensure any soft-deletion bookkeeping is cleared
14521468 draft . pendingDeletions . delete ( instanceId ) ;
14531469
@@ -1495,6 +1511,19 @@ const useGraphStore = create(saveCoordinatorMiddleware((set, get, api) => {
14951511 draft . pendingDeletions . delete ( instanceId ) ;
14961512 } ) ;
14971513
1514+ // Clean up group membership for all deleted instances
1515+ if ( graph . groups ) {
1516+ for ( const [ groupId , group ] of graph . groups . entries ( ) ) {
1517+ if ( group . memberInstanceIds ) {
1518+ const originalLength = group . memberInstanceIds . length ;
1519+ group . memberInstanceIds = group . memberInstanceIds . filter ( id => ! instanceIdSet . has ( id ) ) ;
1520+ if ( group . memberInstanceIds . length !== originalLength ) {
1521+ console . log ( `[removeMultipleNodeInstances] Cleaned up ${ originalLength - group . memberInstanceIds . length } stale members from group ${ groupId } ` ) ;
1522+ }
1523+ }
1524+ }
1525+ }
1526+
14981527 console . log ( `[removeMultipleNodeInstances] Deleted ${ instanceIdSet . size } instances and ${ edgesToDelete . length } edges` ) ;
14991528 } ) ) ;
15001529 } ,
@@ -2269,6 +2298,46 @@ const useGraphStore = create(saveCoordinatorMiddleware((set, get, api) => {
22692298 console . log ( `[Store createGraphWithId] Created and activated graph ${ graphId } ('${ name } ')` ) ;
22702299 } ) ) ,
22712300
2301+ // Repair tool to re-sync bidirectional links between graphs and their defining nodes
2302+ repairGraphLinkages : ( ) => {
2303+ console . log ( '[Repair Tool] Starting bidirectional link repair...' ) ;
2304+ set ( produce ( ( draft ) => {
2305+ let repairCount = 0 ;
2306+
2307+ // Iterate all graphs
2308+ for ( const [ graphId , graph ] of draft . graphs . entries ( ) ) {
2309+ // Check if graph defines any nodes
2310+ const definingNodeIds = graph . definingNodeIds || [ ] ;
2311+
2312+ definingNodeIds . forEach ( prototypeId => {
2313+ const prototype = draft . nodePrototypes . get ( prototypeId ) ;
2314+ if ( ! prototype ) {
2315+ console . warn ( `[Repair Tool] Graph "${ graph . name } " (${ graphId } ) defines missing prototype ${ prototypeId } ` ) ;
2316+ return ;
2317+ }
2318+
2319+ // Ensure prototype links back to this graph
2320+ if ( ! Array . isArray ( prototype . definitionGraphIds ) ) {
2321+ prototype . definitionGraphIds = [ ] ;
2322+ }
2323+
2324+ if ( ! prototype . definitionGraphIds . includes ( graphId ) ) {
2325+ prototype . definitionGraphIds . push ( graphId ) ;
2326+ console . log ( `[Repair Tool] 🛠️ FIXED: Linked Node "${ prototype . name } " back to definition Graph "${ graph . name } "` ) ;
2327+ repairCount ++ ;
2328+ }
2329+ } ) ;
2330+ }
2331+
2332+ if ( repairCount > 0 ) {
2333+ console . log ( `[Repair Tool] ✅ Completed with ${ repairCount } repairs.` ) ;
2334+ // Force a store update trigger if needed, though Immer should handle it
2335+ } else {
2336+ console . log ( '[Repair Tool] No broken links found.' ) ;
2337+ }
2338+ } ) ) ;
2339+ } ,
2340+
22722341 // Creates a new graph, assigns it as a definition to a prototype, and makes it active
22732342 createAndAssignGraphDefinition : ( prototypeId ) => {
22742343 let newGraphId = null ;
0 commit comments