Skip to main content
Traducción. Autoritativo: fs-crm-0003-lists-and-views.md.

Contexto

core ya tiene segmentos dinámicos y cubren la mayoría de las necesidades. Lo que no pueden expresar es lo arbitrario: un grupo piloto elegido a mano, los asistentes a un evento, las ocho cuentas que un ejecutivo atiende personalmente. Eso no tiene regla; tiene el criterio de una persona. Dos cosas distintas comparten una feature porque los tenants las piensan como una:
  • Una lista estática es membresía explícita. Alguien está porque alguien lo puso.
  • Una vista guardada es un filtro almacenado sobre contactos. Es un atajo, y su membresía cambia cuando cambian los datos.
La distinción importa al momento de enviar. Una lista es estable — los miembros son los que eran la semana pasada. Una vista se evalúa al usarla y puede haber cambiado. Confundirlas es cómo una campaña llega a una audiencia distinta de la que la persona esperaba.

Alcance (normativo)

  • crm.lists: estática o vista guardada, por tenant.
  • crm.list_memberships para listas estáticas.
  • Definición de filtro para vistas guardadas, reusando la gramática del DSL de segmentos.
  • Agregar y quitar miembros individual y masivamente.
  • Usar una lista como audiencia de campaña.
  • Exportación CSV de una lista, gateada por permiso y auditada.

Fuera de alcance (normativo)

  • Segmentos dinámicos, que son de core.
  • Compartir listas entre tenants. Nunca.
  • Automatización sobre cambios de membresía — eso lo hace un segmento, y una lista no debería volverse un segundo sistema de disparadores.

Comportamiento (normativo)

  1. Una lista es static o saved_view, declarada al crearse e inmutable después. Convertir una en otra cambia en silencio qué significa “los miembros”.
  2. La membresía estática es explícita, con quién agregó el contacto y cuándo. Esa atribución es lo que hace defendible una lista cuando alguien pregunta por qué una persona recibió una campaña.
  3. Una vista guardada almacena un filtro con la gramática del DSL de segmentos (ADR-012) en vez de un segundo lenguaje de consulta. Su membresía se evalúa en lectura y nunca se materializa.
  4. Una vista guardada usada como audiencia de campaña se evalúa al despachar y la membresía resuelta se congela en la corrida de la campaña, para que la audiencia sea reproducible después.
  5. Quitar un contacto de una lista estática es lógico: removed_at, conservado. “Quién estaba en esta lista en marzo” tiene que ser respondible.
  6. La supresión quita al contacto de toda lista y borra sus filas de membresía.
  7. La exportación tiene su propio permiso y queda auditada como acceso masivo, como cualquier lectura masiva de datos personales.
  8. El alta masiva está acotada y es idempotente: agregar el mismo contacto dos veces deja una membresía activa.

Datos (normativo)

API (normativo)

Eventos (normativo)

crm.list.membership_changed, para que una campaña o integración pueda reaccionar. No se ofrece como webhook saliente por defecto.

Criterios de aceptación (normativo)

  1. El tipo de una lista no se puede cambiar tras crearse.
  2. La membresía estática registra quién agregó el contacto y cuándo.
  3. La membresía de una vista guardada se evalúa en lectura y nunca se materializa.
  4. Una vista usada como audiencia de campaña congela su membresía resuelta en la corrida.
  5. Quitar es lógico: “quién estaba en esta lista en una fecha pasada” es respondible.
  6. La supresión quita al contacto de toda lista.
  7. La exportación exige crm.lists.export y escribe una fila de auditoría de acceso masivo.
  8. Agregar masivamente el mismo contacto dos veces deja una membresía activa.
  9. Negativo: ninguna lista referencia un contacto de otro tenant.

Ejecución

Un solo slice, comando síncrono. La evaluación de vistas guardadas reusa el evaluador del DSL de packages/core — una gramática, un evaluador, un conjunto de tests.

Preguntas abiertas

Changelog

Registro de entrega

Aún no implementado.