| ← 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, orON(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:
- SpatialHierarchyBreadcrumb: Shows parent relationship chain only
- SpatialContentsView: Shows child objects (via parent relationships)
- SpatialPositionalView: Shows positioned objects (via positional relationships)
- 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
- Parent relationship limits: Object can have only one spatial parent
- Cycle prevention: Parent relationships cannot create cycles
- Positional relationship limits: Object can have multiple positional relationships but only one per axis
- Container scope validation: Positional relationships only allowed within same container
- Mandatory parent validation: Every object MUST have exactly one parent relationship
Movement Operation Validation
- Permission checks: User must have SPATIAL_MOVE permission for parent object
- Capacity validation: Target container must support the object type
- 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
Related Documentation
- Spatial Relationships System - Core spatial relationship definitions
- Relationship Decision Guide - When to use parent vs positional relationships
- Neo4j Core Schema - Database schema including spatial_predicates table
Migration Strategy
Phase 1: Schema Updates
- Add
creates_parent_relationshipfield to spatial_predicates table - Update existing predicate classifications
- Validate no existing data conflicts
Phase 2: GraphQL Resolver Updates
- Update spatial hierarchy queries to use parent relationships only
- Implement movement propagation logic
- Add validation for parent relationship operations
Phase 3: UI Component Updates
- Update spatial navigation components
- Implement parent vs positional relationship visualization
- Add movement operation feedback
Phase 4: Testing and Validation
- Test movement operations with various parent-child configurations
- Validate spatial hierarchy accuracy
- Performance test with large spatial hierarchies