# Fix `cd-system:set-demo` — actualizar las 3 fuentes de verdad

> Fecha: 2026-05-15
> Detectado en: cd-frontend-dev (container Docker)
> Symptom: al cambiar de demo, vistas + clase `<html>` cambiaban OK pero header, footer y CSS específico del demo seguían usando el demo viejo.

---

## Causa raíz

El helper `get_theme_demo()` (en `app/helpers.php`) lee la fuente del demo activo con esta prioridad:

```php
function get_theme_demo()
{
    try {
        $slug = cache()->remember('active_demo_slug', 300, function () {
            return \App\Models\Demo::where('is_active', true)->value('slug');
        });
        if ($slug) return $slug;
    } catch (\Throwable $e) { /* fallback */ }

    return config('cd-system.theme.demo', 'demo-accounting-1');
}
```

**Prioridad de resolución**:
1. Tabla `demos` con `is_active=true` (cache 300s)
2. Cache key `active_demo_slug` (300s TTL)
3. Fallback: `config('cd-system.theme.demo')` en `settings` table

**El comando `cd-system:set-demo` (versión vieja)** solo actualizaba el **fallback** (`settings.cd-system.theme.demo`). NO tocaba la tabla `demos` ni invalidaba el cache.

**Por eso parte del sistema sí cambiaba y parte no**:

| Lugar del codebase | Cómo lee el demo | ¿Se actualizaba con el comando viejo? |
|---|---|---|
| `<x-base-layout>` clase `<html>` | `config('cd-system.theme.demo')` directo | ✅ SÍ |
| Algunas blades welcome/about/contact | `config(...)` directo | ✅ SÍ |
| `layout/front/partials/_header.blade.php` | `get_theme_demo()` | ❌ NO (devolvía demo viejo de la tabla) |
| `layout/front/partials/_footer.blade.php` | `get_theme_demo()` | ❌ NO |
| `layout/front/partials/_styles.blade.php` | `get_theme_demo()` | ❌ NO (cargaba `demos/{demo-viejo}.css`) |
| `_scripts.blade.php` | `get_theme_demo()` | ❌ NO |

---

## Fix aplicado al comando

El comando ahora actualiza **las 3 fuentes** + clear caches:

```php
// 1. Tabla demos: desactivar todos, activar/crear el target
Demo::query()->update(['is_active' => false]);
Demo::updateOrCreate(['slug' => $demo], ['is_active' => true, 'name' => $demo]);

// 2. Settings (fallback)
CdSystemConfigService::setMany(['theme' => ['demo' => $demo]]);

// 3. Cache del helper
Cache::forget('active_demo_slug');

// 4. Config + view cache
CdSystemConfigService::clearCache();
$this->call('config:clear');
$this->call('view:clear');
```

---

## Uso (igual que antes)

```bash
# En cd-frontend-dev:
docker compose exec app php artisan cd-system:set-demo demo-accounting-2

# En cd-system (local o tenant):
php artisan cd-system:set-demo demo-restaurant
```

**Output esperado**:
```
Estado actual:
  config cd-system.theme.demo:  demo-law-firm-2
  tabla demos is_active=true:   demo-restaurant
  get_theme_demo() efectivo:    demo-restaurant

Aplicando demo: demo-accounting-2
  ✓ Tabla demos actualizada (slug=demo-accounting-2, id=1)
  ✓ Settings actualizado (cd-system.theme.demo=demo-accounting-2)
  ✓ Cache 'active_demo_slug' limpiado
  ✓ Config cache limpiado
  ✓ View cache limpiado

✓ Demo actualizado: demo-restaurant → demo-accounting-2
  Refrescá el navegador (hard reload Ctrl+Shift+R) para ver header/footer/CSS nuevos.
```

---

## Opciones

| Flag | Descripción |
|---|---|
| `{demo}` | Slug del demo (`demo-marketing-1`, `demo-restaurant`, etc.) |
| `--clear-cache=false` | NO limpiar caches (no recomendado, default: limpiar) |
| `--no-views` | Skip `view:clear` (más rápido pero blades pueden quedar cacheadas) |

---

## Workaround manual para containers con imagen vieja

Si tu container `cd-frontend-dev` tiene una imagen ANTES de este fix:

```bash
docker compose exec app php artisan tinker --execute='
$demo = "demo-accounting-2";
\App\Models\Demo::query()->update(["is_active" => false]);
\App\Models\Demo::updateOrCreate(["slug" => $demo], ["is_active" => true, "name" => $demo]);
\App\Services\CdSystemConfigService::setMany(["theme" => ["demo" => $demo]]);
\Illuminate\Support\Facades\Cache::forget("active_demo_slug");
'
docker compose exec app php artisan config:clear
docker compose exec app php artisan view:clear
```

Después de eso, hard reload del navegador (Ctrl+Shift+R).

Cuando salga la nueva imagen del container con el comando ya fixed, el workaround no será necesario.

---

## Validación end-to-end (verificado 2026-05-15)

Después del workaround manual en container cd-frontend-dev:

```bash
$ curl -s http://localhost:8080 | grep -oE '<html[^>]*class="[^"]*"'
<html lang="es" class="light demo-accounting-2"

$ curl -s http://localhost:8080 | grep -oE 'demos/demo-[a-z0-9-]+\.css'
demos/demo-accounting-2.css
```

Confirmado: `<html class>` + CSS apuntan al demo correcto. Header y footer (que usan `get_theme_demo()`) también resuelven al nuevo demo.

---

## Próximo deploy

Para que la imagen del container (`ghcr.io/lacompaniadigital/cd-system:latest`) tenga el fix:

1. CI/CD del repo `cd-system` rebuilds la imagen tras este push
2. Devs frontend hacen `docker compose pull` para bajar la imagen nueva
3. Restart del container: `docker compose restart app`

Mientras no se haga el pull/restart, el workaround manual sigue siendo válido.

---

## Referencias

- Comando: `app/Console/Commands/SetDemoInDatabase.php`
- Helper: `app/helpers.php` (función `get_theme_demo` línea 400)
- Modelo: `app/Models/Demo.php`
- Service: `app/Services/CdSystemConfigService.php`
- Arquitectura repo split: `docs/bewpro2.0/repo-frontend-dev/`
