# Dependencias entre Módulos

Este documento mapea cómo los módulos dependen unos de otros, cómo se conectan con los demos (especialmente en el welcome/homepage), y qué pasa al activar o desactivar un módulo.

## Principio de diseño

Los módulos son **independientes a nivel de base de datos** (no hay foreign keys entre tablas de distintos módulos). La dependencia existe solo a nivel de **vistas** (qué secciones del homepage muestran datos de qué módulos) y a nivel de **seeders** (orden de ejecución).

## Matriz de dependencias

### Dependencias de datos (DB)

Ningún módulo depende de otro a nivel de tablas. Cada módulo tiene sus propias tablas aisladas. La única dependencia compartida es:

| Dependencia | Módulos que la usan | Tabla |
|-------------|---------------------|-------|
| users | blog, news | `posts.user_id`, `news.user_id` → `users.id` |

### Dependencias de vistas (Homepage/Welcome)

El `HomepageController` consulta **todos los módulos activos** y pasa los datos a la vista welcome del demo. Cada demo usa un subconjunto:

#### demo-restaurant (welcome.blade.php)

| Sección del homepage | Variable | Módulo requerido | Comportamiento si módulo inactivo |
|---------------------|----------|-----------------|----------------------------------|
| Hero carousel | `$carouselImages` | (base, siempre) | Muestra carousel con imágenes estáticas |
| Preview del menú | `$menuSections` | menu | Sección no se renderiza (colección vacía) |
| Link "Ver menú completo" | -- | menu | Se oculta con `config('cd-system.modules.menu.active')` |
| Blog reciente | `$recentPosts` | blog | Sección no se renderiza (colección vacía) |

**Módulos que NO usa en el welcome:** products, services, projects, gallery, team, references, news, faqs.

#### demo-law-firm-2 (welcome.blade.php)

| Sección del homepage | Variable | Módulo requerido | Comportamiento si módulo inactivo |
|---------------------|----------|-----------------|----------------------------------|
| Hero carousel | `$carouselImages` | (base, siempre) | Fallback a imagen estática |
| Servicios carousel | `$services` | services | Sección no se renderiza (`isset && count > 0`) |
| Equipo carousel | `$teamMembers` | team | Sección no se renderiza (`count > 0`) |
| Blog/noticias | `$recentPosts` | blog | Sección no se renderiza (`isset && count > 0`) |
| Referencias marquee | `$featuredReferences` | references | Sección comentada actualmente |

**Módulos que NO usa en el welcome:** products, menu, projects, gallery, news, faqs.

### Mapa completo: qué datos pasa el HomepageController

| Variable | Modelo | Módulo | Condición |
|----------|--------|--------|-----------|
| `$carouselImages` | WelcomeCarousel | (base) | Siempre |
| `$featuredProducts` | Product | products | `modules.products.active` |
| `$categories` | ProductCategory | products | `modules.products.active` |
| `$services` | Service | services | `modules.services.active` |
| `$recentPosts` | Post | blog | `modules.blog.active` |
| `$menuSections` | MenuCategory | menu | `modules.menu.active` |
| `$featuredProjects` | Project | projects | `modules.projects.active` |
| `$featuredReferences` | Reference | references | `modules.references.active` |
| `$teamMembers` | TeamMember | team | `modules.team.active` |
| `$recentNews` | News | news | `modules.news.active` |
| `$galleryImages` | Gallery | gallery | `modules.gallery.active` |
| `$featuredFaqs` | Faq | faqs | `modules.faqs.active` |
| `$kpis` | (hardcoded) | (base) | Siempre |
| `$seoData` | (hardcoded) | (base) | Siempre |

Si un módulo está inactivo, el controlador pasa una **colección vacía** (`collect()`). Las vistas verifican `isset()` y `->count() > 0` antes de renderizar las secciones correspondientes. Esto garantiza que no hay errores si un módulo está desactivado.

## Dependencias de navegación

Los módulos aparecen en header y footer según su configuración `navigation.header` y `navigation.footer`. Si un módulo está inactivo, no aparece en la navegación aunque tenga `navigation.header: true`.

| Módulo | Header por defecto | Footer por defecto |
|--------|-------------------|--------------------|
| blog | si | si |
| menu | si | si |
| products | si | si |
| services | si | si |
| projects | si | si |
| gallery | no | si |
| faqs | no | si |
| about | no | si |
| contact | si | si |
| team | configurable | configurable |
| references | no | configurable |
| news | no | si |
| newsletter | -- | -- (componente inline) |

## Dependencias de seeders

El `Project_Seeder` ejecuta seeders en orden. Los seeders de módulos solo corren si el módulo está activo en `cd-system.json`:

```
1. CdSystemSeeder        → (siempre, debe ser primero)
2. AssetsSeeder           → (siempre)
3. SiteDataSeeder         → depende de: AssetsSeeder (resuelve URLs)
4. AnalyticsSeeder        → (siempre)
5. ProjectsUsersSeeder    → (siempre)
6. Seeders de módulos:
   ├── ServiceCategoriesSeeder + ProjectsServicesSeeder  (si services activo)
   ├── BlogSeeder                                         (si blog activo)
   ├── GallerySeeder                                      (si gallery activo)
   ├── ProjectsSeeder                                     (si projects activo)
   ├── TeamSeeder                                         (si team activo)
   ├── ProductsSeeder                                     (si products activo)
   ├── ReferencesSeeder                                   (si references activo)
   ├── FaqsSeeder                                         (si faqs activo)
   ├── NewsSeeder                                         (si news activo)
   └── MenuSeeder                                         (si menu activo)
7. CdBaseSeeder           → (siempre, al final)
```

**Dependencia crítica:** `AssetsSeeder` antes de `SiteDataSeeder` (la primera vez, SiteDataSeeder no puede resolver URLs de Cloudinary si la tabla assets está vacía).

No hay dependencias entre seeders de distintos módulos (cada uno es independiente).

## Dependencias de page-headers

Cada módulo que tiene vista frontend necesita un `dynamic-header.blade.php` con variantes para los demos que lo soportan. Actualmente:

| Módulo | Archivos dynamic-header | Demos con variante |
|--------|------------------------|--------------------|
| cd-base | `modules/cd-base/frontend/partials/dynamic-header.blade.php` | Todos |
| blog | `modules/blog/frontend/partials/dynamic-header.blade.php` | restaurant, law-firm-2, etc. |
| menu | `modules/menu/frontend/partials/dynamic-header.blade.php` | restaurant, etc. |
| products | `modules/products/frontend/partials/dynamic-header.blade.php` | Todos |
| services | `modules/services/frontend/partials/dynamic-header.blade.php` | law-firm-2, etc. |
| projects | `modules/projects/frontend/partials/dynamic-header.blade.php` | Todos |
| gallery | `modules/gallery/frontend/partials/dynamic-header.blade.php` | Todos |
| team-members | `modules/team-members/frontend/partials/dynamic-header.blade.php` | law-firm-2, etc. |
| references | `modules/references/frontend/partials/dynamic-header.blade.php` | Todos |
| faqs | `modules/cd-base/faqs/frontend/partials/dynamic-header.blade.php` | Todos |

**Implicación al crear un producto nuevo:** Verificar que cada módulo incluido tenga variante de dynamic-header para el demo del producto. Si no la tiene, crearla.

## Compatibilidad módulo-producto

### Qué módulos tiene sentido activar en cada producto

| Producto | Módulos esenciales | Módulos opcionales útiles | Módulos que no aplican |
|----------|--------------------|---------------------------|------------------------|
| Restaurant | menu, blog, faqs | gallery, newsletter, products | services, projects, team, references |
| Law Firm | services, blog, faqs, team | references, gallery, newsletter | menu, products |
| Agency | services, projects, blog | gallery, team, newsletter | menu, products |
| Photography | gallery, blog | services, newsletter | menu, products, team |
| SaaS | products, blog, faqs | newsletter | menu, gallery, team |
| Insurance | services, blog, faqs, team | newsletter, references | menu, products, gallery |

Esta tabla es orientativa. Técnicamente **cualquier módulo puede activarse con cualquier demo**, pero la integración visual (page-headers y secciones del welcome) puede no estar implementada para todas las combinaciones.

## Escenarios de activación/desactivación

### Activar un módulo adicional en un proyecto existente

1. Editar `cd-system.json` → `modules.{modulo}.active: true`
2. Ejecutar `php artisan db:seed --class=CdSystemSeeder`
3. Si el módulo necesita contenido inicial, ejecutar su seeder (ej: `php artisan db:seed --class=BlogSeeder`)
4. Limpiar caché: `php artisan cache:clear && php artisan view:clear`
5. Verificar: la ruta del módulo responde (ej: `/blog`), aparece en navegación si tiene `navigation.header/footer: true`

### Desactivar un módulo

1. Editar `cd-system.json` → `modules.{modulo}.active: false`
2. Ejecutar `php artisan db:seed --class=CdSystemSeeder`
3. Limpiar caché
4. Las rutas del módulo devuelven 404 (middleware `module.enabled`), desaparece de la navegación, las secciones del welcome no se renderizan
5. Los datos en la DB se conservan (no se borran tablas)

### Agregar un módulo nuevo al sistema

1. Crear la estructura del módulo (ver [guias/GUIA-COMPLETA-MODULOS.md](../guias/GUIA-COMPLETA-MODULOS.md))
2. Registrar en `config/cd-system.php` → `modules`
3. Crear rutas en `routes/modules/{modulo}.php`
4. Crear `dynamic-header.blade.php` con variantes para los demos que lo necesiten
5. Crear seeder y JSON de datos
6. Agregar al mapeo de `Project_Seeder`
7. Agregar consulta en `HomepageController` si el módulo debe aparecer en el welcome
8. Documentar

## Diagrama de flujo: resolución de un módulo en runtime

```
Request → /blog
    │
    ├── Middleware module.enabled:blog
    │   └── ¿is_module_active('blog')? 
    │       ├── NO → 404
    │       └── SI → continúa
    │
    ├── BlogController::index()
    │   └── Consulta posts, categorías
    │
    ├── blog/frontend/index.blade.php
    │   └── @extends('layout.front.master')
    │       ├── _header.blade.php → get_demo_layout('header') → headers/demo-restaurant.blade.php
    │       ├── dynamic-header.blade.php → detecta demo → renderiza page-header estilo restaurant
    │       ├── Contenido del módulo (listado de posts)
    │       └── _footer.blade.php → get_demo_layout('footer')
    │
    └── Página renderizada con identidad del demo + contenido del módulo
```
