Files
thrillwiki_laravel/memory-bank/features/AreaOrganization.md

5.0 KiB

Area Organization System

Overview

The Area Organization system provides a flexible way to structure and order areas within a park. It supports both flat and nested hierarchies, with drag-and-drop reordering capabilities and efficient position management.

Database Structure

Park Areas Table

CREATE TABLE park_areas (
    id bigint unsigned NOT NULL AUTO_INCREMENT,
    park_id bigint unsigned NOT NULL,
    parent_id bigint unsigned NULL,
    name varchar(255) NOT NULL,
    slug varchar(255) NOT NULL,
    description text NULL,
    opening_date date NULL,
    closing_date date NULL,
    position integer NOT NULL DEFAULT 0,
    created_at timestamp NULL,
    updated_at timestamp NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (park_id) REFERENCES parks(id),
    FOREIGN KEY (parent_id) REFERENCES park_areas(id),
    INDEX idx_ordering (park_id, position),
    INDEX idx_hierarchy (park_id, parent_id)
);

Key Features

1. Position Management

  • Automatic position assignment for new areas
  • Zero-based position indexing
  • Position maintenance during reordering
  • Efficient batch updates for position changes

2. Hierarchical Structure

  • Parent-child relationships between areas
  • Unlimited nesting depth
  • Separate position sequences per parent
  • Cascading deletion options

3. Query Optimization

  • Compound indexes for efficient ordering
  • Optimized parent-child lookups
  • Position-based sorting
  • Scoped uniqueness constraints

Implementation Details

Position Management

  1. New Area Creation

    protected static function boot()
    {
        parent::boot();
        static::creating(function (ParkArea $area) {
            if (is_null($area->position)) {
                $area->position = $area->getNextPosition();
            }
        });
    }
    
  2. Position Calculation

    public function getNextPosition(): int
    {
        $maxPosition = static::where('park_id', $this->park_id)
            ->where('parent_id', $this->parent_id)
            ->max('position');
    
        return ($maxPosition ?? -1) + 1;
    }
    
  3. Position Updates

    public function moveToPosition(int $newPosition): void
    {
        if ($newPosition === $this->position) {
            return;
        }
    
        $oldPosition = $this->position;
    
        if ($newPosition > $oldPosition) {
            // Moving down: decrement positions of items in between
            static::where('park_id', $this->park_id)
                ->where('parent_id', $this->parent_id)
                ->whereBetween('position', [$oldPosition + 1, $newPosition])
                ->decrement('position');
        } else {
            // Moving up: increment positions of items in between
            static::where('park_id', $this->park_id)
                ->where('parent_id', $this->parent_id)
                ->whereBetween('position', [$newPosition, $oldPosition - 1])
                ->increment('position');
        }
    
        $this->update(['position' => $newPosition]);
    }
    

Hierarchical Relationships

  1. Parent Relationship

    public function parent(): BelongsTo
    {
        return $this->belongsTo(ParkArea::class, 'parent_id');
    }
    
  2. Children Relationship

    public function children(): HasMany
    {
        return $this->hasMany(ParkArea::class, 'parent_id')
            ->orderBy('position');
    }
    
  3. Helper Methods

    public function hasChildren(): bool
    {
        return $this->children()->exists();
    }
    
    public function isTopLevel(): bool
    {
        return is_null($this->parent_id);
    }
    

Usage Examples

Creating a New Area

$area = new ParkArea([
    'name' => 'Adventure Zone',
    'description' => 'Thrilling rides area',
]);
$park->areas()->save($area);

Moving an Area

$area->moveToPosition(5);

Adding a Sub-Area

$subArea = new ParkArea([
    'name' => 'Coaster Corner',
    'parent_id' => $area->id,
]);
$park->areas()->save($subArea);

Future Enhancements

  1. Add drag-and-drop reordering UI
  2. Implement position validation
  3. Add move restrictions
  4. Implement area statistics
  5. Add bulk reordering
  6. Implement depth limits
  7. Add position caching
  8. Implement move history

Security Considerations

  1. Position Validation

    • Prevent out-of-bounds positions
    • Validate parent-child relationships
    • Check for circular references
  2. Access Control

    • Restrict reordering permissions
    • Validate park ownership
    • Log position changes

Performance Optimization

  1. Batch Updates

    • Use transactions for moves
    • Minimize position updates
    • Cache position values
  2. Query Optimization

    • Use compound indexes
    • Minimize nested queries
    • Efficient position calculations

Testing Strategy

  1. Unit Tests

    • Position calculation
    • Move operations
    • Parent-child relationships
  2. Integration Tests

    • Reordering flows
    • Nested operations
    • Position maintenance
  3. Performance Tests

    • Large-scale reordering
    • Nested structure queries
    • Position update efficiency