# Laboratorio privado QA (Villa Aurora)

Ambiente interno persistente para pruebas de Juan Carlos Jaramillo. No es un cliente, no aparece en el catálogo público ni en métricas reales.

## Identidad

| Campo | Valor |
| --- | --- |
| Nombre | Laboratorio privado de Juan — Villa Aurora QA |
| Slug | `qa-juan-villa-aurora` |
| Tipo | `internal_test` |
| Geografía | Sierra Clara QA / Villa Aurora QA (ficticia, `is_internal`) |
| Candidato | Juan Carlos Jaramillo — PRUEBAS |
| Login propietario | `juan.qa@example.test` (no es un buzón real) |

## Cómo provisionar (idempotente)

```bash
php artisan goberdata:qa:provision --dry-run
php artisan goberdata:qa:provision --slug=qa-juan-villa-aurora --email=juan.qa@example.test
```

La primera ejecución crea el tenant y escribe contraseñas **solo** en `storage/app/qa-credentials-qa-juan-villa-aurora.json` (ignorado por git). Las ejecuciones siguientes no cambian contraseñas ni duplican el ambiente.

Restablecer únicamente datos sintéticos:

```bash
php artisan goberdata:qa:provision --reset-synthetic
```

Desactivar el laboratorio sin tocar clientes:

```sql
-- o desde tinker:
-- Campaign::where('slug','qa-juan-villa-aurora')->update(['status'=>'suspended']);
```

## Cómo entrar

1. Abrir `/login` en el dominio del entorno (local: el `APP_URL` configurado).
2. Usar `juan.qa@example.test` y la contraseña del archivo local.
3. El panel de campaña es `/m/dashboard` (alias `/admin/dashboard`).
4. Superadministrador: `/superadmin/estadisticas`. Para inspeccionar este tenant, `?campaign_id=` con el ID real.

Roles QA: `candidate`, `campaign_manager`, `territorial_coordinator`, `digital_coordinator`, `treasurer`, `volunteer`, `auditor`.

## Privacidad

- El catálogo `/geo/departamentos` no lista Sierra Clara QA.
- El registro público de demo no acepta esa geografía.
- Un usuario de otro tenant recibe 403 en el snapshot.
- Un miembro con `campaign_user.is_active = false` pierde `hasUser()`.
- La vitrina `/demo` sigue siendo pública e independiente.

## Purga y pagos

Las tareas `demos:purgar` y `membresias:revisar` no tratan este tipo como demo comercial. Un webhook sandbox no lo convierte a `client` ni lo suma a ingresos reales.
