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.
Alcance (normativo)
crm.lists: estática o vista guardada, por tenant.crm.list_membershipspara 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)
- Una lista es
staticosaved_view, declarada al crearse e inmutable después. Convertir una en otra cambia en silencio qué significa “los miembros”. - 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.
- 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.
- 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.
- 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. - La supresión quita al contacto de toda lista y borra sus filas de membresía.
- La exportación tiene su propio permiso y queda auditada como acceso masivo, como cualquier lectura masiva de datos personales.
- 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)
- El tipo de una lista no se puede cambiar tras crearse.
- La membresía estática registra quién agregó el contacto y cuándo.
- La membresía de una vista guardada se evalúa en lectura y nunca se materializa.
- Una vista usada como audiencia de campaña congela su membresía resuelta en la corrida.
- Quitar es lógico: “quién estaba en esta lista en una fecha pasada” es respondible.
- La supresión quita al contacto de toda lista.
- La exportación exige
crm.lists.exporty escribe una fila de auditoría de acceso masivo. - Agregar masivamente el mismo contacto dos veces deja una membresía activa.
- 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 depackages/core — una gramática, un evaluador, un conjunto de tests.