# 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 ```sql 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 ```php protected static function boot() { parent::boot(); static::creating(function (ParkArea $area) { if (is_null($area->position)) { $area->position = $area->getNextPosition(); } }); } ``` 2. Position Calculation ```php 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 ```php 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 ```php public function parent(): BelongsTo { return $this->belongsTo(ParkArea::class, 'parent_id'); } ``` 2. Children Relationship ```php public function children(): HasMany { return $this->hasMany(ParkArea::class, 'parent_id') ->orderBy('position'); } ``` 3. Helper Methods ```php public function hasChildren(): bool { return $this->children()->exists(); } public function isTopLevel(): bool { return is_null($this->parent_id); } ``` ## Usage Examples ### Creating a New Area ```php $area = new ParkArea([ 'name' => 'Adventure Zone', 'description' => 'Thrilling rides area', ]); $park->areas()->save($area); ``` ### Moving an Area ```php $area->moveToPosition(5); ``` ### Adding a Sub-Area ```php $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