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
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)
apps/web/app/(app)/admin/altas/tabla-altas.tsx · «'/api/admin/users'»apps/web/lib/admin/invitar-usuario.ts · apps/web/lib/admin/invitar-usuario.ts:14apps/web/lib/auth/invitacion-entrega.ts · apps/web/lib/admin/invitar-usuario.ts:129 (el envío sale en la misma llamada)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:
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.
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.
/invitacion/[token] → /alta/telefono ver la primera vez ↗fuente: apps/web/app/(auth)/invitacion/[token]/actions.ts:188/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/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/dashboard → /setup ver la primera vez ↗fuente: apps/web/app/(app)/dashboard/page.tsx:28 · apps/web/lib/setup/aterrizaje.ts:41La verificación del teléfono (/alta/telefono ver la primera vez ↗) es el único WhatsApp que hoy recibe: un código.
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.
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:
/onboarding ver la primera vez ↗ ver en local ↗ ver en web ↗
Lo hace el sistema solo. No tenés que configurar nada.
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.
/setup/preferences ver la primera vez ↗ ver en local ↗ ver en web ↗
Cómo se ve tu oficina y las horas de tu agenda.
/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.
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.
/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.
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.
/setup/templates ver la primera vez ↗ ver en local ↗ ver en web ↗
Lo que tu oficina dice cuando saluda, agenda o hace seguimiento.
/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.
/setup/team ver la primera vez ↗ ver en local ↗ ver en web ↗
Cada uno recibe su usuario y sus prospectos.
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.
/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.
/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.
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
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 ↗
Entregables Cl. 7.5: código, runbooks, credenciales, incident playbook, Anexo C.
/onboarding/handoff ver la primera vez ↗ ver en local ↗ ver en web ↗
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.
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
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:47La 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:192Buscar 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«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:30Abrí 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:65Confirmar 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/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| Etapa | Qué recibís | Cómo continúa |
|---|---|---|
| 1 · Consulta inicial sin costo | Informació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 empresa | Informació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.
| Decisión | Qué significa | Qué sigue |
|---|---|---|
| Una cuenta centralizada | Varias sedes compran mediante el mismo operador o matriz, con evidencia. | Trabajar la cuenta compradora y mantener sus ubicaciones como contexto. |
| Varios compradores independientes | Cada operador decide su compra. Contar sedes no prueba esta autonomía. | Elegir, enviar y enriquecer cada operador como prospecto único. |
| Matriz o comprador sin confirmar | La evidencia no alcanza para concluir quién decide. | Conservar lo conocido y completar la investigación antes de asumir una estructura. |
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.
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.
/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:54checkVendedorBudget 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:115Un 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:13Si 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:87Notificació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/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:22Conceder 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/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| Quién puede | Dónde | Qué 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-cap | El 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/creditos | Recarga de créditos — si el freno es «la oficina se quedó sin créditos» (saldo), el tope no alcanza: hace falta cargar. |
apps/web/lib/coach/topes-herramienta.ts · «Sólo dueño o admin autorizado». En el Coach global (el orbe), el freno de presupuesto contesta un 422 genérico con sólo un aviso de paso: no abre este modal ni ofrece pedir saldo.Los pasos no tienen ruta propia: se revisan entrando y recorriéndola. La cuenta de pasos sale del código (importada o citada).
| pantalla | pasos | fuente |
|---|---|---|
/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) |
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).
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.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.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.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.
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.