Ecosistema LPDI — Versión 22 — Sincronización de copy con producción en los 4 correos de Scouting (#90 a #93): fecha y hora con huso horario (GMT) en los cuatro, #91 con sus dos modos reales (inmediato y resumen numerado), #92 con sus dos diseños reales (a la startup y al convocante) y #93 con quién designó al destinatario — 2026-08-24
87 correos + 4 eliminados · Organizados por: USUARIO → STARTUP → ICG → ENTIDADES → ADMINISTRATIVOS → PERKS → EVENTOS → SCOUTING
Nota (2026-07-06): el trabajo de cumplimiento de esta fecha (bitácora de acciones, versionado de TYC/PDP, controles de sesión) usa pantallas y registros, no agrega correos nuevos. El correo de anuncio de cambio de TYC/PDP (correo 53) ya está cableado y operativo: al publicar una versión nueva desde Documentos legales, una casilla (desmarcada por defecto) lo envía a todos los usuarios registrados, incluidas las cuentas sin confirmar; la regla bloquea su envío si la versión nueva no está cargada.
CATEGORÍA / DESTINATARIO / EXISTENCIA / PRIVILEGIO / TIPO MENSAJE / TYC / FUENTEnotify_applications_enabled), #92 aviso de retiro de postulación (a la entidad siempre, al convocante si notify_withdrawals_enabled está activo) y #93 invitación al organizador designado que aún no tiene cuenta. En ENTIDADES (migración 191, ciclo de vida de borradores 180 días): #94 recordatorio de formalizar (hitos 30/60/90/120/150 días), #95 aviso de cierre (hitos 15 y 3 días antes del corte) y #96 aviso de que el borrador pasó a la papelera. Los 3 correos de borradores los dispara el cron purge-draft-entities, idempotente vía la columna draft_reminder_stage.sendIdeaNotificationEmail): cuando un usuario envía una propuesta desde el modal, llega a soporte@lpdi.co (ahora configurable vía IDEAS_NOTIFY_EMAIL) con hasta 3 imágenes adjuntas. Además la propuesta se persiste en idea_submissions y se consulta en Administración → Sistema → Propuestas de mejora (solo Superadmin).partners@lpdi.co con los datos del prospecto y del referente). Se disparan al guardar un referido en el modal «Referir a LPDI» (sendLpdiReferralEmails), best-effort: un fallo de envío no revierte el referido ya registrado.src/lib/server/email.ts y email-team.ts) las tarjetas de todos los correos activos que cambiaron en los ciclos 1 y 2 (designación de CEO fusionada #13, invitación al equipo de botón único #18, bienvenidas al equipo sin credenciales #20/#21, cuenta creada #65, contacto ICG fusionado #28/#29). Se agregó el correo nuevo #66 (Solicitud de visibilidad de miembro). Además, cada correo cuyo botón abre una pantalla muestra ahora el screenshot de esa pantalla (etiqueta «Pantalla que abre el botón»): #13, #18, #28/#29 y #66.| # | Nombre Técnico | Asunto del correo | Destino CTA | Descripción | Estado | TyC | Img | |
|---|---|---|---|---|---|---|---|---|
| USUARIO — Correos de cuenta y autenticación (15) | ||||||||
| 01 | USUARIO/USER/NUEVO/NO-ED/Confirmación de Correo/NO-TYC/SUPA | “Confirma tu cuenta en el Ecosistema LPDI” | {{ .ConfirmationURL }} → eco.lpdi.co | Confirmación de email al crear cuenta nueva. | Activo | NO | ✓ | |
| 15 | USUARIO/USER/NUEVO/NO-ED/Recordatorio día 3/NO-TYC/LPDI | “Recordatorio: confirma tu cuenta en el Ecosistema LPDI” | ${confirmUrl} | Recordatorio día 3 si no verifica su correo. Lo envía el cron de verificación (Opción B), activo desde 2026-07-06. | Activo | NO | ✓ | |
| 16 | USUARIO/USER/NUEVO/NO-ED/Recordatorio Urgente día 6/NO-TYC/LPDI | “Último aviso: confirma tu cuenta en el Ecosistema LPDI” | ${confirmUrl} | Aviso día 6. Si no verifica, la cuenta se inactiva el día 8. Lo envía el cron de verificación (Opción B), activo. | Activo | NO | ✓ | |
| 62 | USUARIO/USER/EXIST/NO-ED/Cuenta Inactivada/NO-TYC/LPDI | “Tu cuenta fue inactivada — confírmala para reactivarla” | /auth/verificar | Día 8 sin verificar: la cuenta se inactiva y este correo avisa que tiene 30 días para reactivarla verificando su correo. Lo envía el cron de verificación (Opción B). | Activo | NO | ✓ | |
| 05 | USUARIO/USER/NUEVO/NO-ED/Invitación Admin/NO-TYC/SUPA | “Has sido invitado al Ecosistema LPDI” | {{ .ConfirmationURL }} → eco.lpdi.co | Invitación directa desde Supabase Dashboard. | Activo | NO | ✓ | |
| 03 | USUARIO/USER/NUEVO/NO-ED/Magic Link/NO-TYC/SUPA | “Tu enlace de acceso — Ecosistema LPDI” | {{ .ConfirmationURL }} → eco.lpdi.co | Enlace mágico de acceso. Reservado para uso admin. | Activo | NO | ✓ | |
| 06 | USUARIO/USER/EXIST/NO-ED/Reautenticación OTP/NO-TYC/SUPA | “Código de verificación — Ecosistema LPDI” | Código OTP (sin botón) | Código de verificación para acciones sensibles. | Activo | NO | ✓ | |
| 02 | USUARIO/USER/EXIST/NO-ED/Recuperación de Contraseña/NO-TYC/SUPA | “Restablece tu contraseña — Ecosistema LPDI” | eco.lpdi.co/auth/recuperar | Reset de contraseña con enlace seguro. | Activo | NO | ✓ | |
| 10 | USUARIO/USER/EXIST/NO-ED/Contraseña Actualizada/NO-TYC/LPDI | “Tu contraseña ha sido actualizada — Ecosistema LPDI” | eco.lpdi.co/auth/recuperar | Notificación del sistema LPDI cuando el usuario cambia su contraseña. | Activo | NO | ✓ | |
| 08 | USUARIO/USER/EXIST/NO-ED/Notificación Contraseña Cambiada/NO-TYC/SUPA | “Tu contraseña ha sido cambiada — Ecosistema LPDI” | Sin CTA | Avisa al usuario que su contraseña fue actualizada. | Activo | NO | ✓ | |
| 04 | USUARIO/USER/EXIST/NO-ED/Cambio de Correo/NO-TYC/SUPA | “Confirma el cambio de correo — Ecosistema LPDI” | {{ .ConfirmationURL }} → eco.lpdi.co | Verificación del nuevo correo al cambiar email. | Activo | NO | ✓ | |
| 07 | USUARIO/USER/EXIST/NO-ED/Notificación Correo Cambiado/NO-TYC/SUPA | “Tu correo electrónico ha sido actualizado — Ecosistema LPDI” | Sin CTA | Avisa al usuario que su correo fue actualizado. | Activo | NO | ✓ | |
| 09 | USUARIO/USER/EXIST/NO-ED/Eliminación de Cuenta/NO-TYC/LPDI | “Tu cuenta en el Ecosistema LPDI ha sido eliminada” | eco.lpdi.co | Confirmación de eliminación voluntaria de cuenta. | Activo | NO | ✓ | |
| 53 | USUARIO/USER/AMBOS/NO-ED/Actualización T&C y Política/NO-TYC/LPDI | “Actualizamos nuestras condiciones y políticas — Ecosistema LPDI” | Enlaces a T&C + Política | Aviso de publicación de versión nueva de los documentos legales (Grupo A, tácita). | Activo | NO | ✓ | |
| 65 | USUARIO/USER/NUEVO/NO-ED/Cuenta Creada/NO-TYC/LPDI | “Tu cuenta fue creada — Ecosistema LPDI” | eco.lpdi.co/login | Aviso al CEO nuevo de que su cuenta quedó activa tras registrarse en el FUS. Sin contraseña (la definió él). Los miembros nuevos cumplen este rol con el correo #20/#21. | Activo | NO | ✓ | |
| STARTUP — Registro, equipo y ciclo de vida de Startups/PyMEs (13) | ||||||||
| 11 | STARTUP/CEO/NUEVO/SI-ED/Bienvenida Registro/SI-TYC/LPDI | “Bienvenido al Ecosistema LPDI — Confirma tu cuenta” | ${confirmUrl} | Bienvenida al registrante de una startup. | Activo | SI | ✓ | |
| 12 | STARTUP/CEO/NUEVO/SI-ED/Bienvenida CEO Designado/SI-TYC/LPDI | “Bienvenido al Ecosistema LPDI — {empresa}” | — | ELIMINADO — Fusionado en #13. Un único correo de designación de CEO, sin contraseña temporal. Los enlaces ya enviados siguen operativos vía /aceptar-designacion. | Eliminado | — | — | |
| 13 | STARTUP/CEO/AMBOS/SI-ED/Designación de CEO (fusionado 12+13)/NO-TYC/LPDI | “Has sido designado CEO de {empresa} en el Ecosistema LPDI” | /team/confirmar?token= | Designación de CEO, tenga o no cuenta. Un solo template, CTA «Revisar designación», sin contraseña temporal. TyC se aceptan en el FUS. | Activo | NO | ✓ | |
| 18 | STARTUP/TEAM/NUEVO/NO-ED/Invitación al Equipo/SI-TYC/LPDI | “{CEO} te ha incluido en el equipo de {empresa} — confirma tu registro” | ${confirmUrl} | Invitación a persona sin cuenta LPDI. | Activo | SI | ✓ | |
| 20 | STARTUP/TEAM/EXIST/SI-ED/Bienvenida con Edición/NO-TYC/LPDI | “Bienvenido al equipo de {empresa} en el Ecosistema LPDI” | eco.lpdi.co/dashboard | Miembro aceptado CON permiso de edición. Sin credenciales. | Activo | NO | ✓ | |
| 21 | STARTUP/TEAM/EXIST/NO-ED/Bienvenida sin Edición/NO-TYC/LPDI | “Bienvenido al equipo de {empresa} en el Ecosistema LPDI” | eco.lpdi.co/dashboard | Miembro aceptado SIN permiso de edición. Sin credenciales. | Activo | NO | ✓ | |
| 22 | STARTUP/TEAM/EXIST/NO-ED/Confirmación de Rechazo/NO-TYC/LPDI | “Confirmación: no haces parte del equipo de {empresa}” | ${confirmAgainUrl} | Confirma rechazo exitoso de invitación. | Activo | NO | ✓ | |
| 23 | STARTUP/CEO/EXIST/SI-ED/Notificación Miembro Aceptó/NO-TYC/LPDI | “{miembro} aceptó la invitación al equipo de {empresa}” | eco.lpdi.co/dashboard | Avisa al equipo que un miembro aceptó. | Activo | NO | ✓ | |
| 24 | STARTUP/CEO/EXIST/SI-ED/Notificación Miembro Rechazó/NO-TYC/LPDI | “{miembro} rechazó la invitación al equipo de {empresa}” | eco.lpdi.co/dashboard | Avisa al equipo que un miembro rechazó. | Activo | NO | ✓ | |
| 25 | STARTUP/TEAM/EXIST/SI-ED/Cambio de Permisos/NO-TYC/LPDI | “Cambio de permisos en {empresa}” | eco.lpdi.co/dashboard | Notifica al miembro cuando el CEO modifica sus permisos. | Activo | NO | ✓ | |
| 14 | STARTUP/CEO/EXIST/SI-ED/Seguimiento de Score/NO-TYC/LPDI | “Aumenta el score de tu perfil en el Ecosistema LPDI” | ${profileUrl} | Recordatorio para completar perfil y subir score. | Activo | NO | ✓ | |
| 66 | STARTUP/TEAM/EXIST/NO-ED/Solicitud de Visibilidad/NO-TYC/LPDI | “Autoriza la visibilidad de tu perfil en el equipo de {empresa}” | /team/visibilidad?token= | A un miembro YA verificado se le pide solo autorizar la visibilidad de su perfil (LinkedIn + género). NO re-verifica el vínculo; el botón abre la pantalla de autorización. | Activo | NO | ✓ | |
| 67 | NUEVO | STARTUP/USER/EXIST/NO-ED/Cambio de CEO (aviso al registrante)/NO-TYC/LPDI | “El CEO de {empresa} ha cambiado” | sin CTA | Avisa al registrante o administrador de la entidad que el cargo de CEO cambió: quién salía, quién entra, quién lo ejecutó y cuándo. El párrafo del CEO anterior cambia según su destino (continúa como miembro / fue retirado del equipo). Informativo, sin botón de acción. | Activo | NO | ✓ |
| 68 | NUEVO | STARTUP/CEO/EXIST/NO-ED/Cambio de CEO (aviso al CEO anterior)/NO-TYC/LPDI | “Tu rol en {empresa} cambió” (destino miembro) · “Tu vínculo con {empresa} finalizó” (destino retirado) | sin CTA | Dos variantes según el destino del CEO saliente. (a) Miembro: deja el cargo y continúa en el equipo; su vínculo verificado y sus autorizaciones de visibilidad NO cambian. (b) Retirado: su vínculo con la compañía terminó; su perfil sale del equipo y sus autorizaciones dentro de ese equipo dejan de aplicar, con constancia en la bitácora. Informativo, sin botón de acción. | Activo | NO | ✓ |
| ICG — Registro y ciclo de vida de ICGs (3) | ||||||||
| 28 | ICG/CON/NUEVO/NO-ED/Vinculación Contacto (fusionado 28+29)/SI-TYC/LPDI | “{ICG} te ha vinculado como contacto en el Ecosistema LPDI” | /icg/confirmar?token= | Contacto designado sin cuenta LPDI. Fusionado: sin contraseña temporal, CTA «Revisar vinculación». TyC en el FUS. | Activo | SI | ✓ | |
| 29 | ICG/CON/EXIST/NO-ED/Vinculación Contacto (fusionado 28+29)/NO-TYC/LPDI | “{ICG} te ha vinculado como contacto en el Ecosistema LPDI” | /icg/confirmar?token= | Mismo template que #28 (rama userExists=true): contacto con cuenta LPDI. CTA «Revisar vinculación». | Activo | NO | ✓ | |
| 55 | ICG/USER/EXIST/NO-ED/Seguimiento de Score/NO-TYC/LPDI | “Aumenta el score de tu perfil en el Ecosistema LPDI” | /dashboard/icg/{id} | Versión ICG del Seguimiento de Score, con barra del semáforo. | Activo | NO | ✓ | |
| ENTIDADES — Correos comunes a Startup e ICG (11) | ||||||||
| 56 | ENTIDAD/USER/NUEVO/NO-ED/Creación de Entidad/NO-TYC/LPDI | “Registraste tu {Startup/ICG} en el Ecosistema LPDI” | deep-link a la entidad | Confirma la creación de la entidad + score inicial con barra del semáforo. | Activo | NO | ✓ | |
| 26 | ENTIDAD/USER/EXIST/NO-ED/Eliminación de Entidad/NO-TYC/LPDI | “El registro de {entidad} ha sido eliminado del Ecosistema LPDI” | ${dashboardUrl} | Notifica a todos los asociados que la entidad fue eliminada. | Activo | NO | ✓ | |
| 27 | ENTIDAD/USER/EXIST/NO-ED/Restauración de Entidad/NO-TYC/LPDI | “{entidad} ha sido restaurado en el Ecosistema LPDI” | ${dashboardUrl} | Notifica restauración desde la papelera. Aplica también a ICG. | Activo | NO | ✓ | |
| 57 | ENTIDAD/RECEPTOR/AMBOS/NO-ED/Invitación de Transferencia/NO-TYC/LPDI | “Te transfieren una entidad — Ecosistema LPDI” | /transferencia/{token} | Invita al receptor a aceptar/rechazar una transferencia (10 días). Nota TYC/PDP si es cuenta nueva. | Activo | NO | ✓ | |
| 58 | ENTIDAD/RECEPTOR/AMBOS/NO-ED/Recordatorio de Transferencia/NO-TYC/LPDI | “Recordatorio: transferencia pendiente — Ecosistema LPDI” | /transferencia/{token} | Recordatorio al receptor (días 3/6/10) de una transferencia pendiente. | Activo | NO | ✓ | |
| 59 | ENTIDAD/RECEPTOR/AMBOS/NO-ED/Transferencia Confirmada/NO-TYC/LPDI | “Transferencia confirmada — Ecosistema LPDI” | /dashboard/perfil-{startup|icg} | Confirma al nuevo responsable que la transferencia se completó. | Activo | NO | ✓ | |
| 60 | ENTIDAD/PROPIETARIO/AMBOS/NO-ED/Transferencia No Completada/NO-TYC/LPDI | “La transferencia no se completó — Ecosistema LPDI” | /dashboard/perfil-{startup|icg} | Avisa al propietario que la transferencia no se completó (vencida/rechazada/cancelada). | Activo | NO | ✓ | |
| 61 | ICG/PROPIETARIO/EXIST/NO-ED/ICG Sin Contacto/NO-TYC/LPDI | “Tu ICG quedó sin persona de contacto — Ecosistema LPDI” | /dashboard/icg/nuevo (FID) | Avisa al propietario del ICG que su contacto cerró la cuenta; CTA a registrar uno nuevo. | Activo | NO | ✓ | |
| 94 | NUEVO | ENTIDAD/USER/EXIST/NO-ED/Recordatorio de Borrador/NO-TYC/LPDI | “Formaliza tu registro en el Ecosistema LPDI” | perfil de la entidad | Recordatorio escalonado (30/60/90/120/150 días) al dueño de un borrador sin formalizar. Cron purge-draft-entities. Nuevo (2026-08-22). | Activo | NO | ✓ |
| 95 | NUEVO | ENTIDAD/USER/EXIST/NO-ED/Aviso de Cierre de Borrador/NO-TYC/LPDI | “Aviso de cierre: formaliza tu registro en {N} días” | perfil de la entidad | Aviso de cierre (15 y 3 días antes de los 180) al dueño de un borrador. Cron purge-draft-entities. Nuevo (2026-08-22). | Activo | NO | ✓ |
| 96 | NUEVO | ENTIDAD/USER/EXIST/NO-ED/Borrador a Papelera/NO-TYC/LPDI | “Tu borrador pasó a la papelera del Ecosistema LPDI” | /dashboard (papelera) | Aviso al dueño del borrador cuando cumple 180 días sin formalizar y pasa a papelera (30 días para restaurar). Cron purge-draft-entities. Nuevo (2026-08-22). | Activo | NO | ✓ |
| 97 | NUEVO | ADMIN/EXIST/NO-ED/Respuesta a Propuesta/NO-TYC/LPDI | “Respuesta a tu propuesta” | /dashboard/admin/propuestas | Respuesta del equipo LPDI al autor de una propuesta, escrita desde el panel de Propuestas de mejora. Botón al ecosistema. Nuevo (2026-09-03). | Activo | NO | ✓ |
| ADMINISTRATIVOS — Reportes automáticos internos (3) | ||||||||
| 31 | CRON/ADMIN/EXIST/NO-ED/Reporte Diario/NO-TYC/LPDI | “Reporte diario Ecosistema LPDI — {fecha}” | CSV adjunto | Cron 6:00 AM Lima — altas + bajas del día diferenciadas: 1) órdenes de baja (gestionables, en papelera con ventana de 30 días) y 2) anonimizados en firme (definitivos). CSV de usuarios y de bajas. Actualizado 2026-08-04. | Activo | NO | ✓ | |
| 89 | ADMIN/EXIST/NO-ED/Ideas y Mejoras/NO-TYC/LPDI | “[categoría] {título de la propuesta}” | soporte@lpdi.co | Usuario envía una propuesta desde el modal «Ideas y mejoras»; adjunta hasta 3 imágenes. Destino configurable vía IDEAS_NOTIFY_EMAIL. Persiste en idea_submissions (panel Admin → Sistema → Propuestas de mejora). Nuevo (2026-08-01). | Activo | NO | ✓ | |
BENEFICIOS (PERKS) · notification-emails.ts (15) | ||||||||
| 32 | FP/ALIADO/Registro Exitoso/NO-TYC/LPDI | “¡Registro exitoso de beneficio!” | /dashboard/beneficios | Al aliado: su beneficio quedó en revisión (al pasar a «enviado»). Funcionando. | Activo | NO | ✓ | |
| 33 | FP/EQUIPO/Nuevo por Aprobar/NO-TYC/LPDI | “Nuevo beneficio por aprobar” | /dashboard/beneficios/admin | Al admin asignado: beneficio nuevo por revisar. Funcionando. | Activo | NO | ✓ | |
| 34 | FP/ALIADO/Aprobado/NO-TYC/LPDI | “¡Beneficio aprobado!” | /perks/{id} | Al aliado: beneficio aprobado y publicado. Funcionando (admin). | Activo | NO | ✓ | |
| 35 | FP/ALIADO/Aprobado Programado/NO-TYC/LPDI | “¡Beneficio aprobado!” | /dashboard/beneficios | Al aliado: aprobado con fecha de publicación futura (F2); el cron publish-scheduled lo activa. Funcionando. | Activo | NO | ✓ | |
| 36 | FP/ALIADO/Actualizado/NO-TYC/LPDI | “¡Beneficio actualizado!” | /perks/{id} | Al aliado: cambios guardados (al editar un publicado → «edición»). Funcionando. | Activo | NO | ✓ | |
| 37 | FP/EQUIPO/Cambios por Aprobar/NO-TYC/LPDI | “Cambios de beneficio por aprobar” | /dashboard/beneficios/admin | Al equipo: un beneficio publicado tiene cambios por revisar (de «edición» → «enviado»). Funcionando. | Activo | NO | ✓ | |
| 38 | FP/ALIADO/Solicitud de Ajustes/NO-TYC/LPDI | “Tu beneficio necesita unos ajustes” | /dashboard/beneficios | Al aliado: el admin pide ajustes (status «cambios», recuperable: ajusta y reenvía). Incluye el detalle. Funcionando. | Activo | NO | ✓ | |
| 39 | FP/ALIADO/No Aceptado/NO-TYC/LPDI | “Beneficio no aceptado” | /dashboard/beneficios | Al aliado: rechazo definitivo desde el panel admin (acción «Rechazar»). El beneficio va a «Eliminados / Rechazados» (borrado a 30 días). | Activo | NO | ✓ | |
| 63 | FP/ALIADO/Cambios Aprobados/NO-TYC/LPDI | “Los cambios de tu beneficio fueron aprobados” | /perks/{id} | Al aliado: el admin aprobó los cambios a un beneficio ya publicado; entran al catálogo. | Activo | NO | ✓ | |
| 64 | FP/ALIADO/Cambios No Aprobados/NO-TYC/LPDI | “Los cambios de tu beneficio no fueron aprobados” | /perks/{id} | Al aliado: el admin rechazó los cambios; el beneficio sigue publicado como estaba. | Activo | NO | ✓ | |
| 40 | FP/ALIADO/Terminado/NO-TYC/LPDI | “Beneficio terminado” | /dashboard/beneficios | Al aliado: beneficio cerrado (manual o por vigencia). Funcionando (admin desactivar). | Activo | NO | ✓ | |
| 41 | FP/ALIADO/Eliminado/NO-TYC/LPDI | “Beneficio eliminado” | /dashboard/beneficios | Al aliado: beneficio eliminado (enviado a papelera). Funcionando. | Activo | NO | ✓ | |
| 42 | FP/ALIADO/Registro en Beneficio/NO-TYC/LPDI | “¡Nuevo registro en tu beneficio!” | /dashboard/beneficios/referidos | Al aliado (cc partners@lpdi.co): un usuario se registró en su beneficio, con sus datos y el tipo de registro. Funcionando. | Activo | NO | ✓ | |
| 69 | FP/LPDI/Solicitud de Alianza/NO-TYC/LPDI | “Nueva solicitud de alianza — [nombre]” | partners@lpdi.co | Al equipo LPDI: solicitud «Quiero ser aliado» con los datos del usuario y de la entidad en dos secciones. Funcionando. Nuevo (2026-07-23). | Activo | NO | ✓ | |
| 70 | FP/USUARIO/Solicitud de Alianza/NO-TYC/USUARIO | “Recibimos tu solicitud de alianza” | /agenda30min | Al usuario solicitante: acuse de recibo distinto del interno, con CTA para agendar una reunión. Funcionando. Nuevo (2026-07-23). | Activo | NO | ✓ | |
| 54 | FP/USUARIO/Solicitud recibida/NO-TYC/LPDI | “Recibimos tu solicitud — Ecosistema LPDI” | eco.lpdi.co | Al usuario (cc partners@lpdi.co): confirma que su solicitud de beneficio fue enviada al aliado + tipología. Funcionando. | Activo | NO | ✓ | |
| 86 | FP/PROSPECTO/Referido a LPDI/NO-TYC/PROSPECTO | “Una recomendación para conectar con La Punta del Iceberg” | /registro-usuario | Al prospecto: referido comercial (no invitación). Un miembro lo recomendó con LPDI para construir sinergias; LPDI lo contactará en los próximos días. CTA para crear cuenta. Funcionando. Nuevo (2026-07-30). | Activo | NO | ✓ | |
| 87 | FP/REFERENTE/Acuse Referido/NO-TYC/USUARIO | “Recibimos tu recomendación — Ecosistema LPDI” | /dashboard/beneficios/referidos | Al referente: acuse de que su recomendación a LPDI quedó registrada. Funcionando. Nuevo (2026-07-30). | Activo | NO | ✓ | |
| 88 | FP/LPDI/Nuevo Prospecto Referido/NO-TYC/LPDI | “Nuevo prospecto referido a La Punta del Iceberg” | partners@lpdi.co | Al equipo LPDI: ficha del prospecto (nombre, correo, teléfono, empresa, estado; si ya existe: cargo, LinkedIn, web) y del referente (nombre, correo, teléfono, empresa, cargo, LinkedIn). Responder-a al referente. Funcionando. Nuevo (2026-07-30). | Activo | NO | ✓ | |
EVENTOS · notification-emails.ts (10) | ||||||||
| 43 | FE/ORGANIZADOR/Registro Exitoso/NO-TYC/LPDI | “¡Registro exitoso de evento!” | /dashboard | Al organizador: evento registrado y en revisión (incluye código). Funcionando. | Activo | NO | ✓ | |
| 44 | FE/EQUIPO/Nuevo por Aprobar/NO-TYC/LPDI | “Nuevo evento por aprobar” | /dashboard | Al admin asignado: evento nuevo por revisar. Funcionando. | Activo | NO | ✓ | |
| 45 | FE/ORGANIZADOR/Aprobado/NO-TYC/LPDI | “¡Evento aprobado!” | /dashboard | Al organizador: evento aprobado. Funcionando. | Activo | NO | ✓ | |
| 46 | FE/ORGANIZADOR/Aprobado Programado/NO-TYC/LPDI | “¡Evento aprobado!” | /dashboard | Al organizador: aprobado con fecha de publicación futura (F2). Funcionando. | Activo | NO | ✓ | |
| 47 | FE/ORGANIZADOR/Actualizado/NO-TYC/LPDI | “¡Evento actualizado!” | /dashboard | Al organizador: su evento publicado fue actualizado. Funcionando. | Activo | NO | ✓ | |
| 48 | FE/EQUIPO/Cambios por Aprobar/NO-TYC/LPDI | “Cambios de evento por aprobar” | /dashboard | Al equipo: un editor que no es de confianza editó un evento ya aprobado; los cambios pasan a revisión. Cableado 2026-07-07. | Activo | NO | ✓ | |
| 49 | FE/ORGANIZADOR/No Aceptado/NO-TYC/LPDI | “Evento no aceptado” | /dashboard | Al organizador: evento no aceptado. Funcionando. | Activo | NO | ✓ | |
| 50 | FE/ORGANIZADOR/Eliminado/NO-TYC/LPDI | “Evento eliminado” | /dashboard | Al organizador: evento eliminado. Funcionando. | Activo | NO | ✓ | |
| 51 | FE/ORGANIZADOR/Publicación Automática/NO-TYC/LPDI | “¡Publicación automática de evento!” | /dashboard | Al organizador (cc admin): evento publicado automáticamente por privilegio de auto-publicación (F6). Funcionando. | Activo | NO | ✓ | |
| 52 | FE/ORGANIZADOR/Solicitud de Ajustes/NO-TYC/LPDI | “Tu evento necesita unos ajustes” | /dashboard | Al organizador (cc al admin que la envía): el admin pide ajustes a un evento, con el detalle. Espejo del #38 de FP. Funcionando. | Activo | NO | ✓ | |
| 80 | NUEVO | FE/ORGANIZADOR/Invitación al Ecosistema/NO-TYC/LPDI | “Te invitaron a registrarte — Ecosistema LPDI” | /registro-usuario | A un coorganizador de un evento SIN entidad registrada: crear cuenta y registrar su entidad para figurar en el directorio. | Activo | NO | ✓ |
| 81 | NUEVO | FE/ORGANIZADOR/Recordatorio Invitación/NO-TYC/LPDI | “Recordatorio: te invitaron a registrarte — Ecosistema LPDI” | /registro-usuario | Recordatorio (cron ~3 días) de la invitación al organizador no registrado. | Activo | NO | ✓ |
| 82 | NUEVO | FE/SPEAKER/Invitación al Ecosistema/NO-TYC/LPDI | “Te invitaron como speaker — Ecosistema LPDI” | /registro-usuario | A un speaker no registrado de un evento: crear cuenta para confirmar su participación y aparecer con el distintivo. | Activo | NO | ✓ |
| 83 | NUEVO | FE/HOST/Invitación al Ecosistema/NO-TYC/LPDI | “Te invitaron como host — Ecosistema LPDI” | /registro-usuario | A un host no registrado de un evento: crear cuenta para confirmar su participación y aparecer con el distintivo. | Activo | NO | ✓ |
| 84 | NUEVO | FE/SPEAKER/Recordatorio Invitación/NO-TYC/LPDI | “Recordatorio: te invitaron como speaker — Ecosistema LPDI” | /registro-usuario | Recordatorio (cron ~3 días) al speaker no registrado. | Activo | NO | ✓ |
| 85 | NUEVO | FE/HOST/Recordatorio Invitación/NO-TYC/LPDI | “Recordatorio: te invitaron como host — Ecosistema LPDI” | /registro-usuario | Recordatorio (cron ~3 días) al host no registrado. | Activo | NO | ✓ |
SCOUTING · Convocatorias y postulaciones (migración 190) · notification-emails.ts (4) | ||||||||
| 90 | NUEVO | SCOUT/APLICANTE/Confirmación Postulación/NO-TYC/LPDI | “Recibimos tu postulación en {convocatoria}” | /dashboard/convocatorias/mis-aplicaciones | A la startup que se postula: confirma el registro de la postulación con fecha y hora con GMT, más el resumen de campos enviados. Siempre se envía. Nuevo (2026-08-22, copy sincronizado 2026-08-24). | Activo | NO | ✓ |
| 91 | NUEVO | SCOUT/ORGANIZADOR/Nueva Postulación o Resumen/NO-TYC/LPDI | “Nueva postulación” / “Resumen de postulaciones” | /dashboard/postulaciones (con acceso) | Al organizador (correo de Notificaciones de la convocatoria): postulación inmediata o resumen diario/semanal/al cierre con las postulaciones numeradas de la más reciente a la más antigua. El botón es «Ver postulaciones» (al panel) si el destinatario tiene acceso, o «Ver convocatoria» (al formulario público /scouting/{slug}) si no. Solo si el aviso está activo. Actualizado 2026-09-03. | Activo | NO | ✓ |
| 92 | NUEVO | SCOUT/ENTIDAD-ORGANIZADOR/Retiro de Postulación/NO-TYC/LPDI | “Se retiró la postulación de {startup}...” | /dashboard | Al retirar una postulación: siempre al admin/CEO de la entidad (botón «Aplicar de nuevo»); al convocante solo si tiene activo el aviso de retiros (botón «Mis campañas»). Nuevo (2026-08-22, copy sincronizado 2026-08-24). | Activo | NO | ✓ |
| 93 | NUEVO | SCOUT/ORGANIZADOR-NO-REGISTRADO/Invitación/NO-TYC/LPDI | “Fuiste designado para recibir notificaciones de {convocatoria}” | /auth/verificar | Al correo designado en Notificaciones que aún no tiene cuenta: se le crea, se le dice quién lo designó y se le invita a activarla. Nuevo (2026-08-22, copy sincronizado 2026-08-24). | Activo | NO | ✓ |
ASOCIACIÓN DE ENTIDADES (Tarea 67) · email-join-requests.ts (9) | ||||||||
| 71 | ASOC/SOLICITANTE/Solicitud Enviada | “Tu solicitud fue enviada” | /api/entidades/solicitudes | Acuse al solicitante: su solicitud de asociación fue enviada a los administradores de la entidad; vigencia 10 días. | Activo | NO | ✓ | |
| 72 | ASOC/APROBADOR/Nueva Solicitud | “Nueva solicitud de asociación” | /api/entidades/solicitudes | A quienes administran la entidad: alguien pidió asociarse; enlace a revisar en el panel (PS/PI) para aceptar con cargo y permisos. | Activo | NO | ✓ | |
| 73 | ASOC/APROBADOR/Recordatorio | “Recordatorio: solicitud pendiente” | /api/entidades/solicitudes | Recordatorio al aprobador: la solicitud sigue pendiente y vence pronto. | Activo | NO | ✓ | |
| 74 | ASOC/SOLICITANTE/Aprobada | “Ya haces parte de [entidad]” | /api/entidades/solicitudes | Al solicitante: su solicitud fue aprobada (con su cargo) y ya quedó asociado a la entidad. | Activo | NO | ✓ | |
| 75 | ASOC/APROBADOR/Aprobada | “Solicitud aprobada” | /api/entidades/solicitudes | Constancia al aprobador de que aprobó la solicitud y el miembro quedó registrado. | Activo | NO | ✓ | |
| 76 | ASOC/SOLICITANTE/Rechazada | “Sobre tu solicitud de asociación” | /api/entidades/solicitudes | Al solicitante: su solicitud no fue aprobada (sin exponer quién rechazó). | Activo | NO | ✓ | |
| 77 | ASOC/APROBADOR/Rechazada | “Solicitud rechazada” | /api/entidades/solicitudes | Constancia al aprobador del rechazo; sin cambios en la entidad. | Activo | NO | ✓ | |
| 78 | ASOC/SOLICITANTE/Expirada | “Tu solicitud venció sin respuesta” | /api/entidades/solicitudes | Al solicitante: la solicitud venció a los 10 días sin respuesta; puede reintentar o crear su entidad. | Activo | NO | ✓ | |
| 79 | ASOC/APROBADOR/Expirada | “Solicitud vencida” | /api/entidades/solicitudes | Constancia informativa al aprobador de que la solicitud venció sin respuesta. | Activo | NO | ✓ | |
| CORREOS ELIMINADOS — consolidados o retirados del sistema (3) | ||||||||
| 17 | ELIMINADO | Expiración de Registro (Startup) — No se obliga a confirmar la creación de una startup. | ||||||
| 19 | ELIMINADO | Invitación al Equipo (usuario existente) — Consolidado en #18 — mismo template (buildTeamInvitationHtml), las dos ramas (usuario nuevo / usuario existente) las maneja el flag userExists. | ||||||
| 30 | ELIMINADO | Expiración de Registro ICG — No se obliga a confirmar la creación de un ICG. | ||||||
| Nombre técnico | USUARIO/USER/NUEVO/NO-ED/Confirmación de Correo/NO-TYC/SUPA |
| Función en código | Supabase Auth — Confirm signup template |
| Asunto | “Confirma tu cuenta en el Ecosistema LPDI” |
| Trigger | Supabase Auth dispara tras signup o signInWithOtp |
| Destinatario | Email del usuario nuevo |
| CTA | Botón: “Confirmar mi cuenta” Destino: {{ .ConfirmationURL }} → redirige a https://eco.lpdi.co/ (SITE_URL con token de confirmación) |
| Descripción | Correo automático de Supabase para verificar que el email es válido al crear una cuenta nueva. El diseño usa el template personalizado configurado en el dashboard de Supabase con branding LPDI. |
| TyC / Tratamiento | NO — Los TyC se aceptan en el formulario de la aplicación ANTES de que Supabase envíe este correo. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/NUEVO/NO-ED/Recordatorio día 3/NO-TYC/LPDI |
| Función en código | lpdi-confirmation-cron.py (modo reminder, plantilla branded día 3) |
| Asunto | “Recordatorio: confirma tu cuenta en el Ecosistema LPDI” |
| Trigger | Cron de verificación (Opción B) en Hetzner — día 3 sin verificar el correo. Activo desde 2026-07-06 (crontab 45 10 * * *). |
| Destinatario | Cualquier cuenta con el correo sin verificar (profiles.email_verified_at IS NULL), sea usuario individual, de startup o de ICG. Se excluyen las cuentas de prueba. No es exclusivo de startups. |
| CTA | Botón: “Confirmar mi cuenta” Destino: ${confirmUrl} → URL de confirmación Supabase |
| Descripción | Primer recordatorio amigable si la persona no ha verificado su correo 3 días después del registro. Muestra días restantes. Si verifica antes del día 6, no se envía el correo #16. |
| TyC / Tratamiento | NO — TyC ya fueron aceptados en el registro. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/NUEVO/NO-ED/Recordatorio Urgente día 6/NO-TYC/LPDI |
| Función en código | lpdi-confirmation-cron.py (modo reminder, plantilla branded día 6) |
| Asunto | “Ultimo aviso: confirma tu cuenta en el Ecosistema LPDI” |
| Trigger | Cron de verificación (Opción B) en Hetzner — día 6 sin verificar el correo. Mismo cron que #15. |
| Destinatario | Cualquier cuenta con el correo sin verificar (profiles.email_verified_at IS NULL). Misma lógica que el correo #15. |
| CTA | Botón: “Confirmar mi cuenta” Destino: ${confirmUrl} → URL de confirmación Supabase |
| Descripción | Segundo recordatorio (día 6), más cerca del vencimiento. Mismo diseño que el #15: el cron envía el mismo correo el día 3 y el día 6. Si la persona no verifica, al día 8 el cron marca la cuenta account_status=inactive y envía el correo #62 (Cuenta Inactivada), con 30 días de gracia para reactivarla verificando. |
| TyC / Tratamiento | NO — TyC ya aceptados en registro. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Cuenta Inactivada/NO-TYC/LPDI |
| Asunto | “Tu cuenta fue inactivada — confírmala para reactivarla” |
| Trigger | Ciclo de verificación (Opción B): al día 8 sin verificar el correo, el cron marca la cuenta account_status=inactive y programa borrado a 30 días. |
| Descripción | Avisa que la cuenta quedó inactivada por no verificar el correo y que tiene 30 días de gracia para reactivarla verificando (enlace magiclink → /auth/verificar). |
| Envío | Cron DB-direct lpdi-confirmation-cron.py (Hetzner, diario), vía Resend. Activo. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/NUEVO/NO-ED/Invitación Admin/NO-TYC/SUPA |
| Función en código | Supabase Auth — Invite template |
| Asunto | “Has sido invitado al Ecosistema LPDI” |
| Trigger | Admin invita usuario desde Supabase Dashboard vía inviteUserByEmail() |
| Destinatario | Email del usuario invitado por admin |
| CTA | Botón: “Aceptar invitación” Destino: {{ .ConfirmationURL }} → redirige a https://eco.lpdi.co/ (SITE_URL) |
| Descripción | Template de invitación directa. Actualmente NO se usa en el flujo normal del sistema (las invitaciones de equipo van por correos #14/#15 del sistema LPDI). Disponible para invitaciones manuales desde el dashboard de Supabase. |
| TyC / Tratamiento | NO — TyC se validan en la aplicación al llegar. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/NUEVO/NO-ED/Magic Link/NO-TYC/SUPA |
| Función en código | Supabase Auth — Magic link template |
| Asunto | “Tu enlace de acceso — Ecosistema LPDI” |
| Trigger | Admin invita usuario vía supabase.auth.admin.inviteUserByEmail() |
| Destinatario | Email del usuario invitado |
| CTA | Botón: “Iniciar sesión” Destino: {{ .ConfirmationURL }} → redirige a https://eco.lpdi.co/ (SITE_URL) |
| Descripción | Enlace mágico para acceso directo sin contraseña. Actualmente NO se usa en el flujo principal (las invitaciones van por correos #14/#15). Reservado para invitaciones administrativas manuales. |
| TyC / Tratamiento | NO — TyC deberían validarse en la aplicación al llegar. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Reautenticación OTP/NO-TYC/SUPA |
| Función en código | Supabase Auth — Reauthentication template |
| Asunto | “Código de verificación — Ecosistema LPDI” |
| Trigger | Usuario intenta una acción que requiere reautenticación (ej: cambio de contraseña, eliminación de cuenta) |
| Destinatario | Email del usuario |
| CTA | Sin botón CTA — muestra código OTP {{ .Token }} en el cuerpo del correo |
| Descripción | Envía un código numérico de verificación para acciones sensibles. El usuario debe ingresar el código en la aplicación para continuar. |
| TyC / Tratamiento | NO — Es verificación de identidad para seguridad. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Recuperación de Contraseña/NO-TYC/SUPA |
| Función en código | Supabase Auth — Reset password template |
| Asunto | “Restablece tu contraseña — Ecosistema LPDI” |
| Trigger | Usuario solicita reset de contraseña vía /auth/reset |
| Destinatario | Email del usuario |
| CTA | Botón: “Restablecer mi contraseña” Destino: https://eco.lpdi.co/auth/recuperar?token_hash=...&type=recovery |
| Descripción | Permite al usuario restablecer su contraseña mediante un enlace seguro con expiración (por defecto 24h). Template personalizado con branding LPDI. |
| TyC / Tratamiento | NO — Acción de seguridad/recuperación. No requiere aceptación. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Contraseña Actualizada/NO-TYC/LPDI |
| Función en código | sendPasswordChangedEmail |
| Asunto | “Tu contraseña ha sido actualizada — Ecosistema LPDI” |
| Trigger | Usuario cambia su contraseña exitosamente desde el sistema LPDI |
| Destinatario | Email del usuario |
| CTA | Botón: “Restablecer contraseña” (emergencia) Destino: https://eco.lpdi.co/auth/recuperar (hardcoded) |
| Descripción | Notificación enviada por el sistema LPDI (no Supabase) que confirma al usuario que su contraseña fue actualizada. Complementa al correo #08 de Supabase. |
| TyC / Tratamiento | NO — Correo informativo de seguridad. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Notificación Contraseña Cambiada/NO-TYC/SUPA |
| Función en código | Supabase Auth — Password changed notification |
| Asunto | “Tu contraseña ha sido cambiada — Ecosistema LPDI” |
| Trigger | Supabase detecta que la contraseña del usuario fue cambiada |
| Destinatario | Email del usuario |
| CTA | Sin CTA — correo informativo (notificación de seguridad) |
| Descripción | Notificación automática de seguridad enviada por Supabase cuando se detecta un cambio de contraseña. Diferente al correo #10 que es enviado por el sistema LPDI. |
| TyC / Tratamiento | NO — Correo informativo de seguridad. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Cambio de Correo/NO-TYC/SUPA |
| Función en código | Supabase Auth — Change email template |
| Asunto | “Confirma el cambio de correo — Ecosistema LPDI” |
| Trigger | Usuario cambia su email desde configuración de cuenta |
| Destinatario | Email nuevo del usuario |
| CTA | Botón: “Confirmar cambio de correo” Destino: {{ .ConfirmationURL }} → redirige a https://eco.lpdi.co/ (SITE_URL) |
| Descripción | Verificación del nuevo correo cuando el usuario actualiza su dirección de email. El email anterior sigue activo hasta que se confirme el nuevo. |
| TyC / Tratamiento | NO — Verificación de identidad. No requiere nueva aceptación. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Notificación Correo Cambiado/NO-TYC/SUPA |
| Función en código | Supabase Auth — Email changed notification |
| Asunto | “Tu correo electrónico ha sido actualizado — Ecosistema LPDI” |
| Trigger | Supabase detecta que el email del usuario fue cambiado exitosamente |
| Destinatario | Email anterior del usuario (el que se reemplazó) |
| CTA | Sin CTA — correo informativo (notificación de seguridad) |
| Descripción | Notificación automática de seguridad enviada al email ANTERIOR cuando el usuario cambia su dirección. Permite al usuario detectar cambios no autorizados. |
| TyC / Tratamiento | NO — Correo informativo de seguridad. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/EXIST/NO-ED/Eliminación de Cuenta/NO-TYC/LPDI |
| Función en código | sendAccountDeletedEmail |
| Asunto | “Tu cuenta en el Ecosistema LPDI ha sido eliminada” |
| Trigger | Usuario elimina su cuenta desde /api/account/delete |
| Destinatario | Email del usuario que eliminó su cuenta |
| CTA | Botón: “Registrarme de nuevo” Destino: https://eco.lpdi.co (hardcoded) |
| Descripción | Confirmación de que la cuenta fue eliminada voluntariamente. Los datos se marcan para eliminación. Si desea volver, debe registrarse de nuevo. |
| TyC / Tratamiento | NO — Correo informativo. Si se re-registra, se pedirán TyC nuevamente. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/AMBOS/NO-ED/Actualización T&C y Política/NO-TYC/LPDI |
| Función en código | sendAccountUpdateNotificationEmail |
| Asunto | “Actualizamos nuestras condiciones y políticas — Ecosistema LPDI” |
| Trigger | Publicación de una versión nueva de T&C / Política de Datos (cutover del lifecycle) |
| Destinatario | Usuarios con aceptación válida previa (Grupo A) — aceptación tácita por uso continuado |
| CTA | Enlaces a los documentos actualizados (T&C + Política). Sin botón de acción. |
| Descripción | Informa la publicación de una versión nueva de los documentos legales. Reutilizable: parámetros changes / termsUrl / privacyUrl para futuras actualizaciones. El Grupo B (nunca aceptó válidamente, <25-may) NO recibe tácita: va por casilla expresa al próximo login. |
| TyC / Tratamiento | SÍ (informativo) — Aceptación TÁCITA por uso continuado; no incluye casilla. Aprobado por Frank 2026-07-02. |
PREVIEW DEL CORREO
| Nombre técnico | USUARIO/USER/NUEVO/NO-ED/Cuenta Creada/NO-TYC/LPDI |
| Función en código | buildAccountCreatedNotificationHtml / sendAccountCreatedNotificationEmail |
| Asunto | “Tu cuenta fue creada — Ecosistema LPDI” |
| Trigger | Un CEO designado sin cuenta previa completa su registro en el FUS (/registro-usuario) tras aceptar la designación. Sustituye al aviso de credenciales del antiguo correo #12. |
| Destinatario | Email del CEO recién registrado |
| CTA | Botón: “Iniciar sesión” Destino: https://eco.lpdi.co/login |
| Descripción | Aviso breve de que la cuenta quedó activa. Sin contraseña: la persona la definió ella misma en el FUS. Los miembros nuevos no reciben este correo; su bienvenida #20/#21 ya cumple ese rol (para no mandar dos correos al mismo buzón en el mismo flujo). |
| TyC / Tratamiento | NO — Los TyC ya se aceptaron en el FUS al crear la cuenta. |
PREVIEW DEL CORREO (regenerado 2026-07-17 desde buildAccountCreatedNotificationHtml)
| Nombre técnico | STARTUP/CEO/NUEVO/SI-ED/Bienvenida Registro/SI-TYC/LPDI |
| Función en código | sendStartupWelcomeEmail |
| Asunto | “Bienvenido al Ecosistema LPDI — Confirma tu cuenta” |
| Trigger | Registro de startup en /registro-startup (formulario completado) |
| Destinatario | Email del CEO que registra la startup |
| CTA | Botón: “Confirmar mi cuenta y ver mi registro” Destino: ${confirmUrl} → URL de confirmación Supabase (redirige a SITE_URL) |
| Descripción | Correo de bienvenida al registrante de una startup. La startup queda en estado “pendiente” hasta que el CEO confirme. Si no confirma en 7 días, se activan los correos #15, #16 y eventualmente #17. |
| TyC / Tratamiento | SÍ — El formulario de registro (/registro-startup) tiene checkbox obligatorio de TyC y Política de Tratamiento de Datos ANTES de enviar. El consent se graba en consent_log con flow=“FS”. |
PREVIEW DEL CORREO
| Estado | ELIMINADO — Fusionado en #13. |
| Razón | La designación de CEO ya no crea cuenta ni contraseña temporal: el correo #13 pasó a ser un único template que se envía tenga o no cuenta el CEO. El CTA «Revisar designación» lleva a /team/confirmar; el usuario nuevo crea su cuenta y acepta TyC en el FUS (/registro-usuario). Mantener un correo aparte «con credenciales» para el CEO sin cuenta quedó sin sentido. |
| Enlaces en vuelo | Los correos 12/13 ya enviados siguen operativos: sus enlaces magiclink resuelven vía /aceptar-designacion (ruta legacy viva, sin sellar visibilidad automáticamente). El flujo nuevo deja de generarlos. |
| Dónde queda documentado | El correo de designación de CEO, ahora único, se describe en #13. |
| Nombre técnico | STARTUP/CEO/AMBOS/SI-ED/Designación de CEO/NO-TYC/LPDI |
| Función en código | buildCeoWelcomeHtml / sendCeoWelcomeEmail — un solo template (sin rama userExists) |
| Asunto | “Has sido designado CEO de {empresa} en el Ecosistema LPDI” |
| Trigger | Se designa un CEO (registro de startup FS/FD o Panel 6), tenga o no cuenta previa. Absorbe al antiguo correo #12. |
| Destinatario | Email del CEO designado |
| CTA | Botón único: “Revisar designación” Destino: ${originUrl}/team/confirmar?token=${token} |
| Descripción | Notifica al CEO que {designatorName} lo designó CEO de la empresa. Sin contraseña temporal y sin rama usuario nuevo/existente: la pantalla /team/confirmar resuelve la diferencia (usuario nuevo va al FUS a crear su cuenta; usuario existente confirma y va a login). El pie remite al correo corporativo de la empresa para dudas. |
| TyC / Tratamiento | NO en el correo — Los TyC y el Tratamiento de Datos se aceptan en el FUS (/registro-usuario) cuando el usuario nuevo crea su cuenta con su propia contraseña. El usuario existente ya los aceptó. |
PREVIEW DEL CORREO (regenerado 2026-07-18 desde buildCeoWelcomeHtml)
PANTALLA QUE ABRE EL BOTÓN — “Revisar designación” → /team/confirmar?token= (variante CEO)
| Nombre técnico | STARTUP/TEAM/NUEVO/NO-ED/Invitación al Equipo/SI-TYC/LPDI · STARTUP/TEAM/EXIST/NO-ED/Invitación al Equipo/NO-TYC/LPDI |
| Función en código | buildTeamInvitationHtml / sendTeamInvitationEmail (un template, paramía por userExists + canEdit + addedByName) |
| Asunto | “{Nombre de quien agrega} te ha incluido en el equipo de {empresa} — confirma tu registro” |
| Trigger | Un miembro con privilegio de edición agrega miembro en Panel 6 (Equipo). El template se ejecuta sea cual sea el estado del invitado: usuario nuevo o existente. |
| Destinatario | Email del miembro invitado (ingresado por quien tiene privilegio de edición) |
| CTA | Botón único (azul): “Revisar vinculación” Destino: ${confirmUrl} → /team/confirmar. El correo ya no decide (se quitó el botón de rechazo ${rejectUrl}): solo lleva a la pantalla donde se acepta o rechaza y se marca la casilla de visibilidad. |
| Descripción | Invitación a unirse al equipo de una startup. Muestra tabla con datos registrados (nombre, email, cargo, permiso de edición asignado). El bloque de TyC solo aparece cuando el invitado aún no tiene cuenta LPDI. |
| Variantes | 4 variantes por cruce de 2 ejes: usuario nuevo/existente × con/sin permiso de edición. (a) Nuevo + CON edición: Persona sin cuenta LPDI, con permiso de editar. Al confirmar, se le piden TyC y Tratamiento de Datos (checkboxes obligatorios en pantalla de confirmación). El consent se graba en consent_log con flow=“team_invitation”.(b) Nuevo + SIN edición: Persona sin cuenta LPDI, solo lectura. Misma lógica de TyC que variante (a). (c) Existente + CON edición: Persona con cuenta LPDI activa + permiso de editar. NO se piden TyC (ya los aceptó previamente). Solo confirma vinculación. (d) Existente + SIN edición: Persona con cuenta LPDI activa, solo lectura. NO se piden TyC. Solo confirma vinculación. |
| TyC / Tratamiento | Variantes (a) y (b) — SÍ (usuario nuevo, acepta en pantalla de confirmación) · Variantes (c) y (d) — NO (usuario existente, ya tiene consent previo) |
can_edit_form=true) puede agregar a otro miembro al equipo. El privilegio que se asigna al invitado (SI-ED o NO-ED) lo decide quien crea la invitación al momento de capturar el miembro./team/confirmar, donde aparecen (o no) los checkboxes según si el usuario ya tiene cuenta.PREVIEW — Variante (a) Nuevo + CON edición
PREVIEW — Variante (b) Nuevo + SIN edición
PREVIEW — Variante (c) Existente + CON edición
PREVIEW — Variante (d) Existente + SIN edición
PANTALLA QUE ABRE EL BOTÓN — “Revisar vinculación” → /team/confirmar?token= (variante miembro)
| Nombre técnico | STARTUP/TEAM/EXIST/SI-ED/Bienvenida con Edición/NO-TYC/LPDI |
| Función en código | sendTeamWelcomeWithEditEmail |
| Asunto | “Bienvenido al equipo de {empresa} en el Ecosistema LPDI” |
| Trigger | Miembro hace clic en “Confirmar mi vinculación” + tiene canEdit=true |
| Destinatario | Email del miembro que confirmó su vinculación |
| CTA | Botón: “Ir al dashboard” Destino: eco.lpdi.co/dashboard |
| Descripción | Confirma al miembro que fue aceptado en el equipo CON permiso de edición. Ninguna variante lleva credenciales: el usuario existente usa su contraseña y el usuario nuevo (creado en el FUS) ya definió la suya — solo se le informa «Tu cuenta fue creada. Inicia sesión con el correo y la contraseña que definiste». Nota: “tu CEO te otorgó permisos para editar”. |
| TyC / Tratamiento | NO — TyC ya fueron aceptados en el correo de invitación (#18) o en su registro original. |
PREVIEW DEL CORREO
| Nombre técnico | STARTUP/TEAM/EXIST/NO-ED/Bienvenida sin Edición/NO-TYC/LPDI |
| Función en código | sendTeamWelcomeNoEditEmail |
| Asunto | “Bienvenido al equipo de {empresa} en el Ecosistema LPDI” |
| Trigger | Miembro confirma vinculación + tiene canEdit=false |
| Destinatario | Email del miembro que confirmó su vinculación |
| CTA | Botón: “Ir al dashboard” Destino: eco.lpdi.co/dashboard |
| Descripción | Confirma al miembro que fue aceptado en el equipo SIN permiso de edición. Solo puede ver información, no modificarla. Ninguna variante lleva credenciales: usuario existente usa su contraseña; usuario nuevo (FUS) ya definió la suya y solo recibe el aviso «Tu cuenta fue creada». |
| TyC / Tratamiento | NO — Mismo caso que correo #20. TyC ya aceptados previamente. |
PREVIEW DEL CORREO
| Nombre técnico | STARTUP/TEAM/EXIST/NO-ED/Confirmación de Rechazo/NO-TYC/LPDI |
| Función en código | sendTeamRejectionConfirmationEmail |
| Asunto | “Confirmación: no haces parte del equipo de {empresa}” |
| Trigger | Miembro hace clic en “No hago parte de la compañía” desde correo #18 o #19 |
| Destinatario | Email del miembro que rechazó la invitación |
| CTA | Botón condicional: “Confirmar mi vinculación” (si fue error) Destino: ${confirmAgainUrl} (condicional, puede ser null → sin CTA) |
| Descripción | Confirma al miembro que rechazó exitosamente la invitación. Si fue un error, puede contactar al CEO para que lo vuelva a invitar. |
| TyC / Tratamiento | NO — Correo informativo de confirmación de rechazo. |
PREVIEW DEL CORREO
| Nombre técnico | STARTUP/CEO/EXIST/SI-ED/Notificación Miembro Aceptó/NO-TYC/LPDI |
| Función en código | sendCeoMemberConfirmationEmail |
| Asunto | “{miembro} aceptó la invitación al equipo de {empresa}” |
| Trigger | Miembro acepta invitación (hace clic en “Confirmar mi vinculación”) |
| Destinatario | Todos los miembros del equipo de la startup |
| CTA | Botón: “Ir al dashboard” Destino: https://eco.lpdi.co/dashboard (hardcoded) |
| Descripción | Avisa al equipo que un miembro aceptó la invitación. Muestra quién confirmó, su email y los permisos asignados. |
| TyC / Tratamiento | NO — Correo informativo al CEO. |
PREVIEW DEL CORREO
| Nombre técnico | STARTUP/CEO/EXIST/SI-ED/Notificación Miembro Rechazó/NO-TYC/LPDI |
| Función en código | sendCeoMemberRejectionEmail |
| Asunto | “{miembro} rechazó la invitación al equipo de {empresa}” |
| Trigger | Miembro rechaza invitación (hace clic en “No hago parte de la compañía”) |
| Destinatario | Todos los miembros del equipo de la startup |
| CTA | Botón: “Ir al dashboard” Destino: https://eco.lpdi.co/dashboard (hardcoded) |
| Descripción | Avisa al equipo que un miembro rechazó la invitación. Sugiere comunicarse con la persona si fue un error. |
| TyC / Tratamiento | NO — Correo informativo al CEO. |
PREVIEW DEL CORREO
| Nombre técnico | STARTUP/TEAM/EXIST/SI-ED/Cambio de Permisos/NO-TYC/LPDI |
| Función en código | sendPermissionChangeEmail |
| Asunto | “Cambio de permisos en {empresa}” |
| Trigger | Cualquier usuario con permisos de edición modifica los permisos de otro miembro del equipo |
| Destinatario | Email del miembro cuyo permiso cambió |
| CTA | Botón: “Ir al dashboard” Destino: https://eco.lpdi.co/dashboard (hardcoded) |
| Descripción | Notifica al miembro cuando el CEO modifica sus permisos de edición en el equipo (por ejemplo, de solo lectura a edición o viceversa). Detectado en código, no estaba en el reporte v1. |
| TyC / Tratamiento | NO — Correo informativo. |
PREVIEW DEL CORREO
| Nombre técnico | STARTUP/CEO/EXIST/SI-ED/Seguimiento de Score/NO-TYC/LPDI |
| Función en código | sendStartupFollowupEmail |
| Asunto | “Aumenta el score de tu perfil en el Ecosistema LPDI” |
| Trigger | Cron pg_cron horario → POST /api/cron/startup-followup. Procesa DOS ventanas por corrida:• Día 2 — startups creadas hace 24–48 h; marca followup_sent_at.• Día 30 — startups creadas hace 720–744 h; marca followup_30d_sent_at.Condiciones por ventana: la marca respectiva en NULL, deleted_at IS NULL y la cuenta registradora con email confirmado. La ventana de día 30 queda inerte hasta aplicar la migración 090 (columna followup_30d_sent_at). |
| Destinatario | Contacto de la startup (contact_email) + miembros de startup_founders con can_edit_form=true y verification_status='verified'. |
| CTA | Botón: “Aumentar mi score” Destino: ${profileUrl} → perfil de la startup en dashboard |
| Descripción | Recordatorio automático para que el equipo complete el perfil de la startup y suba su score de visibilidad. El correo muestra el score actual con la barra del semáforo. Nota: el cron NO filtra por score en la consulta — se envía a toda startup confirmada dentro de la ventana que aún no tenga la marca correspondiente. |
| TyC / Tratamiento | NO — El usuario ya aceptó TyC durante el registro. |
PREVIEW DEL CORREO
| Nombre técnico | STARTUP/TEAM/EXIST/NO-ED/Solicitud de Visibilidad/NO-TYC/LPDI |
| Función en código | buildVisibilityRequestHtml / sendVisibilityRequestEmail (email-team.ts) |
| Asunto | “Autoriza la visibilidad de tu perfil en el equipo de {empresa}” |
| Trigger | A un miembro ya verificado se le pide únicamente que autorice la visibilidad de su perfil. NO re-verifica su vínculo con el equipo (ciclo 2, D5). |
| Destinatario | Email del miembro verificado del equipo de la startup |
| CTA | Botón (verde): “Autorizar visibilidad” Destino: ${visibilityUrl} → /team/visibilidad?token=. La casilla/decisión vive en la pantalla, nunca dentro del botón del correo (DESIGN.md §9). |
| Descripción | Explica que al autorizar, su perfil de LinkedIn y su género serán visibles para los ICG cuando consulten el perfil de la compañía, y enumera qué pierde si no autoriza. Su vínculo con el equipo ya está confirmado; esta autorización es una decisión aparte y voluntaria. |
| TyC / Tratamiento | NO — No re-verifica ni re-acepta TyC. El clic en “Autorizar visibilidad” ES el acto expreso de consentimiento (Ley 1581); no autorizar = no actuar. |
PREVIEW DEL CORREO (regenerado 2026-07-18 desde buildVisibilityRequestHtml)
PANTALLA QUE ABRE EL BOTÓN — “Autorizar visibilidad” → /team/visibilidad?token=
| Nombre técnico | STARTUP/USER/EXIST/NO-ED/Cambio de CEO (aviso al registrante)/NO-TYC/LPDI |
| Función en código | buildCeoChangeAdminHtml / sendCeoChangeAdminEmail (email-team.ts) |
| Asunto | “El CEO de {empresa} ha cambiado” |
| Trigger | Al completarse el cambio de CEO (flujo explícito de designación con aceptación, punto 52). Se envía siempre que el cambio se materializa, incluso si quien lo ejecutó es el propio destinatario: la notificación es evidencia, no cortesía. |
| Destinatario | Registrante o administrador de la entidad. Dedup: si el registrante y el CEO anterior son la misma persona, recibe sólo el #68. |
| CTA | Ninguna. Correo informativo, sin botón de acción. Cierra con la vía de contacto soporte@lpdi.co por si el cambio no corresponde. |
| Descripción | Cuadro con CEO anterior, CEO actual, quién realizó el cambio y fecha; luego explica qué pasó con el CEO anterior según el destino elegido (continúa como miembro con su vínculo intacto, o su vínculo con el equipo se retiró y su perfil sale de la compañía), y que el nuevo CEO pasa a gestionar el perfil de la compañía. En la variante retirada la fila del cuadro dice «CEO anterior (retirado)». Molde visual del correo #13 (logo, franja azul, título navy, footer estándar). |
| TyC / Tratamiento | NO — No re-verifica ni re-acepta TyC. Ley 1581: el correo no otorga ni insinúa visibilidad ante los ICG; esa autorización es siempre expresa y aparte, y no cambia por el cambio de rol. |
PREVIEW DEL CORREO (generado 2026-07-20 desde buildCeoChangeAdminHtml)

VARIANTE «EL CEO SALIENTE SE RETIRA DEL EQUIPO»
| Nombre técnico | STARTUP/CEO/EXIST/NO-ED/Cambio de CEO (aviso al CEO anterior)/NO-TYC/LPDI |
| Función en código | buildCeoChangeFormerCeoHtml / sendCeoChangeFormerCeoEmail (email-team.ts) |
| Asunto | “Tu rol en {empresa} cambió” si el saliente continúa como miembro; “Tu vínculo con {empresa} finalizó” si se retira del equipo. El asunto cambia porque el hecho notificado es otro. |
| Trigger | Al completarse el cambio de CEO, en el mismo paso que el #67. Si no había CEO vinculado anterior, va al correo de la fila degradada; si no había fila alguna, sólo sale el #67. |
| Destinatario | CEO anterior de la startup / PyMe. |
| CTA | Ninguna. Correo informativo, sin botón de acción. Cierra con la vía de contacto soporte@lpdi.co por si el cambio no corresponde. |
| Descripción | Dos variantes según el destino que se eligió para el CEO saliente al designar al nuevo (ampliación del 2026-07-20). (a) Continúa como miembro (opción por defecto): le informa que deja el cargo de CEO y continúa como miembro del equipo. Dice explícitamente que su vínculo verificado y sus autorizaciones de visibilidad no cambian, que sus datos se conservan tal como los registró y que lo único que cambia es su cargo, editable desde el perfil de la compañía. (b) Se retira del equipo: le informa que su vínculo con la compañía terminó, que su perfil ya no aparece en el equipo y que pierde el acceso a la información de la compañía; que las autorizaciones de visibilidad que había dado dentro de ese equipo dejan de aplicar y queda constancia de ellas en el registro de la operación; y que su cuenta personal LPDI sigue activa con sus datos intactos. Nunca afirma que continúa como miembro: eso sería falso. Ambas cierran indicando quién asumió el cargo, quién realizó el cambio y en qué fecha. |
| TyC / Tratamiento | NO — No re-verifica ni re-acepta TyC. Ley 1581: en el destino miembro las columnas de consentimiento de visibilidad no se tocan y el correo lo declara al destinatario. En el destino retirado no se ponen en NULL: desaparece la fila entera del equipo, y su evidencia (fechas de consentimiento y de revocación) queda volcada a la bitácora append-only team_member_unlinked ANTES del borrado, que es la misma vía de cualquier miembro retirado. |
PREVIEW DEL CORREO (generado 2026-07-20 desde buildCeoChangeFormerCeoHtml)

VARIANTE «TE RETIRAS DEL EQUIPO»
| Nombre técnico | ICG/CON/NUEVO/NO-ED/Vinculación Contacto (fusionado 28+29)/SI-TYC/LPDI |
| Función en código | buildIcgContactInvitationHtml / sendIcgContactInvitationEmail (userExists=false) — reemplaza al deprecado sendContactWelcomeEmail |
| Asunto | “{ICG} te ha vinculado como contacto en el Ecosistema LPDI” |
| Trigger | ICG registra contacto de compañía en /registro-icg o /dashboard/icg/nuevo — el contacto NO tiene cuenta LPDI |
| Destinatario | Email de la persona de contacto designada por el ICG |
| CTA | Botón único: “Revisar vinculación” Destino: ${reviewUrl} → /icg/confirmar?token=. La pantalla resuelve la rama: usuario nuevo va al FUS a crear cuenta; usuario existente confirma directo. La cuenta NUNCA se crea en el correo. |
| Descripción | Fusionado (antes 28+29), como el 12+13 del CEO. Un solo template; la única rama es el párrafo del CTA según userExists. Sin contraseña temporal (la cuenta nace en el FUS). Informa qué datos se comparten con el ecosistema (nombres, apellidos, cargo en el ICG y LinkedIn) y que el celular es privado. |
| TyC / Tratamiento | SÍ — Se aceptan en el FUS (/registro-usuario) al crear la cuenta, no en el correo. El usuario existente ya los aceptó. |
PREVIEW DEL CORREO (regenerado 2026-07-18 desde buildIcgContactInvitationHtml, userExists=false)
PANTALLA QUE ABRE EL BOTÓN — “Revisar vinculación” → /icg/confirmar?token=
| Nombre técnico | ICG/CON/EXIST/NO-ED/Vinculación Contacto (fusionado 28+29)/NO-TYC/LPDI |
| Función en código | buildIcgContactInvitationHtml / sendIcgContactInvitationEmail (userExists=true) — mismo template que #28 |
| Asunto | “{ICG} te ha vinculado como contacto en el Ecosistema LPDI” |
| Trigger | ICG registra contacto de compañía — el contacto YA tiene cuenta LPDI |
| Destinatario | Email de la persona de contacto designada por el ICG |
| CTA | Botón único: “Revisar vinculación” Destino: ${reviewUrl} → /icg/confirmar?token=. Al ser usuario existente, la pantalla confirma la vinculación sin crear cuenta. |
| Descripción | Rama userExists=true del template fusionado: cambia solo el párrafo del CTA («Ya tienes una cuenta… Revisa la vinculación y decide si aceptas»). Mismo bloque informativo de datos compartidos y celular privado. |
| TyC / Tratamiento | NO — Ya tiene cuenta y aceptó TyC previamente. |
PREVIEW DEL CORREO (regenerado 2026-07-18 desde buildIcgContactInvitationHtml, userExists=true)
PANTALLA QUE ABRE EL BOTÓN — misma pantalla /icg/confirmar?token= (ver #28); para usuario existente el botón confirma sin crear cuenta.
| Nombre técnico | ICG/USER/EXIST/NO-ED/Seguimiento de Score/NO-TYC/LPDI |
| Función en código | sendIcgFollowupEmail |
| Asunto | “Aumenta el score de tu perfil en el Ecosistema LPDI” |
| Trigger | Cron pg_cron horario → POST /api/cron/icg-followup. DOS ventanas por corrida: día 2 (creados hace 24–48 h, marca followup_sent_at) y día 30 (creados hace 720–744 h, marca followup_30d_sent_at), solo con la cuenta dueña confirmada y deleted_at IS NULL. El correo se envía al contact_email del ICG. |
| Destinatario | Contacto/responsable del ICG |
| CTA | Botón: “Completar mi perfil” → deep-link /dashboard/icg/{id} |
| Descripción | Versión ICG del Seguimiento de Score. Muestra el score con la barra del semáforo (rojo/ámbar/verde). Espejo del de startup (#14). |
| Estado | Correo listo; cron codificado con ambas ventanas (día 2 + día 30), INERTE hasta la migración 090 (agrega las columnas followup_sent_at y followup_30d_sent_at a icgs). |
PREVIEW DEL CORREO

sendEntityCreatedEmail para startup e ICG. Para ICG se dispara en registro-icg, dashboard/icg/nuevo y dashboard/icg/nuevo-simplificado.| Nombre técnico | ENTIDAD/USER/NUEVO/NO-ED/Creación de Entidad/NO-TYC/LPDI |
| Función en código | sendEntityCreatedEmail |
| Asunto | “Registraste tu {Startup/ICG} en el Ecosistema LPDI” |
| Trigger | Al crear una entidad, best-effort (no bloqueante), en TODAS las vías de registro: • Startup: registro-startup, dashboard/startups/nuevo, dashboard/startups/nuevo-detallado.• ICG: registro-icg, dashboard/icg/nuevo, dashboard/icg/nuevo-simplificado. |
| Destinatario | Usuario que registró la entidad |
| CTA | Botón: “Completar mi perfil” → deep-link a la entidad (/dashboard/startups/{id} o /dashboard/icg/{id}) |
| Variantes | 2: Startup e ICG (mismo diseño, label dinámico) |
| Descripción | Confirma que la entidad se creó correctamente + muestra el score inicial con la barra del semáforo. Motiva a completar el perfil. |
| Estado | Correo listo y CABLEADO — sendEntityCreatedEmail se invoca (best-effort) en las 6 vías de creación de startup e ICG. |
PREVIEW DEL CORREO — 2 variantes
Variante Startup
Variante ICG
| Nombre técnico | ENTIDAD/USER/EXIST/SI-ED/Eliminación de Entidad/NO-TYC/LPDI — aplica a Startup e ICG (función genérica) |
| Función en código | sendEntityDeletedEmail |
| Asunto | “El registro de {entidad} ha sido eliminado del Ecosistema LPDI” |
| Trigger | Usuario elimina startup o ICG desde /api/entities/delete |
| Destinatario | Miembros asociados a la entidad (CEO, equipo, contacto) CON permiso de edición. Miembros SIN edición reciben variante informativa (correo #26b) sin CTA Restaurar. |
| CTA | Botón: “Restaurar” Destino: https://eco.lpdi.co/dashboard (sección papelera) |
| Descripción | Notifica a los miembros con edición que la entidad fue eliminada. Incluye quién dio la orden. Los datos se eliminan permanentemente en 30 días. Miembros sin edición reciben un correo solo informativo con el contacto del responsable. |
| TyC / Tratamiento | NO — Correo informativo. La restauración no requiere nueva aceptación. |
PREVIEW — CON EDICIÓN (CTA Restaurar)
PREVIEW — SIN EDICIÓN (solo informativo)
| Nombre técnico | STARTUP/USER/EXIST/NO-ED/Restauración de Entidad/NO-TYC/LPDI |
| Función en código | sendEntityRestoredEmail |
| Asunto | “{entidad} ha sido restaurado en el Ecosistema LPDI” |
| Trigger | Usuario restaura una entidad desde la papelera del dashboard |
| Destinatario | Miembros asociados a la entidad restaurada |
| CTA | Botón: “Ver en Dashboard” Destino: ${dashboardUrl} → https://eco.lpdi.co/dashboard |
| Descripción | Notifica a los asociados que la entidad fue restaurada exitosamente desde la papelera. Aplica tanto a Startups como a ICGs. |
| TyC / Tratamiento | NO — Correo informativo. |
PREVIEW DEL CORREO
sendTransferNotification con entityKind y entityLabel: inserta el nombre real de la entidad, sea “la startup Acme” o “la ICG Fondo X”). Los previews de abajo usan una startup de ejemplo solo para ilustrar; en producción el nombre cambia según la entidad transferida.| Nombre técnico | ENTIDAD/RECEPTOR/AMBOS/NO-ED/Invitación de Transferencia/NO-TYC/LPDI |
| Función en código | sendTransferNotification('invitation') |
| Asunto | “Te transfieren una entidad — Ecosistema LPDI” |
| Trigger | Al crear una transferencia (POST /api/entity-transfer/create, rank 1) y al activar el siguiente rank de sucesión (cron ~/bin/lpdi-entity-transfer-cron.py). |
| Destinatario | El receptor de la transferencia (founder/contacto o correo indicado) |
| CTA | Botón: “Revisar y responder” → /transferencia/{token} |
| Descripción | Invita a aceptar o rechazar la transferencia; explica el plazo de 10 días. Si el correo no tiene cuenta, incluye la nota de TYC/PDP (se marcan en la página). |
| TyC / Tratamiento | NO — Correo transaccional. La aceptación de TYC/PDP (cuentas nuevas) ocurre en la página de aceptación, no por correo. |
| Estado | Correo listo y CABLEADO — se envía desde el endpoint de creación (rank 1) y desde el cron al avanzar la sucesión. |
PREVIEW DEL CORREO

| Nombre técnico | ENTIDAD/RECEPTOR/AMBOS/NO-ED/Recordatorio de Transferencia/NO-TYC/LPDI |
| Función en código | sendTransferNotification('reminder') |
| Asunto | “Recordatorio: transferencia pendiente — Ecosistema LPDI” |
| Trigger | Cron diario (lpdi-entity-transfer-cron.py, entity_transfer_tick): días 3, 6 y 10 desde que el rank quedó activo. |
| Destinatario | El receptor con la transferencia activa |
| CTA | Botón: “Revisar y responder” → /transferencia/{token} |
| Descripción | Recuerda al receptor que tiene una transferencia pendiente antes de que venza el plazo de 10 días. |
| TyC / Tratamiento | NO — Correo transaccional. La aceptación de TYC/PDP (cuentas nuevas) ocurre en la página de aceptación, no por correo. |
| Estado | Correo listo y CABLEADO — lo dispara el cron diario. |
PREVIEW DEL CORREO

| Nombre técnico | ENTIDAD/RECEPTOR/AMBOS/NO-ED/Transferencia Confirmada/NO-TYC/LPDI |
| Función en código | sendTransferNotification('confirmed') |
| Asunto | “Transferencia confirmada — Ecosistema LPDI” |
| Trigger | Al aceptar la transferencia en la página pública (/transferencia/[token]). |
| Destinatario | El nuevo responsable (quien aceptó) |
| CTA | Botón: “Ir a la entidad” → perfil de la entidad |
| Descripción | Confirma que la transferencia se completó e indica con qué estatus entra (miembro en Startup / administrador en ICG). |
| TyC / Tratamiento | NO — Correo transaccional. La aceptación de TYC/PDP (cuentas nuevas) ocurre en la página de aceptación, no por correo. |
| Estado | Correo listo y CABLEADO — se envía tras aceptar. |
PREVIEW DEL CORREO

| Nombre técnico | ENTIDAD/PROPIETARIO/AMBOS/NO-ED/Transferencia No Completada/NO-TYC/LPDI |
| Función en código | sendTransferNotification('fallen') |
| Asunto | “La transferencia no se completó — Ecosistema LPDI” |
| Trigger | Cron: cuando la cadena de sucesión se agota (todos los sucesores vencen/rechazan sin aceptar). |
| Destinatario | El propietario original |
| CTA | Botón: “Ir a la entidad” → perfil de la entidad |
| Descripción | Informa que la transferencia no prosperó y que sigue siendo el propietario; puede reiniciar el proceso. |
| TyC / Tratamiento | NO — Correo transaccional. La aceptación de TYC/PDP (cuentas nuevas) ocurre en la página de aceptación, no por correo. |
| Estado | Correo listo y CABLEADO — lo dispara el cron al agotarse la cadena. |
PREVIEW DEL CORREO

| Nombre técnico | ICG/PROPIETARIO/EXIST/NO-ED/ICG Sin Contacto/NO-TYC/LPDI |
| Función en código | sendTransferNotification('icg_sin_contacto') |
| Asunto | “Tu ICG quedó sin persona de contacto — Ecosistema LPDI” |
| Trigger | Cuando el contacto de un ICG (que no es el propietario) cierra su cuenta (POST /api/account/delete). |
| Destinatario | El propietario del ICG |
| CTA | Botón: “Registrar nuevo contacto” → FID (/dashboard/icg/nuevo) |
| Descripción | Avisa que el contacto ya no está disponible y que se limpiaron sus datos; invita a registrar un contacto nuevo. |
| TyC / Tratamiento | NO — Correo transaccional. La aceptación de TYC/PDP (cuentas nuevas) ocurre en la página de aceptación, no por correo. |
| Estado | Correo listo y CABLEADO — se envía al cerrar la cuenta del contacto. |
PREVIEW DEL CORREO

formalized_at IS NULL). El cron diario purge-draft-entities resuelve el correo del dueño del borrador vía la cuenta que lo registró (registered_by_id), con respaldo en el correo de contacto de la entidad. Idempotencia por la columna draft_reminder_stage (solo avanza, nunca retrocede) y por el filtro deleted_at IS NULL.| Nombre técnico | ENTIDAD/USER/EXIST/NO-ED/Recordatorio de Borrador/NO-TYC/LPDI |
| Función en código | draftReminderSpec() / sendDraftReminderEmail() con isClosing=false (notification-emails.ts) |
| Asunto | “Formaliza tu registro en el Ecosistema LPDI” |
| Trigger | Cron diario POST /api/cron/purge-draft-entities: recordatorio escalonado a los 30, 60, 90, 120 y 150 días desde created_at de un borrador (formalized_at IS NULL, deleted_at IS NULL). No repite un mismo hito. |
| Destinatario | El dueño del borrador (Startup o ICG sin formalizar): correo de la cuenta que lo registró, o el correo de contacto de la entidad como respaldo. |
| CTA | Botón: “Formalizar mi registro” → perfil de la entidad |
| Descripción | Invita a formalizar el registro (visibilidad ante el ecosistema, beneficios y conexiones) e indica los días restantes antes de que el borrador pase a la papelera (corte a los 180 días). |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO
| Nombre técnico | ENTIDAD/USER/EXIST/NO-ED/Aviso de Cierre de Borrador/NO-TYC/LPDI |
| Función en código | draftReminderSpec() / sendDraftReminderEmail() con isClosing=true (notification-emails.ts) — misma función que #94, con copy de cierre |
| Asunto | “Aviso de cierre: formaliza tu registro en {N} días” |
| Trigger | Cron diario purge-draft-entities: hitos a los 165 y 177 días desde created_at (15 y 3 días antes del corte de 180). No repite un mismo aviso. |
| Destinatario | El dueño del borrador (Startup o ICG sin formalizar) |
| CTA | Botón: “Formalizar mi registro” → perfil de la entidad |
| Descripción | Mismo correo que #94 con tono más urgente: indica cuántos días quedan antes de que el borrador pase a la papelera. |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO
| Nombre técnico | ENTIDAD/USER/EXIST/NO-ED/Borrador a Papelera/NO-TYC/LPDI |
| Función en código | draftTrashedSpec() / sendDraftTrashedEmail() (notification-emails.ts) |
| Asunto | “Tu borrador pasó a la papelera del Ecosistema LPDI” |
| Trigger | Cron diario purge-draft-entities, cuando el borrador cumple 180 días sin formalizar: se mueve a papelera (soft-delete, delete_scheduled_for = +30 días) y este correo se envía en la misma corrida. |
| Destinatario | El dueño del borrador (Startup o ICG sin formalizar) |
| CTA | Botón: “Restaurar mi registro” → dashboard (sección papelera) |
| Descripción | Avisa que el borrador pasó a la papelera y que tiene 30 días para restaurarlo antes de la eliminación definitiva. |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO
| Nombre técnico | CRON/ADMIN/EXIST/NO-ED/Reporte Diario/NO-TYC/LPDI |
| Función en código | buildDailyReportHtml + sendDailyReportEmail (email-daily-report.ts) |
| Endpoint | GET /api/cron/daily-report (protegido con Authorization: Bearer ${CRON_SECRET}) |
| Asunto | “Reporte diario Ecosistema LPDI — {fecha}” |
| Trigger | Cron diario configurado a las 6:00 AM Lima/Bogotá (11:00 UTC) en vercel.json |
| Destinatario | comunidad@lpdi.co (configurable vía DAILY_REPORT_TO) |
| Remitente | “Ecosistema LPDI” <no-reply@lpdi.co> vía Resend SMTP |
| Secciones |
• Altas del día anterior — Startups (STARTUP/PYME/SCALEUP), ICGs (todos los tipos), usuarios individuales (profiles sin entidad). Incluye fila “Total usuarios registrados” = usuarios individuales + miembros sumados a una entidad existente + responsables de las nuevas entidades. • Bajas del día anterior — Startups e ICGs (soft-delete vía deleted_at) + usuarios individuales (vía profile_deletions_log)• Acumulado — Entidades — Subtotales por tipo de Startup (STARTUP/PYME/SCALEUP) e ICG (INVESTOR_INDIVIDUAL/CORPORATE/HUB_NETWORK/etc.) + TOTAL ENTIDADES • Acumulado — Usuarios — Usuarios individuales (sin entidad) + Total usuarios registrados (destacado, todos los profiles del sistema) |
| CSV adjuntos (2) | Sí — (1) Altas: ecosistema-lpdi-usuarios-YYYY-MM-DD.csv con columnas: Email, Nombre completo, Fecha de registro, Tipo de usuario, Subcategoría del rol, País. (2) Bajas (Frank 26-jun): anexo aparte con usuarios y/o entidades dados de baja el día. Ambos van como attachment. |
| Preview | ![]() |
| CTA | Sin botón — correo informativo con datos tabulares. |
| TyC / Tratamiento | NO — Correo administrativo interno. No requiere consentimiento del destinatario. |
| Audit log | Las bajas de usuarios individuales se consultan desde profile_deletions_log (migración 045). Datos identificables < 12 meses; anonimización automática tras 12 meses (purga corre desde purge_expired_entities RPC). |
| Nombre técnico | ADMIN/EXIST/NO-ED/Ideas y Mejoras/NO-TYC/LPDI |
| Función en código | sendIdeaNotificationEmail (email.ts) |
| Endpoint | POST /api/ideas (rate-limit 3/15 min por IP) |
| Asunto | “[categoría] {título de la propuesta}” |
| Trigger | Un usuario envía una propuesta desde el modal «Ideas y mejoras» (footer / dashboard / ecosistema / /ideas). |
| Destinatario | soporte@lpdi.co (configurable vía IDEAS_NOTIFY_EMAIL; si no está seteada, usa el fallback soporte@lpdi.co) |
| Remitente | “Ecosistema LPDI” <no-reply@lpdi.co> vía Resend SMTP. Responder-a al correo del usuario que envió la propuesta. |
| Contenido | Categoría, título, descripción, nombre y correo del remitente, y número de imágenes adjuntas. |
| Imágenes | Sí — hasta 3 imágenes opcionales (png/jpg/webp, ≤2 MB c/u) que el usuario adjunta; viajan anexas al correo. |
| Persistencia | Desde 2026-08-01 cada propuesta se guarda en idea_submissions (+ idea_attachments) y se consulta en Administración → Sistema → Propuestas de mejora (solo Superadmin). Un fallo del correo ya no pierde la propuesta (email_sent=false la marca). |
| Preview | ![]() |
| CTA | Sin botón — correo informativo interno. |
| TyC / Tratamiento | NO — Correo administrativo interno. No requiere consentimiento del destinatario. |
| Nombre técnico | ADMIN/EXIST/NO-ED/Respuesta a Propuesta/NO-TYC/LPDI |
| Función en código | sendIdeaReplyEmail() (notification-emails.ts) |
| Asunto | “Respuesta a tu propuesta” |
| Trigger | Un super_admin escribe una respuesta desde Administración → Sistema → Propuestas de mejora y presiona «Enviar respuesta por correo». |
| Destinatario | El autor de la propuesta, al correo con el que la envió. |
| CTA | Botón: “Ir al ecosistema” → eco.lpdi.co |
| Contenido | Saludo, el título de la propuesta en negrita y el mensaje que el equipo escribió (respeta los saltos de párrafo). |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO

| Nombre técnico | FP/ALIADO/Registro Exitoso |
| Función en código | sendPerkNotification('registro_exitoso') |
| Asunto | “¡Registro exitoso de beneficio!” |
| Trigger | PATCH /api/perks/[id] al pasar a enviado (desde otro estado). |
| Destinatario | Aliado (correo del registrante) |
| CTA | Botón: “Ver registro” → /dashboard/beneficios |
| Descripción | Confirma al aliado que su beneficio quedó en revisión por el equipo LPDI. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/EQUIPO/Nuevo por Aprobar |
| Función en código | sendPerkNotification('nuevo_por_aprobar') |
| Asunto | “Nuevo beneficio por aprobar” |
| Trigger | PATCH → enviado desde borrador/cambios. |
| Destinatario | Admin asignado |
| CTA | Botón: “Revisar beneficio” → /dashboard/beneficios/admin |
| Descripción | Avisa al equipo que hay un beneficio nuevo pendiente de aprobación. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Aprobado |
| Función en código | sendPerkNotification('aprobado') |
| Asunto | “¡Beneficio aprobado!” |
| Trigger | Acción admin aprobar_y_publicar/publicar. |
| Destinatario | Aliado |
| CTA | Botón: “Ver beneficio” → /perks/{id} |
| Descripción | Notifica al aliado que su beneficio fue aprobado y publicado. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Aprobado Programado |
| Función en código | sendPerkNotification('aprobado_programado') |
| Asunto | “¡Beneficio aprobado!” |
| Trigger | Acción admin aprobar con fecha de publicación futura (vigencia posterior a la aprobación). |
| Destinatario | Aliado |
| CTA | Botón: “Ver registro” → /dashboard/beneficios |
| Descripción | Segundo flujo del Correo 34 (F2): notifica la aprobación e informa la fecha futura en que el beneficio se publicará automáticamente. El cron publish-scheduled lo activa en esa fecha. |
| Estado | Funcionando. NUEVO (F2). |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Actualizado |
| Función en código | sendPerkNotification('actualizado') |
| Asunto | “¡Beneficio actualizado!” |
| Trigger | PATCH al pasar un publicado a edicion. |
| Destinatario | Aliado |
| CTA | Botón: “Ver beneficio” → /perks/{id} |
| Descripción | Confirma que los cambios se guardaron y pasarán por aprobación. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/EQUIPO/Cambios por Aprobar |
| Función en código | sendPerkNotification('cambios_por_aprobar') |
| Asunto | “Cambios de beneficio por aprobar” |
| Trigger | PATCH → enviado desde edicion. |
| Destinatario | Admin asignado |
| CTA | Botón: “Revisar cambios” → /dashboard/beneficios/admin |
| Descripción | Avisa al equipo que un beneficio publicado tiene cambios por revisar. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Solicitud de Ajustes |
| Función en código | sendPerkNotification('cambios_solicitados') |
| Asunto | “Tu beneficio necesita unos ajustes” |
| Trigger | Acción admin solicitar_cambios (→ cambios, recuperable). |
| Destinatario | Aliado |
| CTA | Botón: “Ajustar beneficio” → /dashboard/beneficios |
| Descripción | El admin pide ajustes antes de publicar (incluye el detalle). Reemplaza al “no aceptado” en esta acción porque el estado es recuperable. |
| Estado | Funcionando. NUEVO. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/No Aceptado |
| Función en código | sendPerkNotification('no_aceptado') |
| Asunto | “Beneficio no aceptado” |
| Trigger | Acción «Rechazar» en el panel de admin de beneficios (primera revisión). Cableado 2026-07-07. |
| Destinatario | Aliado |
| CTA | Botón: “Ver registro” → /dashboard/beneficios |
| Descripción | Rechazo definitivo de un beneficio en primera revisión. El beneficio pasa a estado rechazado y va a «Eliminados / Rechazados» (borrado a los 30 días). Distinto de «Solicitar cambios» (#38), que es recuperable. |
| Estado | Activo. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Cambios Aprobados/NO-TYC/LPDI |
| Función en código | sendPerkNotification('cambios_aprobados') |
| Asunto | “Los cambios de tu beneficio fueron aprobados” |
| Trigger | El admin aprueba (Aprobar y publicar / Publicar) los cambios de un beneficio ya publicado (venía de estado edicion). Cableado 2026-07-07. |
| Destinatario | Aliado |
| CTA | Botón: “Ver beneficio” → perfil público del beneficio |
| Descripción | Confirma al aliado que los cambios que envió a un beneficio ya publicado fueron aprobados y ya están en el catálogo. Diferente del #33 (primera aprobación). |
| Estado | Activo. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Cambios No Aprobados/NO-TYC/LPDI |
| Función en código | sendPerkNotification('cambios_rechazados') |
| Asunto | “Los cambios de tu beneficio no fueron aprobados” |
| Trigger | El admin rechaza los cambios de un beneficio ya publicado (estado edicion). Cableado 2026-07-07. |
| Destinatario | Aliado |
| CTA | Botón: “Ver beneficio” → perfil público del beneficio |
| Descripción | Avisa al aliado que los cambios que envió no fueron aprobados y que el beneficio sigue publicado tal como estaba antes (se descartan los cambios). Incluye el motivo si el admin lo indicó. |
| Estado | Activo. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Terminado |
| Función en código | sendPerkNotification('terminado') |
| Asunto | “Beneficio terminado” |
| Trigger | Acción admin desactivar o cierre por vigencia. |
| Destinatario | Aliado · con copia (cc) al admin asignado |
| CTA | Botón: “Ver registro” → /dashboard/beneficios |
| Descripción | Notifica que el beneficio fue cerrado y ya no aparece en el catálogo. |
| Estado | Funcionando (admin desactivar). |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Eliminado |
| Función en código | sendPerkNotification('eliminado') |
| Asunto | “Beneficio eliminado” |
| Trigger | DELETE /api/perks/[id] (soft-delete → papelera). |
| Destinatario | Aliado · con copia (cc) al admin asignado |
| CTA | Botón: “Validar en la base de datos” → /dashboard/beneficios |
| Descripción | Notifica que el beneficio fue enviado a la papelera (recuperable 30 días). |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/ALIADO/Registro en Beneficio |
| Función en código | sendPerkRegistrationEmail() |
| Asunto | “¡Nuevo registro en tu beneficio!” |
| Trigger | Un usuario se registra para obtener el beneficio — cualquier tipo (código, enlace, agenda o «dejar datos»), en /api/perks/[id]/redeem. |
| Destinatario | Aliado (dueño del beneficio) · con copia (cc) a partners@lpdi.co |
| CTA | Botón: “Ver referido” → /dashboard/beneficios/referidos (Mis referidos) |
| Descripción | Avisa al aliado que un usuario se registró en su beneficio, con los datos del registrante (nombre, correo, teléfono, empresa tomada del perfil del usuario) y el tipo de registro. Unifica el antiguo correo de «lead» al diseño FP y lo extiende a todos los tipos de redención. |
| Estado | Funcionando. NUEVO. |
PREVIEW DEL CORREO
| Nombre técnico | FP/USUARIO/Solicitud recibida/NO-TYC/LPDI |
| Función en código | sendPerkRedemptionUserEmail |
| Asunto | “Recibimos tu solicitud — Ecosistema LPDI” |
| Trigger | El usuario solicita un beneficio en /api/perks/[id]/redeem (cualquier tipo de canje). |
| Destinatario | Usuario que solicitó el beneficio · copia a partners@lpdi.co |
| CTA | Botón: “Ir al ecosistema” → eco.lpdi.co |
| Descripción | Confirma al usuario que su solicitud fue enviada al aliado + muestra la tipología (Código de descuento / Enlace de redención / Dejó sus datos de contacto / Agendó una cita). Espejo (al usuario) del aviso al aliado. Aprobado por Frank 2026-07-02. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/LPDI/Solicitud de Alianza/NO-TYC/LPDI |
| Función en código | sendAllianceRequestEmail() · email.ts |
| Asunto | “Nueva solicitud de alianza — [nombre]” |
| Trigger | POST /api/alianzas desde el pop-up “Quiero ser aliado”. |
| Destinatario | partners@lpdi.co (reply-to al usuario) |
| CTA | Responder directamente al correo para contactar al solicitante. |
| Descripción | Versión interna. Dos secciones: “Datos del usuario solicitante” (nombres y apellidos, correo, teléfono, LinkedIn) y “Datos de la entidad” (nombre, rol, correo corporativo, página web, LinkedIn), más el mensaje. Campos vacíos no se muestran. |
| Estado | Funcionando. Nuevo (Frank 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | FP/USUARIO/Solicitud de Alianza/NO-TYC/USUARIO |
| Función en código | sendAllianceRequestUserEmail() · email.ts |
| Asunto | “Recibimos tu solicitud de alianza — Ecosistema LPDI” |
| Trigger | Mismo POST /api/alianzas (best-effort; su fallo no bloquea la solicitud). |
| Destinatario | Correo del usuario solicitante |
| CTA | Botón: “Agendar una reunión” → lpdi.co/agenda30min |
| Descripción | Acuse de recibo al usuario, distinto del interno: confirma la recepción e invita a agendar una reunión. |
| Estado | Funcionando. Nuevo (Frank 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | FP/PROSPECTO/Referido a LPDI/NO-TYC/PROSPECTO |
| Función en código | sendLpdiReferralEmails (correo 1/3) |
| Asunto | “Una recomendación para conectar con La Punta del Iceberg” |
| Trigger | Un miembro guarda un referido en el modal “Referir a LPDI” (POST /api/perks/referir-lpdi → createReferral). |
| Destinatario | Correo del prospecto referido |
| CTA | Botón: “Unirme al ecosistema” (/registro-usuario) o “Ir al ecosistema” (eco.lpdi.co) si el prospecto ya tiene cuenta |
| Descripción | Referido comercial (no invitación): un miembro lo recomendó con LPDI para construir sinergias; LPDI lo contactará en los próximos días. El texto de cierre invita a crear cuenta mientras conectan. Best-effort. Nuevo (tarea 35, 2026-07-30). |
| TyC / Tratamiento | NO |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/REFERENTE/Acuse Referido/NO-TYC/USUARIO |
| Función en código | sendLpdiReferralEmails (correo 2/3) |
| Asunto | “Recibimos tu recomendación — Ecosistema LPDI” |
| Trigger | Mismo trigger que #86: al guardar el referido en createReferral. |
| Destinatario | Correo del referente (el miembro que refirió) |
| CTA | Botón: “Ver mis referidos” → /dashboard/beneficios/referidos |
| Descripción | Confirma al referente que su recomendación quedó registrada y que el equipo LPDI contactará al prospecto. Lo remite a su lista “Referidos a LPDI”. Best-effort. Nuevo (tarea 35, 2026-07-30). |
| TyC / Tratamiento | NO |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FP/LPDI/Nuevo Prospecto Referido/NO-TYC/LPDI |
| Función en código | sendLpdiReferralEmails (correo 3/3) |
| Asunto | “Nuevo prospecto referido a La Punta del Iceberg” |
| Trigger | Mismo trigger que #86: al guardar el referido en createReferral. |
| Destinatario | partners@lpdi.co · responder-a: el referente |
| CTA | Botón: “Ir al panel” → /dashboard/beneficios/referidos |
| Descripción | Avisa al equipo LPDI de un nuevo prospecto comercial, con dos bloques (Prospecto: nombre, correo, teléfono, empresa, estado; si ya existe: cargo, LinkedIn, web de la empresa. Referente: nombre, correo, teléfono, empresa, cargo, LinkedIn). Best-effort. Nuevo (tarea 35, 2026-07-30). |
| TyC / Tratamiento | NO |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/Registro Exitoso |
| Función en código | sendEventNotification('registro_exitoso') |
| Asunto | “¡Registro exitoso de evento!” |
| Trigger | Action submit de /registro-evento (evento en PENDING). |
| Destinatario | Organizador (contact_email) |
| CTA | Botón: “Ver registro” → /dashboard |
| Descripción | Confirma al organizador que su evento quedó en revisión. Incluye el código. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FE/EQUIPO/Nuevo por Aprobar |
| Función en código | sendEventNotification('nuevo_por_aprobar') |
| Asunto | “Nuevo evento por aprobar” |
| Trigger | Action submit de /registro-evento. |
| Destinatario | Admin asignado |
| CTA | Botón: “Revisar evento” → /dashboard |
| Descripción | Avisa al equipo que hay un evento nuevo pendiente de revisión. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/Aprobado |
| Función en código | sendEventNotification('aprobado') |
| Asunto | “¡Evento aprobado!” |
| Trigger | Acción admin del panel de eventos (N13). |
| Destinatario | Organizador |
| CTA | Botón: “Ver evento” → /dashboard |
| Descripción | Notifica al organizador que su evento fue aprobado. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/Aprobado Programado |
| Función en código | sendEventNotification('aprobado_programado') |
| Asunto | “¡Evento aprobado!” |
| Trigger | Acción admin aprobar con fecha de publicación futura. |
| Destinatario | Organizador |
| CTA | Botón: “Ver registro” → /dashboard |
| Descripción | Segundo flujo de aprobación de evento (F2): informa la fecha futura de publicación automática. Incluye el badge del código del evento. |
| Estado | Funcionando. NUEVO (F2). |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/Actualizado |
| Función en código | sendEventNotification('actualizado') |
| Asunto | “¡Evento actualizado!” |
| Trigger | Edición de un evento ya aprobado (se guarda manteniendo el estado aprobado). |
| Destinatario | Organizador |
| CTA | Botón: “Ver evento” → /dashboard |
| Descripción | Al organizador: su evento publicado fue actualizado. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FE/EQUIPO/Cambios por Aprobar |
| Función en código | sendEventNotification('cambios_por_aprobar') |
| Asunto | “Cambios de evento por aprobar” |
| Trigger | Un usuario que NO es «editor de confianza» envía un cambio a su evento que sí requiere aprobación. (El editor de confianza auto-aprueba, así que su edición no genera este correo.) |
| Destinatario | Admin asignado |
| CTA | Botón: “Revisar cambios” → /dashboard |
| Descripción | Avisa al equipo que un evento tiene cambios enviados por un usuario sin auto-aprobación y deben revisarse. |
| Estado | Pendiente — se activa con el flujo de «Mis eventos». |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/No Aceptado |
| Función en código | sendEventNotification('no_aceptado') |
| Asunto | “Evento no aceptado” |
| Trigger | Acción admin de rechazo (N13). |
| Destinatario | Organizador |
| CTA | Botón: “Ver registro” → /dashboard |
| Descripción | Notifica al organizador que su evento no fue aceptado. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/Eliminado |
| Función en código | sendEventNotification('eliminado') |
| Asunto | “Evento eliminado” |
| Trigger | Eliminación de un evento (N13). |
| Destinatario | Organizador · con copia (cc) al admin asignado |
| CTA | Botón: “Ver registro” → /dashboard |
| Descripción | Notifica al organizador que su evento fue eliminado. |
| Estado | Funcionando. |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/Publicación Automática |
| Función en código | sendEventNotification('publicacion_exitosa') |
| Asunto | “¡Publicación automática de evento!” |
| Trigger | Registro de evento por un usuario con privilegio de auto-publicación (F6): el evento se publica sin pasar por aprobación. |
| Destinatario | Organizador · con copia (cc) al admin asignado |
| CTA | Botón: “Ver evento” → /dashboard |
| Descripción | Confirma que el evento se publicó automáticamente. El privilegio se administra en el panel de admin de eventos (sección de privilegios de auto-publicación por correo). |
| Estado | Funcionando. NUEVO (F6). |
PREVIEW DEL CORREO
| Nombre técnico | FE/ORGANIZADOR/Solicitud de Ajustes |
| Función en código | sendEventNotification('cambios_solicitados') |
| Asunto | “Tu evento necesita unos ajustes” |
| Trigger | El admin pide cambios a un evento (acción «solicitar cambios» en el panel de aprobación). |
| Destinatario | Organizador · con copia (cc) al admin que la envía |
| CTA | Botón: “Ajustar evento” → /dashboard |
| Descripción | Al organizador: el admin solicita ajustes e incluye el detalle de lo que debe corregir; con copia al admin que la envía, para trazabilidad. Es el espejo del correo #38 (Solicitud de Ajustes) de Beneficios. |
| Estado | Funcionando. NUEVO. |
PREVIEW DEL CORREO
| Función en código | organizerInviteSpec / sendOrganizerInvitation (notification-emails.ts) |
| Asunto | “Te invitaron a registrarte — Ecosistema LPDI” |
| Trigger | Al registrar un evento con un coorganizador que NO corresponde a una entidad registrada. Best-effort e individual (nunca en copia). |
| Destinatario | Correo del organizador no registrado. |
| CTA | Botón (azul): “Crear mi cuenta” → /registro-usuario?email= |
| Descripción | La entidad figura como coorganizadora del evento pero aún no tiene perfil; al registrarla acceden a la info del evento, conectan con el ecosistema y la entidad aparece con el distintivo «Organizador de eventos». Incluye los pasos (crear cuenta → registrar como Startup o ICG). Badge con el código del evento. |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO (generado 2026-07-28 desde organizerInviteSpec)
| Función en código | organizerInviteSpec (reminder) / sendOrganizerInvitation (notification-emails.ts) |
| Asunto | “Recordatorio: te invitaron a registrarte — Ecosistema LPDI” |
| Trigger | Recordatorio automático (cron ~3 días) si el organizador sigue sin registrarse. |
| Destinatario | Correo del organizador no registrado. |
| CTA | Botón (azul): “Crear mi cuenta” → /registro-usuario?email= |
| Descripción | Igual que el #80 con encabezado de recordatorio («Te recordamos con cariño…»). |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO (generado 2026-07-28 desde organizerInviteSpec)
| Función en código | speakerHostInviteSpec / sendSpeakerHostInvitation (notification-emails.ts) |
| Asunto | “Te invitaron como speaker — Ecosistema LPDI” |
| Trigger | Al registrar un evento con un speaker cuyo correo no está en el sistema. |
| Destinatario | Correo del speaker no registrado. |
| CTA | Botón (azul): “Soy speaker” → /registro-usuario?email= |
| Descripción | Le informa que fue registrado como speaker del evento y lo invita a crear su cuenta para confirmar su participación y aparecer con el distintivo de participación confirmada. Badge con el código del evento. |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO (generado 2026-07-28 desde speakerHostInviteSpec)
| Función en código | speakerHostInviteSpec / sendSpeakerHostInvitation (notification-emails.ts) |
| Asunto | “Te invitaron como host — Ecosistema LPDI” |
| Trigger | Al registrar un evento con un host cuyo correo no está en el sistema. |
| Destinatario | Correo del host no registrado. |
| CTA | Botón (azul): “Soy host” → /registro-usuario?email= |
| Descripción | Le informa que fue registrado como host del evento y lo invita a crear su cuenta para confirmar su participación y aparecer con el distintivo de participación confirmada. Badge con el código del evento. |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO (generado 2026-07-28 desde speakerHostInviteSpec)
| Función en código | speakerHostInviteSpec (reminder) / sendSpeakerHostInvitation (notification-emails.ts) |
| Asunto | “Recordatorio: te invitaron como speaker — Ecosistema LPDI” |
| Trigger | Cron /api/cron/speaker-host-invite-reminders a los 3 días si el speaker sigue sin registrarse (reminder_count = 0). Un solo recordatorio. |
| Destinatario | Correo del speaker no registrado. |
| CTA | Botón (azul): “Soy speaker” → /registro-usuario?email= |
| Descripción | Recordatorio de la invitación: le recuerda que fue registrado como speaker del evento y aún no tiene cuenta, y lo invita a crearla para confirmar su participación. Badge con el código del evento. |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO (generado 2026-07-28 desde speakerHostInviteSpec)
| Función en código | speakerHostInviteSpec (reminder) / sendSpeakerHostInvitation (notification-emails.ts) |
| Asunto | “Recordatorio: te invitaron como host — Ecosistema LPDI” |
| Trigger | Cron /api/cron/speaker-host-invite-reminders a los 3 días si el host sigue sin registrarse (reminder_count = 0). Un solo recordatorio. |
| Destinatario | Correo del host no registrado. |
| CTA | Botón (azul): “Soy host” → /registro-usuario?email= |
| Descripción | Recordatorio de la invitación: le recuerda que fue registrado como host del evento y aún no tiene cuenta, y lo invita a crearla para confirmar su participación. Badge con el código del evento. |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO (generado 2026-07-28 desde speakerHostInviteSpec)
src/lib/server/notification-emails.ts + endpoint POST/DELETE /api/scouting/[slug]/aplicar + cron POST /api/cron/scouting-notify-digest. Todos best-effort (try/catch, no lanzan). El aviso al organizador (#91) es idempotente vía organizer_notified_at en startup_campaign_applications: cada corrida del cron solo toma y marca las filas aún NULL, así que correrlo dos veces no reenvía.| Nombre técnico | SCOUT/APLICANTE/Confirmación Postulación/NO-TYC/LPDI |
| Función en código | scoutingApplicantEmailSpec() / sendScoutingApplicantEmail() (notification-emails.ts) |
| Endpoint | POST /api/scouting/[slug]/aplicar |
| Asunto | “Recibimos tu postulación en {nombre de la convocatoria}” |
| Trigger | Al enviar una postulación a una convocatoria de scouting (alta en startup_campaign_applications). Siempre se envía, sin importar la configuración de notificaciones del organizador. |
| Destinatario | La Startup/persona que se postula (su correo de usuario) |
| CTA | Botón: “Mis aplicaciones” → /dashboard/convocatorias/mis-aplicaciones |
| Descripción | Confirma que la postulación quedó registrada, con la fecha y hora completas del envío (incluyen el huso horario, ej. «24 de agosto de 2026 a las 9:47 a. m. (GMT-5)»), e incluye el resumen de los campos enviados (nombre de la compañía, país, industria, etc., mismo contenido que ve en «Ver aplicación»). |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO
| Nombre técnico | SCOUT/ORGANIZADOR/Nueva Postulación o Resumen/NO-TYC/LPDI |
| Función en código | scoutingOrganizerEmailSpec() / sendScoutingOrganizerEmail() (notification-emails.ts) |
| Endpoint / Cron | Modo immediate: POST /api/scouting/[slug]/aplicar. Modos daily/weekly/on_close: cron POST /api/cron/scouting-notify-digest. |
| Asunto | “Nueva postulación en {convocatoria}” (una sola) o “Resumen de postulaciones en {convocatoria}” (varias) |
| Trigger | Nueva postulación, solo si «Notificarme las nuevas postulaciones» está activo en la convocatoria (notify_applications_enabled). En modo «una a una» (immediate) llega de inmediato al postularse; en resumen diario/semanal/al cierre lo agrupa el cron (semanal solo domingos; al cierre solo campañas no permanentes ya cerradas). |
| Destinatario | El correo del organizador configurado en la sección Notificaciones de la convocatoria |
| CTA | Depende del acceso del destinatario al panel (actualizado 2026-09-03): si el correo de Notificaciones de la convocatoria tiene acceso al panel de postulaciones, botón “Ver postulaciones” → /dashboard/postulaciones/{slug}; si no tiene acceso, botón “Ver convocatoria” → /scouting/{slug} (formulario público de la convocatoria), y sin el párrafo de ingreso al panel, para no llevarlo a una ruta sin permiso (Frank, 2026-09-03). |
| Descripción — modo inmediato | Una sola postulación: «Hay una nueva postulación en la convocatoria {convocatoria}: {startup} ({correo}), {fecha completa con hora y GMT, ej. 20 de agosto de 2026 a las 10:30 a. m. (GMT-5)}.» |
| Descripción — modo resumen | Varias postulaciones agrupadas por el cron (diario/semanal/al cierre): arranca con «Has recibido {X} nuevas postulaciones en el período {inicio} al {fin} de la convocatoria {convocatoria}.», sigue, solo si el destinatario tiene acceso al panel, con el párrafo «Ingresa al panel para revisar las postulaciones.» y luego lista cada postulación numerada (1, 2, 3…), ordenada de la más reciente a la más antigua, con startup, correo y fecha (con GMT). |
| TyC / Tratamiento | NO. |
PREVIEW — Con acceso al panel (botón «Ver postulaciones»)
PREVIEW — Sin acceso al panel (botón «Ver convocatoria»)
| Nombre técnico | SCOUT/ENTIDAD-ORGANIZADOR/Retiro de Postulación/NO-TYC/LPDI |
| Función en código | scoutingWithdrawalEmailSpec() / sendScoutingWithdrawalEmail() (notification-emails.ts) |
| Endpoint | DELETE /api/scouting/[slug]/aplicar |
| Asunto | “Se retiró la postulación de {startup} de {convocatoria}” (a la entidad) o “{startup} retiró su postulación en {convocatoria}” (al convocante) |
| Trigger | Al retirar una postulación. Inmediato, sin frecuencia configurable. |
| Destinatario | Admin/CEO de la entidad que se retira (siempre) y el convocante (correo de Notificaciones), solo si «Notificarme los retiros» está activo (notify_withdrawals_enabled) — casilla independiente de la de nuevas postulaciones. |
| CTA | Diseño A (a la startup): botón “Aplicar de nuevo” → /dashboard. Diseño B (al convocante): botón “Mis campañas” → /dashboard. |
| Descripción — diseño A (a la startup) | «{correo de quien dio la orden} dio la orden de retirar la postulación de {startup} de la convocatoria {convocatoria} el {fecha, hora y GMT}.» Sigue: «Si crees que ha sido un error, ingresa al dashboard y vuelve a aplicar.» |
| Descripción — diseño B (al convocante) | «{startup} retiró su postulación a la convocatoria {convocatoria} el {fecha, hora y GMT}.» Sigue: «Si deseas comunicarte con ellos para conocer las razones del retiro, puedes escribirles a {correo de contacto}.» |
| TyC / Tratamiento | NO. |
PREVIEW — Diseño A (a la startup)
PREVIEW — Diseño B (al convocante)
| Nombre técnico | SCOUT/ORGANIZADOR-NO-REGISTRADO/Invitación/NO-TYC/LPDI |
| Función en código | sendScoutingNotifyInviteEmail() (notification-emails.ts), invocada desde el editor de convocatorias (dashboard/admin/scouting/[id]/+page.server.ts) |
| Asunto | “Fuiste designado para recibir notificaciones de {convocatoria}” |
| Trigger | Al guardar en el editor una convocatoria con un correo de notificaciones que aún no tiene cuenta en el ecosistema. El sistema le crea la cuenta (usuario + perfil) y genera el enlace de verificación para esta invitación. |
| Destinatario | El correo designado en Notificaciones cuando NO tiene cuenta en el ecosistema |
| CTA | Botón: “Crear mi cuenta” → enlace de verificación (/auth/verificar) |
| Descripción | Ahora identifica a quien lo designó: «Fuiste designado por {correo de quien creó/editó el formulario de la convocatoria} para recibir las notificaciones de la convocatoria {convocatoria} en el Ecosistema LPDI. Crea tu cuenta dando clic en el botón a continuación para empezar a recibir las notificaciones.» |
| TyC / Tratamiento | NO. |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/SOLICITANTE/Solicitud Enviada |
| Función en código | buildJoinRequestCreatedRequesterHtml() · email-join-requests.ts |
| Asunto | “Tu solicitud fue enviada” |
| Trigger | al crear una solicitud «Es mi empresa, solicitar asociación». |
| Destinatario | Solicitante |
| Descripción | Acuse al solicitante: su solicitud de asociación fue enviada a los administradores de la entidad; vigencia 10 días. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/APROBADOR/Nueva Solicitud |
| Función en código | buildJoinRequestCreatedApproverHtml() · email-join-requests.ts |
| Asunto | “Nueva solicitud de asociación” |
| Trigger | al crear la solicitud. |
| Destinatario | Admin/CEO/editor de la entidad |
| Descripción | A quienes administran la entidad: alguien pidió asociarse; enlace a revisar en el panel (PS/PI) para aceptar con cargo y permisos. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/APROBADOR/Recordatorio |
| Función en código | buildJoinRequestReminderApproverHtml() · email-join-requests.ts |
| Asunto | “Recordatorio: solicitud pendiente” |
| Trigger | cron diario, día 5 sin respuesta. |
| Destinatario | Aprobador |
| Descripción | Recordatorio al aprobador: la solicitud sigue pendiente y vence pronto. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/SOLICITANTE/Aprobada |
| Función en código | buildJoinRequestApprovedRequesterHtml() · email-join-requests.ts |
| Asunto | “Ya haces parte de [entidad]” |
| Trigger | al aprobar la solicitud. |
| Destinatario | Solicitante |
| Descripción | Al solicitante: su solicitud fue aprobada (con su cargo) y ya quedó asociado a la entidad. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/APROBADOR/Aprobada |
| Función en código | buildJoinRequestApprovedApproverHtml() · email-join-requests.ts |
| Asunto | “Solicitud aprobada” |
| Trigger | al aprobar. |
| Destinatario | Aprobador |
| Descripción | Constancia al aprobador de que aprobó la solicitud y el miembro quedó registrado. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/SOLICITANTE/Rechazada |
| Función en código | buildJoinRequestRejectedRequesterHtml() · email-join-requests.ts |
| Asunto | “Sobre tu solicitud de asociación” |
| Trigger | al rechazar. |
| Destinatario | Solicitante |
| Descripción | Al solicitante: su solicitud no fue aprobada (sin exponer quién rechazó). |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/APROBADOR/Rechazada |
| Función en código | buildJoinRequestRejectedApproverHtml() · email-join-requests.ts |
| Asunto | “Solicitud rechazada” |
| Trigger | al rechazar. |
| Destinatario | Aprobador |
| Descripción | Constancia al aprobador del rechazo; sin cambios en la entidad. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/SOLICITANTE/Expirada |
| Función en código | buildJoinRequestExpiredRequesterHtml() · email-join-requests.ts |
| Asunto | “Tu solicitud venció sin respuesta” |
| Trigger | cron diario, día 10. |
| Destinatario | Solicitante |
| Descripción | Al solicitante: la solicitud venció a los 10 días sin respuesta; puede reintentar o crear su entidad. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Nombre técnico | ASOC/APROBADOR/Expirada |
| Función en código | buildJoinRequestExpiredApproverHtml() · email-join-requests.ts |
| Asunto | “Solicitud vencida” |
| Trigger | cron diario, día 10. |
| Destinatario | Aprobador |
| Descripción | Constancia informativa al aprobador de que la solicitud venció sin respuesta. |
| Estado | Funcionando. Nuevo (Frank, tarea 67, 2026-07-23). |
PREVIEW DEL CORREO
| Estado | ELIMINADO — No se obliga a confirmar la creación de una startup; lo que se confirma son las cuentas de usuario. El cron de purga (soft-delete a los 8 días) sigue activo, pero ya no envía notificación por email. |
| Función eliminada | sendStartupPurgedEmail (removido de email.ts) |
| Estado | ELIMINADO — Consolidado en #18. |
| Razón | El sistema usa una única función (sendTeamInvitationEmail) para ambos casos (usuario nuevo y usuario existente). La diferencia se controla con el flag userExists, no con dos templates distintos. Mantener dos entradas duplicaba el mismo correo en el inventario. |
| Dónde queda documentado | Las dos variantes (usuario nuevo + SI-TYC · usuario existente + NO-TYC) ahora se describen dentro de #18. |
| Estado | ELIMINADO — No se obliga a confirmar la creación de un ICG; lo que se confirma son las cuentas de usuario. El cron de purga (purge_expired_entities RPC) sigue activo, pero ya no envía notificación por email. |
| Función eliminada | sendIcgPurgedEmail (removido de email.ts) |