← Back to Main Documentation Core Systems Index

Spatial Parent-Child Architecture

This document defines the architectural implications of spatial parent-child relationships in the Plings system, establishing clear rules for movement propagation, spatial hierarchy traversal, and UI behavior.

Overview

Spatial relationships in Plings are divided into two behavioral categories:

  • Parent-Child relationships: Create containment/support bonds where child objects follow parent when moved
  • Positional relationships: Describe relative positioning without creating dependency bonds

This distinction is crucial for implementing correct movement operations, spatial navigation, and UI interactions.

Core Architectural Principles

1. Mandatory Parent Relationship Rule

Every object MUST have exactly one parent relationship in the spatial hierarchy. This ensures:

  • Clear spatial hierarchy navigation
  • Unambiguous movement propagation
  • Consistent spatial context for object creation

Relationship Structure:

  • ONE parent relationship: IN, CONTAINS, or ON (mandatory)
  • Multiple positional relationships: LEFT_OF, RIGHT_OF, ABOVE, UNDER, NEXT_TO, ATTACHED_TO (optional, within same container)

2. Movement Propagation Rule

The Movement Test: “When I move this object, what else moves with it?”

  • Parent relationships (IN, CONTAINS, ON): Child objects follow parent when moved
  • Positional relationships (ABOVE, LEFT_OF, RIGHT_OF, UNDER, NEXT_TO): Objects remain independent

3. Spatial Hierarchy Traversal

The spatialHierarchy GraphQL field must only traverse parent relationships:

// Correct: Only parent relationships
(:Screw)-[:IN]->(:Toolbox)-[:ON]->(:Workbench)-[:IN]->(:Workshop)
// Result: [Screw, Toolbox, Workbench, Workshop]

// Incorrect: Don't traverse positional relationships
(:Shelf)-[:ABOVE]->(:Workbench) // Shelf is NOT part of Screw's hierarchy

4. UI Navigation Behavior

  • Select parent object: Show child objects as “contents” or “on surface”
  • Select positioned object: Show positional relationships as “nearby” or “adjacent”
  • Breadcrumb navigation: Only follows parent relationship chain

Implementation Requirements

Database Schema Enhancement

Proposed addition to spatial_predicates table:

ALTER TABLE spatial_predicates 
ADD COLUMN creates_parent_relationship boolean NOT NULL DEFAULT false;

-- Update existing predicates
UPDATE spatial_predicates SET creates_parent_relationship = true WHERE key IN ('IN', 'CONTAINS', 'ON');
UPDATE spatial_predicates SET creates_parent_relationship = false WHERE key IN ('ABOVE', 'UNDER', 'LEFT_OF', 'RIGHT_OF', 'NEXT_TO', 'ATTACHED_TO');

GraphQL Resolver Updates

Movement Operations:

def moveObject(objectId, newContainerId):
    # 1. Delete existing parent relationships
    delete_parent_relationships(objectId)
    
    # 2. Create new parent relationship
    create_parent_relationship(objectId, newContainerId)
    
    # 3. Update spatial hierarchy for moved object and all children
    update_spatial_hierarchy_cascade(objectId)
    
    # 4. Return updated spatial data
    return get_updated_spatial_data(objectId)

Spatial Hierarchy Queries:

// Updated to traverse only parent relationships
MATCH path = (:ObjectInstance {id: $objectId})-[:IN|ON|CONTAINS*0..]->(root:ObjectInstance)
WHERE NOT (root)-[:IN|ON]->()  // root has no spatial parent
RETURN [node IN nodes(path) | {
    id: node.id, 
    name: node.name, 
    type: COALESCE(node.class, 'GenericObject')
}] as hierarchy

UI Component Architecture

Spatial Navigation Components:

  1. SpatialHierarchyBreadcrumb: Shows parent relationship chain only
  2. SpatialContentsView: Shows child objects (via parent relationships)
  3. SpatialPositionalView: Shows positioned objects (via positional relationships)
  4. SpatialMoveOperation: Implements movement with proper child propagation

Component Behavior Rules:

  • Movement operations must respect parent-child relationships
  • Navigation must distinguish between contents and positioned objects
  • Drag-and-drop must validate parent relationship creation

Use Case Examples

Warehouse Management

// Parent relationships (movement propagation)
(:Box1)-[:ON]->(:Pallet)
(:Box2)-[:ON]->(:Pallet)
(:Pallet)-[:IN]->(:WarehouseZone)

// Positional relationships (no movement propagation)
(:Pallet2)-[:LEFT_OF]->(:Pallet)
(:Shelf)-[:ABOVE]->(:Pallet)

Operations:

  • Move Pallet: Box1, Box2 follow automatically
  • Move Pallet2: Pallet, Shelf remain stationary
  • Select Pallet: UI shows Box1, Box2 as contents
  • Select Pallet: UI shows Pallet2 as “to the left”, Shelf as “above”

Office Desk Setup

// Parent relationships
(:Monitor)-[:ON]->(:Desk)
(:Keyboard)-[:ON]->(:Desk)
(:Mouse)-[:ON]->(:Desk)

// Positional relationships
(:Keyboard)-[:LEFT_OF]->(:Monitor)
(:Mouse)-[:RIGHT_OF]->(:Monitor)

Operations:

  • Move Desk: Monitor, Keyboard, Mouse follow
  • Move Monitor: Keyboard, Mouse remain on desk (positional relationships intact)
  • Select Desk: Shows Monitor, Keyboard, Mouse as objects on surface
  • Navigation: Desk → Monitor/Keyboard/Mouse (parent relationships only)

Container Transition Rules

Parent Relationship Transitions

When an object moves from one container to another, the system must handle both parent and positional relationship changes:

Rule: Moving an object to a new container breaks ALL existing positional relationships and creates a new parent relationship.

Example: Box Movement Between Pallets

Initial State:

// Box A is on Pallet 1, positioned left of Box B
(:BoxA)-[:CURRENT_ON]->(:Pallet1)
(:BoxB)-[:CURRENT_ON]->(:Pallet1)
(:BoxA)-[:CURRENT_LEFT_OF]->(:BoxB)

Move Box A to Pallet 2:

// Step 1: Remove ALL old relationships for BoxA
DELETE (:BoxA)-[:CURRENT_ON]->(:Pallet1)
DELETE (:BoxA)-[:CURRENT_LEFT_OF]->(:BoxB)

// Step 2: Create new parent relationship
CREATE (:BoxA)-[:CURRENT_ON]->(:Pallet2)

// Result: BoxA now only relates to Pallet2, no longer positioned relative to BoxB

Positional Relationship Constraints

Container Scope Rule: Objects can only have positional relationships with other objects in the same container.

Examples:

// ✅ Valid: Both boxes on same pallet
(:BoxA)-[:CURRENT_ON]->(:Pallet1)
(:BoxB)-[:CURRENT_ON]->(:Pallet1)
(:BoxA)-[:CURRENT_LEFT_OF]->(:BoxB)  // Valid within same container

// ❌ Invalid: Boxes on different pallets
(:BoxA)-[:CURRENT_ON]->(:Pallet1)
(:BoxC)-[:CURRENT_ON]->(:Pallet2)
(:BoxA)-[:CURRENT_LEFT_OF]->(:BoxC)  // Invalid - different containers

Object Creation Default Location

Default Parent Assignment: New objects automatically receive a parent relationship to the currently selected container in the spatial navigator.

Creation Examples:

// User creating object while viewing Pallet1 contents
// Default relationship:
(:NewBox)-[:CURRENT_ON]->(:Pallet1)

// User creating object while viewing Room contents  
// Default relationship:
(:NewTable)-[:CURRENT_IN]->(:Room)

// User creating object while viewing Desk surface
// Default relationship:
(:NewLamp)-[:CURRENT_ON]->(:Desk)

Movement Operation Enhancements

Enhanced moveObject Operation:

def moveObject(objectId, newContainerId, relationshipType='ON'):
    # 1. Delete ALL existing spatial relationships for object
    delete_all_spatial_relationships(objectId)
    
    # 2. Create new parent relationship
    create_parent_relationship(objectId, newContainerId, relationshipType)
    
    # 3. Update spatial hierarchy cascade
    update_spatial_hierarchy_cascade(objectId)
    
    # 4. Clean up orphaned positional relationships
    cleanup_orphaned_positional_relationships()
    
    return get_updated_spatial_data(objectId)

def delete_all_spatial_relationships(objectId):
    # Remove parent relationships
    DELETE (:ObjectInstance {id: objectId})-[:CURRENT_IN|CURRENT_ON]->()
    
    # Remove positional relationships (both directions)
    DELETE (:ObjectInstance {id: objectId})-[:CURRENT_LEFT_OF|CURRENT_RIGHT_OF|CURRENT_ABOVE|CURRENT_UNDER|CURRENT_NEXT_TO|CURRENT_ATTACHED_TO]-()
    DELETE ()-[:CURRENT_LEFT_OF|CURRENT_RIGHT_OF|CURRENT_ABOVE|CURRENT_UNDER|CURRENT_NEXT_TO|CURRENT_ATTACHED_TO]->(:ObjectInstance {id: objectId})

Validation Rules

Relationship Creation Validation

  1. Parent relationship limits: Object can have only one spatial parent
  2. Cycle prevention: Parent relationships cannot create cycles
  3. Positional relationship limits: Object can have multiple positional relationships but only one per axis
  4. Container scope validation: Positional relationships only allowed within same container
  5. Mandatory parent validation: Every object MUST have exactly one parent relationship

Movement Operation Validation

  1. Permission checks: User must have SPATIAL_MOVE permission for parent object
  2. Capacity validation: Target container must support the object type
  3. Cascade validation: All child objects must also be moveable

Error Handling

Movement Failures

  • Parent relationship conflicts: Clear error message about existing parent
  • Permission denied: Specific error about which object lacks permission
  • Cascade failures: Detailed error about which child object failed to move

UI Error States

  • Invalid drop targets: Visual feedback for invalid parent relationship targets
  • Movement in progress: Loading states for cascade operations
  • Partial failures: Clear indication of which objects moved successfully

Performance Considerations

Query Optimization

  • Spatial hierarchy queries: Index on parent relationship types
  • Movement operations: Batch updates for cascade operations
  • UI loading: Paginate spatial children for large containers

Cache Strategy

  • Spatial hierarchy: Cache parent chains for frequently accessed objects
  • Movement operations: Invalidate cache for affected spatial hierarchies
  • UI components: Cache positional relationship data

Migration Strategy

Phase 1: Schema Updates

  1. Add creates_parent_relationship field to spatial_predicates table
  2. Update existing predicate classifications
  3. Validate no existing data conflicts

Phase 2: GraphQL Resolver Updates

  1. Update spatial hierarchy queries to use parent relationships only
  2. Implement movement propagation logic
  3. Add validation for parent relationship operations

Phase 3: UI Component Updates

  1. Update spatial navigation components
  2. Implement parent vs positional relationship visualization
  3. Add movement operation feedback

Phase 4: Testing and Validation

  1. Test movement operations with various parent-child configurations
  2. Validate spatial hierarchy accuracy
  3. Performance test with large spatial hierarchies