CRM Comercial
Tablero de prospección y seguimiento del equipo comercial de Marko. Reúne en una sola lista los leads del pipeline y las empresas que ya existen en la plataforma.
Descripción
La pantalla contesta una sola pregunta: qué se está cayendo hoy.
Antes de esto, los leads del pipeline y las empresas ya registradas en Marko vivían en dos sistemas distintos y nadie miraba los dos: una cuenta con 1.393 OC históricas pasó 14 días sin que nadie la contactara. El campo origen existe justo para que las dos fuentes aparezcan en la misma lista.
El segundo problema que resuelve es la agenda: de 414 leads medidos, uno solo tenía próxima acción agendada. Por eso la ficha obliga a decidir cuándo es el siguiente toque, y la bandeja del día se construye sobre esa fecha.
Fuentes de datos
Una cuenta del CRM (CrmAccount) es la unión de dos orígenes:
Origen (origen) | Viene de | Significado |
|---|---|---|
lead | leads | Prospecto del pipeline; todavía no es cliente |
trial | companies con paymentStatus: trial / free | Empresa probando el producto |
cliente | companies con paymentStatus: active | Cliente pagando |
suspendido | companies con paymentStatus: suspended | Cliente suspendido |
Cuando una cuenta está en las dos fuentes (un lead que se registró), gana el estado más avanzado del funnel: el documento del lead puede seguir diciendo new mientras la empresa ya está en trial, y mostrar "sin contactar" sobre alguien que está probando el producto sería engañoso. bounced no compite, porque un rebote de correo no borra que la empresa abrió un trial.
Cuentas excluidas: las empresas internas o de prueba (MAIMAG, MARKO TEST, COMERCIALIZADORA DIP) no son pipeline y quedan fuera del tablero. Los registros hechos con correos del propio equipo (marko.cl, maimag.cl, simplit-solutions.com) tampoco generan lead.
Rendimiento: son ~460 documentos (433 leads + 45 empresas), así que se bajan completos una vez y se filtran en memoria; a cambio la bandeja reacciona en tiempo real. Si
leadspasa de unos 2.000 documentos hay que migrar a queries paginadas porstage/nextActionAtcon sus índices.
Estados del funnel
Estado (stage) | Etiqueta en pantalla |
|---|---|
new | sin contactar |
contacted | contactado |
opened | abrió correo |
replied | respondió |
sql | interés explícito |
discovery | reunión agendada |
demoed | demo hecha |
trialing | en trial |
won | cliente |
lost | perdido |
bounced | rebotó (terminal técnico, fuera del orden lineal) |
Se consideran cuentas vivas —en conversación real— las que están en replied, sql, discovery, demoed o trialing. Una cuenta viva sin próxima acción agendada es un lead cayéndose.
Bandeja del día
Cinco contadores sobre la lista; al hacer clic, filtran:
| Contador | Qué cuenta | Tono |
|---|---|---|
| Vencidas | Próxima acción con fecha pasada | Alerta |
| Hoy | Próxima acción para hoy | Aviso |
| Trials ≤10d | Trial que vence dentro de 10 días o menos | Aviso |
| Sin agenda | Cuentas vivas sin próxima acción | Alerta |
| Mi cartera | Cuentas vivas a nombre del usuario conectado | Neutro |
Las fechas se comparan por día y no por instante: una acción de esta mañana no está "vencida".
Lista de cuentas
Columnas: Cuenta, Estado, Próxima acción, Al Estado (12m) y Dueño.
Filtros: búsqueda libre (empresa, RUT, correo, contacto o dueño), estado del funnel, origen y contador activo.
Ordenamientos:
- Prioridad (por defecto) — acción vencida → acción de hoy → trial por vencer → viva sin agenda → resto. A igual prioridad, primero el que más le compra al Estado.
- Próxima acción — las cuentas sin fecha van al final: lo que no está agendado no compite por el primer lugar.
- Volumen al Estado.
- Nombre.
Ficha de la cuenta
Se abre desde la lista y trae la información por Cloud Function (crmGetAccount), no con el SDK, para que el acceso a los datos de la empresa quede registrado en la auditoría.
Secciones:
- Contacto — razón social, RUT, contacto, cargo, correo, teléfono.
- Actividad en ChileCompra (12 meses) — OC de Convenio Marco, Compra Ágil y licitaciones, monto total, canal dominante, convenio dominante y última OC.
- Cuenta en Marko — estado de pago, plan y fecha de fin del trial (solo si la cuenta ya existe como empresa).
- Registrar toque — tipo, resultado, qué pasó y, opcionalmente, mover el estado del funnel.
- Próxima acción — fecha y tipo (
followup,discovery,demo,cierre,cobranza,otro). - Historial de toques — últimos 100 eventos, del más reciente al más antiguo.
Registrar un toque
| Toque | Se guarda como evento | Canal |
|---|---|---|
| Llamada | note | llamada |
note | whatsapp | |
| Nota | note | nota |
| Correo enviado | email-out | correo |
| Respuesta recibida | email-in | correo |
| Reunión agendada | meeting-scheduled | reunion |
| Reunión hecha | meeting-done | reunion |
Resultado: sin respuesta, conversado, agendado o rechazo. No aplica a las notas al margen, y no es parte del schema de events: viaja en data.resultado.
El enum de events es cerrado, así que lo que no calza se guarda como note con el canal en data.canal — el mismo mapeo que usaba la miniapp puente, para que el historial migrado y el nuevo se lean igual.
Agendar una próxima acción también deja su propio evento en el historial, para que quede la traza de cuándo se comprometió el siguiente toque.
Qué puede escribir el CRM
Solo estos campos del lead: stage, stageUpdatedAt, nextActionAt, nextActionType, ownerEmail, notes, tags, doNotContact y doNotContactReason.
Todo lo demás —los números de BigQuery, el origen, las campañas— lo escribe el pipeline automático, y los datos operativos del cliente no se tocan nunca desde acá.
Alta manual de cuentas
Para los inbound y referidos que no vienen del pipeline automático de Compra Ágil.
- Razón social: obligatoria.
- RUT: opcional. Si se informa, se valida el dígito verificador — un RUT malo cruza mal contra BigQuery y contra
companiespara siempre. - Sin RUT: la cuenta se crea con un ID provisional
sinrut-<empresa>(en minúscula) y queda marcada conpendingRut. Sin esta opción los inbound quedaban fuera del sistema, que es lo que pasó con una cuenta que vivió en una ficha markdown que ningún sistema veía. - Duplicados: si la cuenta ya existe, no se crea otra; la UI navega a la ficha que existe.
Cloud Functions
| Función | Qué hace |
|---|---|
crmListCompanies | Lista de empresas recortada a campos comerciales (evita que el navegador reciba las credenciales de los clientes) |
crmGetAccount | Ficha completa: lead, empresa y últimos 100 eventos |
crmCreateAccount | Alta manual, con o sin RUT |
crmRegisterTouch | Registra el toque y, si corresponde, mueve el estado |
crmScheduleNextAction | Agenda la próxima acción |
crmUpdateCompanyPlan | Cambia el plan de una empresa desde la pestaña Empresas (MRKO-327) |
Todas exigen staff o admin (assertStaff) y escriben en staffAccessLog. Ninguna se deploya automáticamente:
firebase deploy --only functions:crmListCompanies,functions:crmGetAccount --project prod
Toda escritura entra por
ensureLead, que crea la ficha del lead antes del evento. Escribir enleads/{id}/eventscuando el documento padre no existe deja la subcolección colgando: Firestore acepta la escritura, pero el lead no aparece en ningún listado y el historial se vuelve invisible.
Cerrar el ciclo: plan y acuerdo
El CRM prospecta y da seguimiento, pero no cambia el plan de un cliente ni genera su contrato. Eso se hace en Configuración → Empresas, a la que el mismo rol tiene acceso acotado desde MRKO-327: plan, estado de pago, precio de licencia, fechas de trial y el Acuerdo de Servicio. Ver Rol Staff → Gestión de planes y acuerdos.
Enlaces Relacionados
- Rol Staff — el modelo de acceso detrás de esta pantalla
- Administración de Plataforma — gestión de empresas, planes y estado de pago
- Mis Clientes — la cartera de clientes dentro de una empresa (no confundir)
- Análisis Mercado Público — de dónde sale la actividad en ChileCompra