mirror of
https://github.com/pacnpal/thrillwiki_laravel.git
synced 2025-12-20 11:11:12 -05:00
208 lines
5.0 KiB
Markdown
208 lines
5.0 KiB
Markdown
# 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 |