# Migration System Documentation

The migration system has been refactored to be modular and organized, making it easy to add new table migrations.

## Structure

```
app/Console/Commands/
├── MigrateOldDatabaseCommand.php      # Main command entry point
└── Migrations/
    ├── BaseMigration.php              # Base class with common functionality
    ├── MigrationManager.php           # Manages and orchestrates all migrations
    ├── RolesMigration.php             # Creates predefined roles
    ├── StateMigration.php             # Handles state data migration  
    ├── CityMigration.php              # Handles city data migration
    ├── CenterMigration.php            # Handles center data migration
    ├── AssociationMigration.php       # Handles association data migration
    └── UserMigration.php              # Handles user data migration
```

## Available Migrations

### 1. Roles Migration (`RolesMigration`)
- **Purpose**: Creates predefined user roles using Spatie Laravel Permission
- **Dependencies**: None
- **Data Source**: Predefined array (not from old database)
- **Key Features**: Creates 9 system roles, checks for existing roles

### 2. State Migration (`StateMigration`)
- **Purpose**: Migrates geographical states with translations
- **Dependencies**: None  
- **Data Source**: `sek_states` table
- **Key Features**: Preserves original IDs, maps Arabic/English names with Spatie Translatable

### 3. City Migration (`CityMigration`)
- **Purpose**: Migrates cities with state relationships and translations
- **Dependencies**: States must be migrated first
- **Data Source**: `sek_cities` table
- **Key Features**: Links to states via `state_id`, validates relationships

### 4. Center Migration (`CenterMigration`) 
- **Purpose**: Migrates centers with city relationships and family counts
- **Dependencies**: Cities must be migrated first
- **Data Source**: `sek_centers` table  
- **Key Features**: Links to cities, maps `number_of_families` to `families_count`

### 5. Association Migration (`AssociationMigration`)
- **Purpose**: Migrates association data with complex multi-table joins
- **Dependencies**: None (but benefits from location data being present)
- **Data Source**: Multiple joined tables from old database
- **Key Features**: Complex JOIN queries, default value handling, coordinate parsing

### 6. User Migration (`UserMigration`)
- **Purpose**: Migrates user accounts with role assignments
- **Dependencies**: Roles and Associations must exist
- **Data Source**: `sek_users` table
- **Key Features**: Email generation, password hashing, role assignment

## Migration Order & Dependencies

The migrations must be run in dependency order:
1. **Roles** → No dependencies
2. **States** → No dependencies  
3. **Cities** → Requires States
4. **Centers** → Requires Cities
5. **Associations** → No hard dependencies (but should run after locations)
6. **Users** → Requires Roles and Associations

## Command Usage

### Individual Migrations
```bash
php artisan migrate:old-database --roles-only
php artisan migrate:old-database --states-only  
php artisan migrate:old-database --cities-only
php artisan migrate:old-database --centers-only
php artisan migrate:old-database --associations-only
php artisan migrate:old-database --users-only
```

### Migration Groups
```bash
# Migrate all location data (states, cities, centers)
php artisan migrate:old-database --locations

# Migrate basic foundational data (roles, states, cities, centers)  
php artisan migrate:old-database --basic

# Migrate complex entities (associations, users) - requires basic data first
php artisan migrate:old-database --full

# Migrate everything in correct order
php artisan migrate:old-database
```

### Common Options
```bash
# Dry run mode (test without inserting data)
php artisan migrate:old-database --dry-run

# Custom batch size for memory management
php artisan migrate:old-database --batch-size=50

# Start from specific record (useful for resuming)
php artisan migrate:old-database --start-from=100

# Use different database connection
php artisan migrate:old-database --connection=legacy_db
```

## How to Add a New Migration

### 1. Create Migration Class

Create a new file in `app/Console/Commands/Migrations/` (e.g., `ProductMigration.php`):

```php
<?php

namespace App\Console\Commands\Migrations;

use App\Models\Product;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class ProductMigration extends BaseMigration
{
    public function migrate(bool $dryRun, int $batchSize, int $startFrom): void
    {
        $this->info('📦 Starting products migration...');

        $oldDb = DB::connection($this->connection);
        $totalCount = $oldDb->table('sek_products')->count();
        $this->stats['total'] = $totalCount;

        // ... implement migration logic similar to AssociationMigration
    }

    protected function getModelName(): string
    {
        return 'Product';
    }

    protected function getModelClass(): string
    {
        return Product::class;
    }

    protected function mapData(object $oldProduct): array
    {
        // Map old product data to new schema
        return [
            'id' => $oldProduct->id,
            'name' => $oldProduct->name,
            // ... other field mappings
        ];
    }

    protected function validateData(array $data): bool
    {
        $validator = Validator::make($data, [
            'id' => 'required|integer|min:1',
            'name' => 'required|string|max:255',
            // ... validation rules
        ]);

        if ($validator->fails()) {
            $this->error('Product validation errors: ' . implode(', ', $validator->errors()->all()));
            return false;
        }

        return true;
    }
}
```

### 2. Register Migration

Update `MigrateOldDatabaseCommand.php` in the `registerMigrations()` method:

```php
protected function registerMigrations(): void
{
    $connection = $this->option('connection');

    // Register migrations in dependency order
    $this->migrationManager->register('associations', new AssociationMigration($this, $connection));
    $this->migrationManager->register('users', new UserMigration($this, $connection));
    $this->migrationManager->register('products', new ProductMigration($this, $connection)); // Add new migration
}
```

### 3. Add Command Options (Optional)

Add specific options for your migration in the command signature:

```php
protected $signature = 'migrate:old-database 
                       {--connection=old_database : Old database connection name}
                       {--dry-run : Run migration without actually inserting data}
                       {--batch-size=100 : Number of records to process in each batch}
                       {--start-from=0 : Start migration from specific record number}
                       {--associations-only : Migrate only associations}
                       {--users-only : Migrate only users}
                       {--products-only : Migrate only products}';
```

Then update the handle method logic:

```php
if ($this->option('products-only')) {
    $this->migrationManager->runMigration('products', $dryRun, $batchSize, $startFrom);
}
```

## Base Migration Features

The `BaseMigration` class provides:

- **Statistics tracking**: Automatic tracking of total, migrated, skipped, and error counts
- **Date/Time parsing**: `parseDateTime()` and `parseDate()` methods
- **Coordinate parsing**: `parseCoordinates()` method for geographic data
- **Model creation**: `createModel()` with unguarded mass assignment
- **Record existence checking**: `recordExists()` method
- **Logging methods**: `info()`, `warn()`, `error()` methods

## Migration Manager Features

The `MigrationManager` class provides:

- **Migration registration**: Register multiple migrations
- **Selective execution**: Run specific migrations or all migrations
- **Results display**: Unified results display for all migrations
- **Error handling**: Graceful error handling with rollback support

## Usage Examples

```bash
# Run all migrations
php artisan migrate:old-database --dry-run

# Run only associations
php artisan migrate:old-database --associations-only

# Run with custom batch size
php artisan migrate:old-database --batch-size=50

# Run specific migration (if implemented)
php artisan migrate:old-database --products-only
```

## Benefits

1. **Modularity**: Each model has its own migration class
2. **Reusability**: Common functionality in base class
3. **Maintainability**: Easy to modify individual migrations
4. **Scalability**: Simple to add new migrations
5. **Testability**: Each migration can be tested independently
6. **Organization**: Clear separation of concerns
