Los recorridos · el flujo entero, ultra granulado

Los recorridos de Truly Global, paso a paso

Quién lo dispara, qué mensaje viaja (y cuál NO existe), qué es lo primero que ve, y cada tarjeta del alta vacía y llena — con las palabras del propio producto y cada afirmación con su fuente. Si el código cambia, esta página cambia o FRENA: no envejece en silencio.

Alta y onboarding · Cross-país: de la referencia al negocio

Paso 0 · quién lo dispara: el Admin TNI

Cómo nace el alta: el Admin TNI invita al dueño

Ninguna pantalla admin CREA la oficina: las oficinas vienen de TNI (silver, la vista franquicias_alta); su estado se CALCULA — sin_alta → activa en cuanto el invite deja el usuario activo.

los estados del alta (sin_pais · activa · invitada · sin_alta): apps/web/app/(app)/admin/altas/tabla-altas.tsx:134 (sin_pais · activa · invitada · sin_alta)

Alcance: la pista del CORREO (/admin/altas). Hay otras dos entradas al alta que no mandan este recorrido: el Coach y el alta desde el padrón.

apps/web/lib/coach/invitacion-accion.ts:4 (el Coach invita con el mismo invitarUsuario)apps/web/lib/admin/alta-desde-el-padron.ts:32 (el padrón crea cuentas sin invitación)
  1. 1
    El Admin abre /admin/altas y llena el formulario (rol por omisión: el dueño)fuente: apps/web/app/(app)/admin/altas/tabla-altas.tsx · «'/api/admin/users'»
  2. 2
    La API crea la cuenta (ACTIVA desde ya) y encola la invitación en la MISMA transacción; si trae presupuesto, el tope del vendedor viaja adentro (CAT-5204)fuente: apps/web/lib/admin/invitar-usuario.ts · apps/web/lib/admin/invitar-usuario.ts:14
  3. 3
    La entrega arma el token y el correo de bienvenida y lo manda POR RESEND EN EL MOMENTO — no espera al cronfuente: apps/web/lib/auth/invitacion-entrega.ts · apps/web/lib/admin/invitar-usuario.ts:129 (el envío sale en la misma llamada)
  4. 4
    El cron sólo RECOGE lo que quedó pendiente (hasta 3 por corrida); un envío que muere pasa a sin_confirmar y NO se reintenta solofuente: apps/web/app/api/crons/coach-conciliar/route.ts · apps/web/lib/auth/invitacion-entrega.ts:85

/admin/altas ver en local ↗ ver en web ↗ — el formulario del alta, como está HOY:

Paso 1 · lo que le llega al dueño

El correo de bienvenida — y el WhatsApp que NO existe

El correo de abajo no es una maqueta: lo produce el MISMO código que lo manda (apps/web/lib/auth/invitaciones.ts), renderizado con los datos del laboratorio y SIN maquillar. El enlace del botón lleva a /invitacion/<token>.

Hallazgo del producto: el correo real dice el SLUG técnico de la franquicia («tn-gt-109»), no su nombre — la entrega pasa franchise_id tal cual. apps/web/lib/auth/invitacion-entrega.ts:65 → CAT-5245.

El WhatsApp de bienvenida NO existe. Medido al generar: en lib/auth/invitacion-entrega.ts · medido al generar (busca whatsapp/twilio SOLO en ese archivo, sin seguir sus imports) no hay ningún envío por WhatsApp — sólo el correo. El único WhatsApp que puede recibir una persona nueva es el código de verificación del teléfono, y su plantilla de Meta no estaba dada de alta al 18-ago (comentario fechado en lib/auth/telefono-verificacion.ts) → CAT-5243.

Paso 2 · lo primero que ve al entrar

De la invitación al tablero del alta

El botón del correo abre /invitacion/<token>: elegir contraseña. Después el producto lo lleva solo — cada flecha con su fuente, y el aterrizaje MEDIDO en el laboratorio: un dueño en día cero que pide /dashboard aterriza en /setup.

  1. 1
    /invitacion/[token] → /alta/telefono ver la primera vez ↗fuente: apps/web/app/(auth)/invitacion/[token]/actions.ts:188
  2. 2
    /alta/telefono → /alta/coach ver la primera vez ↗fuente: apps/web/app/(app)/alta/telefono/page.tsx:43 (si ya estaba verificado) · y sin verificar también: «lo confirmo después» siempre está — apps/web/components/alta/paso-telefono.tsx:28
  3. 3
    /alta/coach → /dashboard ver la primera vez ↗fuente: apps/web/components/alta/paso-coach.tsx:33 · «lo configuro después» siempre está — apps/web/components/alta/paso-coach.tsx:70
  4. 4
    /dashboard → /setup ver la primera vez ↗fuente: apps/web/app/(app)/dashboard/page.tsx:28 · apps/web/lib/setup/aterrizaje.ts:41

La verificación del teléfono (/alta/telefono ver la primera vez ↗) es el único WhatsApp que hoy recibe: un código.

hoy: sin foto
Paso 3 · el alta paso por paso, con las palabras del producto

El tablero del alta, tarjeta por tarjeta — vacía y llena

El tablero es /setup ver la primera vez ↗ ver en local ↗ ver en web ↗. Cada tarjeta dice quién la hace y qué le dice el producto en cada estado — y el día cero NO es todo «Te toca»: equipo nace «Bloqueado» por presupuesto, preferencias nace con la zona HEREDADA por confirmar, y plantillas nace «Listo» para la 679 (la migración se las clona — infra/schemas/067_clone_master_templates.sql:18). La copia es LA DEL PRODUCTO (_zona-sistema.json) y el progreso se deriva de las tablas donde vive cada dato.

fuente: apps/web/lib/setup/progreso.ts · «Una tarjeta dice `listo` sólo si el dato está DE VERDAD…»fuente: apps/web/lib/setup/progreso.ts · «canales app.office_provisioning»

Los {…} de las copias son variables que el producto rellena en vivo con el dato de la oficina — acá se muestran tal cual viven en _zona-sistema.json.

El tablero, vacío y lleno:

1del alta

Tus canales: WhatsApp, correo y teléfono la corre el sistema pendiente · CAT-5243

/onboarding ver la primera vez ↗ ver en local ↗ ver en web ↗

Lo hace el sistema solo. No tenés que configurar nada.

«Te toca»
Todavía no arrancó.
«En curso»
{listos} de {total} pasos. El resto se resuelve solo o espera a Meta.
«Listo»
Los {total} pasos están arriba.

Auditoría del 23-sep-2026: lo corre un worker (Twilio y Meta), no la oficina. La bienvenida con el link del alta sale SÓLO por correo: el WhatsApp de bienvenida no existe (medido en lib/auth/invitacion-entrega.ts) → CAT-5243.

2del alta

El nombre, el idioma y tu horario la hace Gerente o Dueño sin hallazgo en la auditoría del 23-sep-2026

/setup/preferences ver la primera vez ↗ ver en local ↗ ver en web ↗

Cómo se ve tu oficina y las horas de tu agenda.

«Te toca · día cero»
Tu zona horaria ({zona}) la heredamos del país: confirmala.
«Listo»
{nombre} · {zona}
3del alta

Tarjeta y licencia de oficina la hace Dueño o Gerente verificar en producción

/setup/billing ver la primera vez ↗ ver en local ↗ ver en web ↗

Guardás la tarjeta y activás la licencia de la oficina. Después pagás sólo lo que consumís, al costo del proveedor.

«Te toca»
Falta registrar la tarjeta.
«Listo»
Tarjeta registrada.

Auditoría del 23-sep-2026: la máquina de la licencia y el cobro se terminó ese día (CAT-5205/5206/5208, Done 23-sep). Queda verificar que la bandera del cobro esté encendida en producción cuando toque estrenar.

4del alta

Créditos la hace Gerente o Dueño sin hallazgo en la auditoría del 23-sep-2026

/setup/creditos ver la primera vez ↗ ver en local ↗ ver en web ↗

Con créditos se paga prospectar, enriquecer, campañas e IA. Mínimo US$100; podés activar la recarga automática.

«Te toca»
Falta comprar los primeros créditos (mínimo US$100).
«Listo»
Créditos comprados. Saldo: {saldo}.

Con el cobro apagado esta tarjeta NO se dibuja (el tablero tiene 7). apps/web/lib/setup/progreso.ts:231 (sin cobro, la tarjeta no se dibuja)

Auditoría del 23-sep-2026: cerrada ese día con su ejecutor de recarga (CAT-5207). La pantalla entró a main el 23-sep (Ola M) y su primera foto es de esta revisión.

5del alta

Los mensajes de tu oficina la hace Gerente o Dueño sin hallazgo en la auditoría del 23-sep-2026

/setup/templates ver la primera vez ↗ ver en local ↗ ver en web ↗

Lo que tu oficina dice cuando saluda, agenda o hace seguimiento.

«Te toca»
Todavía no elegiste tus mensajes.
«Listo»
{activas} mensajes activos.
6del alta

Presupuesto de la oficina la hace Gerente o Dueño sin hallazgo en la auditoría del 23-sep-2026

/setup/presupuesto ver la primera vez ↗ ver en local ↗ ver en web ↗

Cuánto puede gastar la oficina por día y por mes. Es el techo que después repartís entre tus vendedores.

«Te toca»
Todavía corre con el de fábrica: poné el de tu oficina antes de sumar al equipo.
«Listo»
La oficina ya tiene su presupuesto.
7del alta

Tus vendedores la hace Gerente o Dueño sin hallazgo en la auditoría del 23-sep-2026

/setup/team ver la primera vez ↗ ver en local ↗ ver en web ↗

Cada uno recibe su usuario y sus prospectos.

«Te toca»
Todavía no has invitado a nadie.
«Bloqueado · día cero»
Primero poné el presupuesto de la oficina: cada vendedor entra con una parte de ese tope.
«Listo»
{vendedores} en tu equipo.
el día cero bloqueado, medido: apps/web/lib/setup/progreso.ts:214

Auditoría del 23-sep-2026: el FORMULARIO de /setup/team no deja crear un vendedor sin presupuesto diario y mensual (CAT-5204). Ojo: /admin/altas sí puede darlo de alta sin presupuesto (nace con el tope por defecto). No existe un tope semanal — pregunta abierta en CAT-5243.

8del alta

Revisión final y salir a operar la hace Gerente o Dueño sin hallazgo en la auditoría del 23-sep-2026

/setup/integrations-check ver la primera vez ↗ ver en local ↗ ver en web ↗

Se revisa que los cuatro canales respondan antes de soltar la oficina.

«Te toca»
Se habilita cuando cierres los pasos de arriba.
«Listo»
Todo revisado. Tu oficina puede salir a operar.
—FUERA del alta

La recepcionista pendiente · CAT-5243

/settings/recepcionista ver la primera vez ↗ ver en local ↗ ver en web ↗

Auditoría del 23-sep-2026: la pantalla existe y el número ya es el mismo del bot por diseño (lee numeroPropioDeOficina, la misma fuente que canales). Pero NO es una tarjeta del alta: nada obliga a configurarla antes del Go Live. Es el paso manual que señaló Pablo → CAT-5243.

Paso 4 · fuente: app/(app)/onboarding/page.tsx · los ids de hub.cards.* leídos del fuente, en su orden

El onboarding de la oficina: DOS vistas, y nadie ve las dos juntas

El dueño y el gerente ven SOLO el bloque de canales — 7 pasos (CHANNEL_STEPS sin fb_page; la tarjeta «canales» de /setup sí exige los 8). El Admin TNI ve SOLO las 3 tarjetas de abajo, más un enlace a /admin/provisioning.

la vista de la oficina: apps/web/app/(app)/onboarding/page.tsx · «AltaDeLaOficina» · pasos: apps/web/lib/onboarding/pasos-de-la-oficina.ts:7 (CHANNEL_STEPS sin fb_page: 7, no 8) la vista del Admin: apps/web/app/(app)/onboarding/page.tsx:56 (las tarjetas sólo se dibujan para TNI) · su enlace extra: apps/web/app/(app)/onboarding/page.tsx:109
1del hub

Training checklist

Módulos listos para capacitar al equipo. Videos train-the-trainer = TNI (post-build).

/onboarding/training ver la primera vez ↗ ver en local ↗ ver en web ↗

2del hub

Handoff pack

Entregables Cl. 7.5: código, runbooks, credenciales, incident playbook, Anexo C.

/onboarding/handoff ver la primera vez ↗ ver en local ↗ ver en web ↗

3del hub

Aceptación Final

Sign-off borrador vs Anexo C. Firma Documenso pendiente del paquete contractual.

/onboarding/acceptance ver la primera vez ↗ ver en local ↗ ver en web ↗

Hallazgo: lib/onboarding/hub.ts exporta HUB_CARDS (5 tarjetas) y NINGÚN archivo lo importa; la página real dibuja training, handoff, acceptance — medido al generar. La pantalla /onboarding/signoff existe y ninguna tarjeta del hub lleva a ella → CAT-5244.

Prospección · de una referencia internacional a un negocio local

Cross-país: el recorrido completo

Aprovechar la relación que Truly ya tiene en otro país para abrir una cuenta local verificada. Vive en /sales/discover/cross-pais ver la primera vez ↗ ver en local ↗ ver en web ↗ — con los ojos del vendedor.

Flujo actualizado · 24-sep Implementación base

primera vez: sin medir en el laboratorio
  1. 1
    Vendedor Mostrar oportunidades

    Se muestran diez empresas por tanda. Ver más oportunidades consulta información ya conocida: no descubre ni investiga nuevas empresas y no inicia enriquecimiento.

    fuente: apps/web/components/prospectar/cross-pais/experience.tsx:47
  2. 2
    Vendedor Entender la empresa en mi país

    La ficha muestra la empresa en el país elegido, las referencias de la red y las ubicaciones conocidas. Si todavía no es cliente local, ofrece Manual y Rocket; al confirmar prepara el prenegocio si aún no existe. Las ubicaciones sólo aparecen cuando hay datos y se despliegan aparte. Un registro o una sede no equivalen a un comprador independiente.

    fuente: apps/web/components/prospectar/cross-pais/experience.tsx:192
  3. 3
    Vendedor → sistema Consulta inicial sin costo

    Buscar empresas relacionadas prepara el prenegocio y consulta fuentes gratuitas para encontrar operadores, proveedores y competidores. Es opcional: se puede trabajar la empresa local directamente desde su ficha. Esta primera etapa muestra lo conocido y coincidencias que aún pueden requerir verificación; no equivale a una investigación completa. No compra la continuación web/IA. El avance queda visible en una espera compacta.

    fuente: apps/web/components/prospectar/cross-pais/experience.tsx:105
  4. 4
    Vendedor con evidencia Revisar quién compra

    «Lo que ya sabemos» abre la ficha de la marca a la derecha, con Manual/Rocket. Las ubicaciones se consultan dentro de esa ficha; los competidores y demás empresas relacionadas quedan aparte. Sólo aparecen categorías con hallazgos. La investigación aporta evidencia: no garantiza que exista una matriz ni convierte cada sede en un prospecto. Si varios operadores compran por separado, trabajá cada uno como prospecto único; si la compra está centralizada, trabajá la cuenta compradora.

    fuente: apps/web/components/prospectar/cross-pais/initial-results.tsx:30
  5. 5
    Vendedor Elegir una empresa y cómo trabajarla

    Abrí la empresa concreta y elegí Modo Manual o Enviar a Truly Rocket. Manual requiere un responsable; el vendedor puede elegirse a sí mismo. La confirmación informa que el enriquecimiento inicial tiene costo. Ya no hay un botón de enriquecimiento independiente en Cross-país.

    fuente: apps/web/components/prospectar/cross-pais/saved-actions.tsx:65
  6. 6
    Sistema Segunda etapa: enriquecer la empresa elegida

    Confirmar Manual o Rocket crea o vincula el negocio con su responsable y solicita enriquecimiento. Esta etapa amplía la información con las fuentes web/IA habilitadas, según necesidad y presupuesto: puede aportar contactos, relaciones y evidencia que la consulta inicial no tenía. Por eso los resultados pueden ser distintos. Si no puede arrancar, no se debe interpretar como completado.

    fuente: apps/web/app/api/leads/route.ts:62
  7. 7
    Responsable o Rocket Continuar en gestión · /sales/board ver la primera vez ↗ ver en local ↗ ver en web ↗

    En Manual, la persona elegida trabaja el negocio en su embudo. En Rocket, el sistema automatiza el seguimiento. Cada empresa se decide por separado. Reabrir una investigación guardada consulta por ID, sin volver a investigar ni duplicar el gasto.

    fuente: apps/web/app/(app)/sales/discover/discover-studio.tsx:1234
    primera vez: manda a /sales-boardhoy: sin foto

Dos etapas de información

EtapaQué recibísCómo continúa
1 · Consulta inicial sin costoInformación conocida y coincidencias de las fuentes gratuitas. Una coincidencia de nombre todavía no prueba una relación con la marca.Abrir la ficha de la empresa correcta y elegir Manual o Rocket.
2 · Enriquecimiento de esa empresaInformación ampliada y evidencia de las fuentes habilitadas, con costo informado. Puede aportar datos diferentes a la primera consulta.Confirmar el envío; seguir el avance y trabajar el negocio en gestión.

Ejemplo 3M: la corrida inicial guardó cuatro coincidencias de nombre —incluidos negocios de otros rubros—, sin búsqueda web ni IA. No son cuatro filiales confirmadas de 3M ni una investigación trabada. Para ampliar la marca, abrir la ficha de 3M; para trabajar otra empresa real, elegir su ficha. No convertir un homónimo en parte del grupo por su nombre. Reabrir esta corrida en el historial recupera esa primera consulta: no ejecuta la segunda etapa.

Las dos decisiones que no hay que confundir

DecisiónQué significaQué sigue
Una cuenta centralizadaVarias sedes compran mediante el mismo operador o matriz, con evidencia.Trabajar la cuenta compradora y mantener sus ubicaciones como contexto.
Varios compradores independientesCada operador decide su compra. Contar sedes no prueba esta autonomía.Elegir, enviar y enriquecer cada operador como prospecto único.
Matriz o comprador sin confirmarLa evidencia no alcanza para concluir quién decide.Conservar lo conocido y completar la investigación antes de asumir una estructura.

Estados, errores y regreso

Validación: pruebas automatizadas, revisión independiente y navegador en escritorio/móvil con consultas reales y envíos interceptados. No se ejecutó investigación pagada ni se crearon negocios reales durante QA. Esta preview conserva el criterio de no publicar fotos con datos del cliente.

Presupuesto · un vendedor topa su tope y pide permiso

Sin créditos: el recorrido completo (CAT-5202)

Cualquier acción paga puede toparse con el tope PERSONAL del vendedor, el de la oficina o el de toda la red — el tope personal sólo puede endurecer, nunca ablandar, un bloqueo que ya puso un nivel de arriba.

  1. 1
    Vendedor El vendedor dispara una acción paga · /sales/discover ver la primera vez ↗ ver en local ↗ ver en web ↗

    Buscar, enriquecer, enviar o pedirle al Coach un lead: cualquier acción que consuma presupuesto pasa por el mismo portón.

    fuente: apps/web/lib/acceso/puede-prospectar.ts:54
  2. 2
    Sistema El servidor mide el tope y frena

    checkVendedorBudget cae CERRADO: si la consulta revienta o no hay fila, bloquea. El tope personal SOLO puede endurecer, nunca ablandar un bloqueo que ya puso la oficina o la red.

    fuente: apps/web/lib/budget/vendedor-cap.ts:115
  3. 3
    Vendedor El vendedor ve el aviso

    Un modal global (no una ruta propia) escucha el evento del navegador y se abre con el título del producto: «No podés seguir: te quedaste sin presupuesto».

    fuente: apps/web/components/prospectar/sin-saldo.tsx:13
  4. 4
    Vendedor Pide permiso: «Solicitar saldo»

    Si el freno es el SUYO y no puede arreglarlo él mismo, ve el botón. Al pulsarlo se crea (o actualiza) la solicitud con una foto del momento: cuánto llevaba gastado y cuál era su tope.

    fuente: apps/web/lib/presupuesto/solicitudes-de-saldo.ts:87
  5. 5
    Sistema Le llega al gerente y al dueño

    Notificación in-app dirigida a franchise_owner/franchise_admin de la oficina, con link directo a la bandeja.

    fuente: apps/web/lib/presupuesto/solicitudes-de-saldo.ts:346
  6. 6
    Gerente o Dueño El gerente o dueño resuelve · /settings/topes-vendedor ver la primera vez ↗ ver en local ↗ ver en web ↗

    La bandeja muestra la solicitud pendiente con la foto de cuánto llevaba y cuál era su tope. Conceder pide un tope nuevo (≤ el de la oficina); Rechazar exige un motivo y abre un enfriamiento de 24 horas.

    fuente: apps/web/components/settings/solicitudes-de-saldo.tsx:22
  7. 7
    Sistema El tope se actualiza y el vendedor se entera

    Conceder escribe el tope nuevo por el único escritor del sistema y avisa al vendedor; Rechazar sólo avisa. El vendedor ve el resultado en su panel «Mi presupuesto».

    fuente: apps/web/lib/presupuesto/solicitudes-de-saldo.ts:245
  8. 8
    Vendedor El vendedor reintenta · /billing/consumo ver la primera vez ↗ ver en local ↗ ver en web ↗

    Con el tope ampliado, la acción original ya no lo frena a él — aunque puede frenarlo otro eslabón de la misma cadena: el tope de la oficina o el de la red.

    fuente: apps/web/components/billing/mi-presupuesto.tsx:18

Lo que dice el producto

«No podés seguir: te quedaste sin presupuesto»
Se te acabó tu presupuesto. Te lo amplían tu gerente o el dueño de la oficina.
Botón
«Solicitar saldo» → «Listo: le avisamos a tu gerente y al dueño.»

Dos rutas directas, sin pasar por la bandeja

Quién puedeDóndeQué sube
Gerente o Dueño/settings/topes-vendedor (formulario directo)El tope PERSONAL del vendedor, sin que exista una solicitud — no cierra ni avisa una solicitud abierta, que queda huérfana hasta que caduque sola.
Gerente o Dueño/settings/cost-capEl tope de TODA la oficina — si el freno era «se llenó el presupuesto de la oficina», es este el que hay que subir, no el personal.
Dueño o Gerente/billing · /setup/creditosRecarga de créditos — si el freno es «la oficina se quedó sin créditos» (saldo), el tope no alcanza: hace falta cargar.

Hallazgos de la exploración (24-sep-2026, con archivo:línea)

Paso 5 · pasos DENTRO de una sola pantalla

Wizards: flujos que viven adentro de una pantalla

Los pasos no tienen ruta propia: se revisan entrando y recorriéndola. La cuenta de pasos sale del código (importada o citada).

pantallapasosfuente
/admin/franchises/new ver en local ↗ ver en web ↗ 5 apps/web/components/admin/franchise-wizard.tsx:66 (datos, twilio, waba, email, confirmar)
/setup/billing ver en local ↗ ver en web ↗ 4 apps/web/components/billing/setup-billing-wizard.tsx:51 (el tipo enumera 1|2|3|4)
/settings/bot ver en local ↗ ver en web ↗ 5 apps/web/app/(app)/settings/bot/i18n.ts:317
/admin/provisioning ver en local ↗ ver en web ↗ 8 lib/admin/provisioning.ts · CHANNEL_STEPS (importado)
El mecanismo · qué se deriva, qué se mide y qué es auditoría fechada

Cómo se actualiza cuando el código cambia

Tres estatus, cada uno dicho donde aparece: lo DERIVADO (pasos, copias, condiciones — se regenera solo), lo MEDIDO (accesos, fotos, hallazgos mecánicos — se re-mide en cada corrida) y la AUDITORÍA FECHADA (los veredictos por tarjeta, con su fecha escrita — envejecen a la vista).

  1. 1
    Los pasos, la copia y las condiciones se DERIVAN al generar (TARJETAS_DEL_ALTA, _zona-sistema.json, el fuente de la página del hub). Toda cita archivo:fragmento se verifica al generar, y los archivo:línea se CALCULAN buscando el fragmento: si un fragmento ya no está, la generación FALLA en vez de mentir.
  2. 2
    Los hallazgos mecánicos (HUB_CARDS sin importadores en el producto, el WhatsApp inexistente) se re-miden en cada corrida: si el código los arregla, acá se retractan solos. El barrido de imports cuenta SOLO app/, components/ y lib/ — ni este instrumento ni los tests son producto.
  3. 3
    La primera vez sale del laboratorio (la 679): laboratorio-dia-cero.sh levanta un Postgres propio con las migraciones reales y sembrar-dia-cero.mjs pone la línea de tiempo REAL del producto (E0 la oficina sin alta · E1 recién invitado · E2 día cero del dueño · E3 entra el primer vendedor). fotos-primera-vez.sh fotografía cada rol EN SU ETAPA contra el laboratorio local. Ojo declarado: el laboratorio corre con un superusuario de Postgres; el local de «hoy» corre como el lector de sólo lectura.
  4. 4
    «HOY» sale de la medición y las fotos del árbol local contra http://127.0.0.1:3101 — el sha y la fecha de ESA medición van aparte en el pie, porque no son los de la matriz.
  5. 5
    Los mensajes: fotos-mensajes.mjs renderiza el correo del builder real (render-correo-bienvenida.ts, sin maquillar el slug) y fotografía /invitacion con el token de la E1.
  6. 6
    Publicar = regenerar dos veces (pantallas-por-rol.mjs y --sin-fotos), desplegar, y sellar con pantallas-publicado-marcar.mjs — el sello guarda el sha de la matriz Y el de la medición.
Comandos para regenerar con la evidencia existente

Requiere salida/medicion.json y las fotos guardadas. Generar la matriz no vuelve a medir accesos: las rutas nuevas se publican como «sin medir».

# Desde la raíz de este repo, en el servidor de sesiones
(cd apps/web && node scripts/run-ts-script.mjs scripts/pantallas-por-rol-datos.ts)
# Conserva las fechas de las mediciones y las fotos existentes
node scripts/mirar-en-local/pantallas-por-rol.mjs
node scripts/mirar-en-local/pantallas-por-rol.mjs --sin-fotos
# DESPUÉS de publicar y verificar las dos versiones:
node scripts/mirar-en-local/pantallas-publicado-marcar.mjs

La completa sale en salida/pantallas-web/; la preview pública, en salida/pantallas-web-sin-fotos/. Antes de desplegar, verificar las citas, las cifras y que la preview no contenga fotos ni datos privados. El sello se escribe después del último despliegue verificado.

Comandos para volver a medir y fotografiar

Corrida aparte de la regeneración: requiere las dos apps locales ya levantadas en esta caja, una contra producción de sólo lectura y la otra contra el laboratorio. El guion de primera vez siembra E0, E1, E2 y E3, fotografía cada rol en su etapa y deja el laboratorio en E2.

# App local contra producción de sólo lectura; conexión en apps/web/.env.local
MEDICION="$PWD/scripts/mirar-en-local/salida/medicion.json" node scripts/mirar-en-local/medir-acceso.mjs 3200
MEDICION="$PWD/scripts/mirar-en-local/salida/medicion.json" node scripts/mirar-en-local/fotos.mjs 3200
# Laboratorio independiente: la app de primera vez debe usar esta base local
bash scripts/mirar-en-local/laboratorio-dia-cero.sh --etapa=2
PGHOST=127.0.0.1 PGPORT=5544 PGUSER=lab PGDATABASE=tn_lab bash scripts/mirar-en-local/fotos-primera-vez.sh 3201

Al terminar, ejecutar los comandos de regeneración, publicar ambas versiones y escribir el sello.

abrir aparte
Foto de la pantalla a tamaño completo