# Mejores Prácticas: Optimización de Seeders por Módulos Activos

## 📋 Problema Identificado

Anteriormente, todos los seeders se ejecutaban independientemente de si el módulo estaba activo o no. Esto causaba:

- ⏱️ **Tiempo de ejecución innecesario**: Seeders ejecutándose para módulos no utilizados
- 💾 **Consumo de recursos**: Procesamiento y almacenamiento de datos innecesarios
- 📦 **Espacio en BD**: Datos de módulos inactivos ocupando espacio
- 🔄 **Mantenimiento complejo**: JSONs con datos de otros proyectos mezclados

## ✅ Solución Implementada

### 1. Verificación de Módulos Activos

El `Project_Seeder` ahora verifica qué módulos están activos antes de ejecutar sus seeders correspondientes.

```php
// Solo ejecuta seeders de módulos activos
$activeModules = $this->getActiveModules();

foreach (self::MODULE_SEEDERS_MAP as $moduleName => $seeders) {
    if (isset($activeModules[$moduleName]) && $activeModules[$moduleName]) {
        $this->call($seeders);
    } else {
        // Omitir seeders de módulos inactivos
    }
}
```

### 2. Mapeo de Módulos a Seeders

Se creó un mapeo claro que relaciona cada módulo con sus seeders:

```php
private const MODULE_SEEDERS_MAP = [
    'services' => [
        ServiceCategoriesSeeder::class,
        ProjectsServicesSeeder::class,
    ],
    'blog' => [
        BlogSeeder::class,
    ],
    // ... otros módulos
];
```

### 3. Seeders Base Siempre Activos

Algunos seeders se ejecutan siempre porque contienen contenido base necesario:

- `CdSystemSeeder` - Configuración del sistema (demo, módulos)
- `SiteDataSeeder` - Datos del proyecto (contacto, SEO)
- `AssetsSeeder` - Assets del proyecto
- `AnalyticsSeeder` - Google Analytics
- `ProjectsUsersSeeder` - Usuarios del proyecto
- `CdBaseSeeder` - Contenido base general

## 🎯 Beneficios

### Optimización de Recursos
- ✅ Solo se ejecutan seeders necesarios
- ✅ Reducción del tiempo de ejecución
- ✅ Menor consumo de memoria y espacio en BD

### Mantenibilidad
- ✅ Código más claro y organizado
- ✅ Fácil agregar nuevos módulos al mapeo
- ✅ Documentación explícita de qué seeders corresponden a qué módulos

### Escalabilidad
- ✅ Fácil agregar nuevos módulos sin afectar los existentes
- ✅ Cada módulo es independiente
- ✅ Configuración centralizada en `cd-system.json`

## 📝 Cómo Agregar un Nuevo Módulo

### Paso 1: Agregar al Mapeo

En `Project_Seeder.php`, agregar el nuevo módulo al mapeo:

```php
private const MODULE_SEEDERS_MAP = [
    // ... módulos existentes
    'nuevo-modulo' => [
        NuevoModuloSeeder::class,
        NuevoModuloCategoriasSeeder::class,
    ],
];
```

### Paso 2: Configurar en cd-system.json

Asegurarse de que el módulo esté configurado en `database/seeders/project-data/cd-system.json`:

```json
{
  "modules": {
    "nuevo-modulo": {
      "active": true,
      "navigation": {
        "header": true,
        "footer": true
      }
    }
  }
}
```

### Paso 3: Crear el Seeder

Crear el seeder correspondiente que verifique si debe ejecutarse:

```php
class NuevoModuloSeeder extends Seeder
{
    public function run()
    {
        // El seeder solo se ejecutará si el módulo está activo
        // (gracias a la verificación en Project_Seeder)
        
        $path = database_path('seeders/project-data/nuevo-modulo.json');
        // ... lógica del seeder
    }
}
```

## 🔍 Verificación de Módulos Activos

### Función Helper

Ya existe una función helper para verificar módulos activos:

```php
if (is_module_active('blog')) {
    // El módulo blog está activo
}
```

### En Seeders Individuales

Si un seeder necesita verificar si debe ejecutarse:

```php
use function is_module_active;

class BlogSeeder extends Seeder
{
    public function run()
    {
        // Verificación adicional (aunque Project_Seeder ya lo hace)
        if (!is_module_active('blog')) {
            $this->command->warn('⚠️  Módulo blog inactivo - omitiendo seeder');
            return;
        }
        
        // ... lógica del seeder
    }
}
```

## ⚠️ Consideraciones Importantes

### 1. Orden de Ejecución

El orden de ejecución es crítico:

1. **CdSystemSeeder** - Debe ejecutarse PRIMERO (otros seeders dependen de él)
2. **SiteDataSeeder** - Configuración del proyecto
3. **AssetsSeeder** - Assets del proyecto
4. **AnalyticsSeeder** - Google Analytics
5. **ProjectsUsersSeeder** - Usuarios
6. **Seeders de módulos activos** - Solo los activos
7. **CdBaseSeeder** - Contenido base (siempre se ejecuta)

### 2. Dependencias entre Seeders

Si un seeder depende de otro, asegurarse de que:

- El seeder dependiente esté en el mismo módulo, o
- El seeder base se ejecute antes (en la sección "siempre activos")

### 3. Seeders Mínimos (Futuro)

Para módulos inactivos, se podría implementar seeders "mínimos" que solo creen:

- Estructura básica de tablas (si es necesario)
- Datos de configuración mínimos
- Sin contenido de ejemplo

Esto permitiría activar el módulo más tarde sin problemas.

## 📊 Métricas de Optimización

### Antes
- Tiempo de ejecución: ~30-45 segundos
- Seeders ejecutados: 12-15 (todos)
- Datos poblados: Todos los módulos

### Después
- Tiempo de ejecución: ~10-20 segundos (dependiendo de módulos activos)
- Seeders ejecutados: Solo módulos activos + seeders base
- Datos poblados: Solo módulos activos

## 🔄 Migración de Proyectos Existentes

Para proyectos existentes que ya tienen datos de módulos inactivos:

1. **Opción 1**: Limpiar datos manualmente
   ```sql
   DELETE FROM posts WHERE id > 0; -- Ejemplo para blog inactivo
   ```

2. **Opción 2**: Ejecutar `migrate:fresh --seed` (limpia todo y vuelve a poblar)

3. **Opción 3**: Crear comandos artisan para limpiar módulos específicos

## 🛠️ Trait para Seeders Individuales

Se creó un trait opcional que los seeders pueden usar para verificación adicional:

```php
use Database\Seeders\Traits\ChecksModuleActive;

class BlogSeeder extends Seeder
{
    use ChecksModuleActive;
    
    protected $moduleName = 'blog';
    
    public function run()
    {
        if (!$this->shouldRun()) {
            return;
        }
        
        // ... lógica del seeder
    }
}
```

**Nota:** Este trait es opcional. El `Project_Seeder` ya verifica los módulos activos antes de ejecutar los seeders, pero el trait es útil si:

- El seeder se ejecuta directamente (no a través de `Project_Seeder`)
- Quieres una verificación adicional con mensajes más descriptivos
- Necesitas lógica condicional dentro del seeder basada en el estado del módulo

## 📊 Ejemplo de Ejecución Optimizada

### Proyecto: Pevero Salud
**Módulos activos:** `services`, `faqs`, `about`, `contact`

**Seeders ejecutados:**
- ✅ `CdSystemSeeder` (siempre)
- ✅ `SiteDataSeeder` (siempre)
- ✅ `AssetsSeeder` (siempre)
- ✅ `AnalyticsSeeder` (siempre)
- ✅ `ProjectsUsersSeeder` (siempre)
- ✅ `ServiceCategoriesSeeder` (módulo `services` activo)
- ✅ `ProjectsServicesSeeder` (módulo `services` activo)
- ✅ `FaqsSeeder` (módulo `faqs` activo)
- ✅ `CdBaseSeeder` (siempre)
- ⏭️ `BlogSeeder` (módulo `blog` inactivo - omitido)
- ⏭️ `GallerySeeder` (módulo `gallery` inactivo - omitido)
- ⏭️ `ProjectsSeeder` (módulo `projects` inactivo - omitido)
- ⏭️ `TeamSeeder` (módulo `team` inactivo - omitido)
- ⏭️ `ProductsSeeder` (módulo `products` inactivo - omitido)
- ⏭️ `ReferencesSeeder` (módulo `references` inactivo - omitido)
- ⏭️ `NewsSeeder` (módulo `news` inactivo - omitido)

**Resultado:** Solo se ejecutan los seeders necesarios, optimizando tiempo y recursos.

## 🔧 Limpieza de Datos Existentes

Si ya ejecutaste seeders con módulos inactivos y quieres limpiar esos datos:

### Opción 1: Migrate Fresh (Recomendado para desarrollo)
```bash
php artisan migrate:fresh --seed
```

### Opción 2: Limpieza Manual por Módulo
```sql
-- Ejemplo: Limpiar datos de blog si está inactivo
DELETE FROM posts;
DELETE FROM post_categories;

-- Ejemplo: Limpiar datos de gallery si está inactivo
DELETE FROM galleries;
DELETE FROM gallery_categories;
DELETE FROM gallery_tags;
```

### Opción 3: Comandos Artisan ✅ (Disponible)

Se han creado comandos artisan para limpiar módulos específicos:

**Comando genérico:**
```bash
php artisan project:clean-module {module} [--force] [--dry-run]
```

**Comandos específicos por módulo:**
```bash
php artisan project:clean-blog [--force] [--dry-run]
php artisan project:clean-services [--force] [--dry-run]
php artisan project:clean-faqs [--force] [--dry-run]
php artisan project:clean-gallery [--force] [--dry-run]
php artisan project:clean-projects [--force] [--dry-run]
php artisan project:clean-products [--force] [--dry-run]
php artisan project:clean-team [--force] [--dry-run]
php artisan project:clean-references [--force] [--dry-run]
php artisan project:clean-news [--force] [--dry-run]
```

**Ejemplos:**
```bash
# Simular limpieza (no aplica cambios)
php artisan project:clean-blog --dry-run

# Limpiar con confirmación
php artisan project:clean-blog

# Limpiar sin confirmación (útil para scripts)
php artisan project:clean-blog --force
```

**Ver documentación completa:** `docs/COMMANDS-CLEAN-MODULES.md`

## 📚 Referencias

- `database/seeders/Project_Seeder.php` - Implementación principal
- `database/seeders/Traits/ChecksModuleActive.php` - Trait opcional para seeders
- `app/helpers.php` - Función `is_module_active()`
- `config/cd-system.php` - Configuración base de módulos
- `database/seeders/project-data/cd-system.json` - Configuración del proyecto

---

**Última actualización:** Enero 2026  
**Versión:** 1.0.0
