# Plan de onboarding — dueño del laboratorio (tenant)

> **Estado:** planificación aprobada (decisiones de producto cerradas 2026-07-27).  
> **Implementación:** **después** del núcleo multi-tenant (MT-0 / MT-1 mínimo).  
> **Relacionado:** `PLAN_MULTITENANT.md` (provisión, roles, config dueño),  
> `PLAN_ACTUALIZACION.md` (fases técnicas SaaS).

Este documento define el **onboarding del dueño del lab** (`admin` del tenant):
qué ve en el primer acceso, qué es obligatorio, qué es opcional y cómo se cierra
el flujo. **No** hay onboarding de producto para `empleado`, `laboratorista` ni
wizard de self-signup.

---

## 1. Objetivo

Que un laboratorio **recién provisionado** por el superadmin quede:

1. **Seguro** — el dueño ya no usa la contraseña temporal.
2. **Identificado** — nombre/datos del lab y sucursal principal revisados.
3. **Orientado** — sabe qué conviene configurar después (personal, precios, etc.)
   sin bloquear la operación.

**Regla de producto:** el lab es **usable desde el minuto 1** (checklist, no
wizard obligatorio de configuración). La única fricción dura es el
**cambio de contraseña temporal**.

---

## 2. Decisiones cerradas

| Tema | Decisión |
|------|----------|
| Protagonista v1 | Solo **dueño** (`admin` del tenant) |
| Forma | **Checklist en el dashboard** (no wizard de setup del lab) |
| Mínimo “operable” | **Identidad del lab + sucursal** (vienen de la provisión; hay que **confirmar/editar**) |
| Catálogo al crear tenant | **Base sembrada, precios en $0** (checkbox de provisión ON por defecto) |
| Primer login | **Forzar cambio de contraseña** en pantalla intermedia **antes** del dashboard |
| Cierre del onboarding | **Auto al cumplir mínimos** + botón **“Marcar como listo”** |
| Alcance del estado | **A nivel tenant** (un onboarding por laboratorio) |
| Tenant 1 (datos actuales) | **Backfill `onboarding_completed_at`** → no ve el checklist |
| Superadmin | Solo **mensaje post-creación con credenciales** (una vez); sin checklist de entrega en UI |
| Staff | Sin tour ni checklist de onboarding |

---

## 3. Actores y qué ve cada uno

| Actor | Onboarding en producto |
|-------|------------------------|
| `superadmin` | Tras crear tenant: pantalla de éxito con URL, usuario admin, contraseña temporal (mostrar **una sola vez**). Sin tour de plataforma. |
| `admin` (dueño, tenant nuevo) | 1) Forzar password → 2) Dashboard con checklist hasta completar o “Marcar como listo”. |
| `admin` (tenant ya completado / tenant 1) | Nada de checklist de bienvenida. |
| `empleado` / `laboratorista` | Nada. |

---

## 4. Flujo extremo a extremo

```
Superadmin
  → /super/tenants/nuevo
  → TenantProvisioner
       · tenant (onboarding_completed_at = NULL)
       · sucursal principal + consecutivo
       · maximos
       · admin dueño + must_change_password
       · catálogo base precios 0 (default)
  → Pantalla éxito: URL + user + pass temporal (una vez)

Dueño (primer login)
  → /login
  → ¿must_change_password? → /auth/cambiar-password (obligatorio)
  → /dashboard
  → Card “Configura tu laboratorio” (checklist)
       · [mínimos] Datos del lab · Sucursal principal
       · [opcionales] Personal · Precios catálogo · Puntos · …
  → Auto-completa al detectar mínimos OK
    o dueño pulsa “Marcar como listo”
  → onboarding_completed_at = now()
  → checklist desaparece para todos los admin del tenant
```

---

## 5. Paso 0 — Cambio de contraseña forzado

### 5.1 Comportamiento

- Flag en usuario (propuesta): `users.force_password_reset` (bool) o reutilizar
  mecanismo Shield equivalente si se adopta de forma limpia.
- Al provisionar el admin del tenant: **flag = 1**.
- Filtro post-auth (o branch en `poblar_sesion_usuario` + redirect):
  - Si flag activo y ruta no es “cambiar password” / logout → **redirect** a
    `/auth/cambiar-password` (nombre exacto al implementar).
- Pantalla mínima: contraseña actual (temporal) + nueva + confirmar.
- Al guardar: actualiza identity Shield, flag = 0, auditoría
  `password_changed_forced`.
- **No** muestra aún el checklist de lab; eso es el dashboard.

### 5.2 Criterios de aceptación

- No puede ir a `/dashboard`, `/resultados`, `/cotizacion`, etc. con el flag activo.
- Tras cambiar, el flag no vuelve a activarse salvo “reset admin” del superadmin
  (ese flujo debe volver a poner flag = 1 y contraseña temporal).

---

## 6. Checklist en el dashboard (dueño)

### 6.1 UI

- **Dónde:** solo en home del admin (`/dashboard`), arriba del POS / atajos.
- **Quién la ve:** cualquier `admin` del tenant mientras
  `tenant.onboarding_completed_at IS NULL`.
- **Tono:** orientativo, no alarmante. Título sugerido:
  **“Configura tu laboratorio”** · subtítulo: “Completa lo esencial para operar
  con tu marca y tu sucursal.”
- **Progreso:** “2 de 2 esenciales · 1 de 4 recomendados” (o barra simple).
- **Acciones globales:**
  - **Marcar como listo** (siempre visible; confirma con modal corto si faltan
    mínimos: “Aún no confirmaste X. ¿Cerrar de todos modos?”).
  - Enlace “Más tarde” no hace falta si el checklist no bloquea la UI del resto
    del dashboard (solo es una card dismissible vía “listo”).

### 6.2 Ítems del checklist

#### Esenciales (mínimo operable)

| ID | Paso | Cómo se detecta “hecho” | CTA |
|----|------|-------------------------|-----|
| `lab_datos` | Revisar datos del laboratorio | Flag `tenant.onboarding_lab_confirmed_at` **o** el dueño guardó al menos una vez en Config › Datos del lab | Ir a configuración del lab |
| `sucursal` | Revisar sucursal principal | Flag `tenant.onboarding_sucursal_confirmed_at` **o** guardó la sucursal principal al menos una vez | Ir a sucursales |

> **Nota de implementación:** la provisión ya crea nombre y sucursal; “hecho”
> no es “existen filas”, sino **confirmación explícita** (guardar en form o
> botón “Confirmar” en el propio checklist que redirige al form prellenado).
> Preferir **confirmación al guardar** el form correspondiente para no duplicar UI.

#### Recomendados (opcionales; no bloquean cierre automático de esenciales)

| ID | Paso | Cómo se detecta “hecho” | CTA |
|----|------|-------------------------|-----|
| `personal` | Dar de alta personal (cajero y/o laboratorista) | Existe ≥1 usuario activo del tenant en grupo `empleado` **o** `laboratorista` (además del admin dueño) | Ir a Personal |
| `precios` | Poner precios al catálogo | Existe ≥1 fila en `precios` del tenant con precio General > 0 | Ir a Precios / Análisis |
| `puntos` | Revisar puntos y descuentos | Guardó al menos una vez en Config › Puntos **o** flag de confirmación | Ir a Config / puntos |
| `explorar_pos` | Probar el punto de venta | Opcional débil: visitó `/dashboard` con POS visible y cerró el tip; **o** existe ≥1 venta del tenant. Preferir “marcar manual” en el ítem o auto si hay venta. | Scroll al POS / abrir cotización |

Los recomendados se muestran con badge “Recomendado”. Completarlos no es
obligatorio para auto-cerrar ni para “Marcar como listo”.

### 6.3 Lógica de cierre

```
mínimos_ok = lab_datos && sucursal

SI mínimos_ok:
  · banner suave “Ya puedes operar. ¿Cerrar la guía?”
  · (opcional) auto-set onboarding_completed_at tras N segundos NO — mejor
    no auto-ocultar sin acción; el plan dice “auto al cumplir mínimos”
    interpretado como: los ítems se marcan solos + se habilita estado listo.
  · Al cumplir mínimos_ok la primera vez: set onboarding_completed_at
    AUTOMÁTICAMENTE (decisión: auto al cumplir mínimos).

SI el dueño pulsa “Marcar como listo” (con o sin mínimos):
  · Si !mínimos_ok → modal de confirmación
  · Set onboarding_completed_at = now()
  · Checklist no vuelve a mostrarse
```

**Interpretación de “Auto al cumplir mínimos + botón Marcar como listo”:**

1. Los pasos se **autodetectan** (checks verdes).
2. Cuando `mínimos_ok` pasa a true → se escribe `onboarding_completed_at` y se
   oculta el checklist en la **siguiente** carga (o se muestra toast
   “Configuración esencial lista” y se colapsa).
3. El botón **Marcar como listo** permite cerrar **antes** (skip consciente) o
   cerrar sin esperar si la detección fallara.

Si se prefiere no sorprender con el auto-hide, alternativa equivalente en
implementación: al cumplir mínimos solo mostrar CTA primario “Listo, continuar”
pre-seleccionado; producto sigue siendo “sin wizard”. Documentar en bitácora
si se elige la variante “CTA final” en lugar de hide inmediato.

**Recomendación de UX al implementar:**  
Al cumplir mínimos → toast + checklist colapsado a una línea “Guía completada”
con “Deshacer” 10 s **o** hide en el siguiente request. Evitar que el POS
“salte” de layout de forma brusca.

### 6.4 Reabrir la guía

- v1: **no** hay “reabrir onboarding” en menú (estado tenant cerrado).
- Soporte: superadmin podría en el futuro “reset onboarding” (MT-4 / backlog).
- El hub `/configuracion` sigue disponible siempre (no es el checklist).

---

## 7. Modelo de datos (propuesta)

Sobre la tabla `tenant` (ver `PLAN_MULTITENANT.md`):

| Campo | Tipo | Uso |
|-------|------|-----|
| `onboarding_completed_at` | datetime null | NULL = mostrar checklist; not null = listo |
| `onboarding_lab_confirmed_at` | datetime null | Paso esencial lab_datos |
| `onboarding_sucursal_confirmed_at` | datetime null | Paso esencial sucursal |

Sobre `users` (Shield):

| Campo | Tipo | Uso |
|-------|------|-----|
| `force_password_reset` | tinyint/bool default 0 | Pantalla intermedia post-login |

**Backfill tenant 1:**  
`onboarding_completed_at = NOW()`, flags de confirmación rellenados, para no
molestar al lab en producción/migración.

**Tenants nuevos:** todo NULL / force_password_reset=1 en el admin creado.

No hace falta tabla `onboarding_steps` en v1: la detección es por flags +
queries de existencia (personal, precios).

---

## 8. Provisión y superadmin (interfaz de entrega)

### 8.1 TenantProvisioner (extensión del plan MT)

Además de lo ya definido en multi-tenant:

1. `onboarding_completed_at = NULL` en tenant nuevo.
2. Admin dueño con `force_password_reset = 1`.
3. Catálogo base con precios General = 0 (default ON).
4. Sucursal principal creada (el paso checklist será “confirmar”, no “crear”).

### 8.2 Pantalla post-creación (superadmin)

```
Laboratorio creado

Nombre: Lab Norte
URL:    https://app.../login
Usuario admin: labnorte_admin
Contraseña temporal: ********  [Copiar]

Avisa al dueño que:
  1. Debe cambiar la contraseña al entrar
  2. Verá una guía corta para confirmar datos del lab y sucursal

[Ir al detalle]  [Crear otro]  [Listado]
```

La contraseña **no** se vuelve a mostrar al recargar el detalle (solo hash en BD).
Si se pierde: acción “Regenerar admin” (ya en plan MT) → nueva temporal + flag reset.

---

## 9. Integración con fases multi-tenant

| Fase MT | Qué del onboarding entra |
|---------|---------------------------|
| **MT-0** | Columnas en `tenant` / `users`; backfill tenant 1 completado; `force_password_reset` en modelo/sesión |
| **MT-1** | Provisioner setea flags; pantalla éxito con credenciales; seed catálogo precios 0 |
| **MT-2** | Forms de Datos del lab y Sucursal marcan `*_confirmed_at` al guardar; card checklist en `/dashboard`; cierre auto + “Marcar como listo” |
| **MT-3** | Tests: tenant nuevo ve checklist; tras mínimos no ve; force password bloquea rutas; tenant 1 no ve checklist |
| **MT-4 (backlog)** | Reabrir onboarding, email de bienvenida, tour staff, logo en checklist |

**Orden de build del onboarding (cuando se ejecute):**

1. Flags + force password (seguridad).
2. Hooks de confirmación en config lab / sucursal.
3. Card checklist + cierre.
4. Copy pantalla super post-alta.
5. Tests.

No implementar onboarding **antes** de existir `tenant` y provisión: el checklist
asume multi-tenant.

---

## 10. Wireframes textuales

### 10.1 Forzar contraseña

```
+------------------------------------------+
|  labSoft                                 |
|  Debes actualizar tu contraseña          |
|  Por seguridad, elige una nueva antes    |
|  de continuar.                           |
|                                          |
|  Contraseña temporal  [............]     |
|  Nueva contraseña     [............]     |
|  Confirmar            [............]     |
|                                          |
|              [ Guardar y continuar ]     |
+------------------------------------------+
```

### 10.2 Dashboard con checklist

```
+---------------------------------------------------------------+
|  Configura tu laboratorio                    2/2 esenciales   |
|  Confirma los datos de tu lab para tickets y operación.       |
|---------------------------------------------------------------|
|  ✓ Datos del laboratorio          [Editar]                    |
|  ✓ Sucursal principal             [Editar]                    |
|  ○ Personal (recomendado)         [Ir a Personal]             |
|  ○ Precios del catálogo           [Ir a Precios]              |
|  ○ Puntos y descuentos            [Ir a Config]               |
|  ○ Explorar el punto de venta     (abajo en esta página)      |
|---------------------------------------------------------------|
|  [ Marcar como listo ]                                        |
+---------------------------------------------------------------+
|  Atajos  |  POS  ...                                          |
```

### 10.3 Super — éxito alta

```
+------------------------------------------+
|  ✓ Laboratorio creado                    |
|  Copia estas credenciales ahora;         |
|  no se mostrarán otra vez.               |
|  ...                                     |
+------------------------------------------+
```

---

## 11. Criterios de aceptación

1. Admin de tenant nuevo **no** entra al dashboard sin cambiar contraseña temporal.
2. Tras cambiar contraseña, ve el checklist en `/dashboard`.
3. Empleado/lab **nunca** ven el checklist de dueño.
4. Tenant 1 migrado **no** ve checklist.
5. Guardar datos del lab y sucursal principal marca esenciales; al tener ambos,
   el onboarding se cierra (auto) o el botón “Marcar como listo” cierra aunque
   falten recomendados.
6. “Marcar como listo” sin mínimos pide confirmación y cierra.
7. Tras `onboarding_completed_at`, ningún admin del tenant vuelve a ver la card.
8. Superadmin ve credenciales **una vez** al crear; reset-admin regenera temporal
   y vuelve a forzar password.
9. Catálogo sembrado con precios 0 no bloquea el checklist; el ítem “precios”
   queda pendiente hasta que haya algún precio > 0 (solo recomendado).

---

## 12. Fuera de alcance (onboarding v1)

- Self-signup / trial público.
- Wizard multi-pantalla de setup del lab (bloqueante).
- Onboarding o product tour de empleado / laboratorista.
- Emails/WhatsApp automáticos de bienvenida.
- Checklist de entrega interactivo para el superadmin (más allá de la pantalla
  de credenciales).
- Importación masiva de catálogo en el onboarding.
- Branding (logo/color) como paso del checklist (va a MT-4 / config dueño).

---

## 13. Riesgos

| Riesgo | Mitigación |
|--------|------------|
| “Confirmar” vs “ya existe fila” confunde la detección | Flags `*_confirmed_at` al guardar form, no al existir fila de provisión |
| Force password se salta por URL directa | Filtro global auth para admins con flag |
| Auto-cierre sorprende al dueño | Toast claro; opcional colapsar en lugar de borrar al instante |
| Varios admin: uno cierra y el otro “pierde” la guía | Comportamiento deseado (estado tenant) |
| Precios 0 y venden sin revisar | Ítem recomendado visible; no bloquear (decisión de producto) |

---

## 14. Resumen ejecutivo

1. **Solo el dueño** tiene onboarding de producto.
2. **Seguridad primero:** cambio de contraseña forzado en pantalla intermedia.
3. **Checklist no bloqueante** en el dashboard: esenciales (lab + sucursal) +
   recomendados (personal, precios, puntos, POS).
4. **Cierre** automático al cumplir esenciales y/o manual con “Marcar como listo”.
5. **Estado por tenant**; lab actual migrado ya completado.
6. **Superadmin** solo entrega credenciales en la UI de alta.
7. Se implementa **encima** de MT-0/MT-1/MT-2, no antes del multi-tenant.

---

## 15. Preguntas abiertas menores (no bloquean el plan)

Resolver en implementación sin reabrir el diseño:

- Nombre exacto de rutas (`/auth/password`, `/configuracion/laboratorio`, …).
- Variante de cierre: hide inmediato vs CTA “Continuar” al cumplir mínimos
  (ver §6.3).
- Si “explorar POS” se detecta por venta o solo es tip estático.
- Copy final en español (revisión de tono en UI).

Si más adelante se quiere onboarding de staff o self-service, abrir un addendum;
no mezclar con este alcance v1.
