1. Maquina de Estados
Cada evento en Nvito sigue un ciclo de vida estricto con 4 estados en base de datos y 1 estado visual derivado (Expirado). Las transiciones estan controladas por EventLifecycleService y EventSchedulerService, garantizando que ningún cambio de estado ocurra fuera de las reglas definidas.
1.1 Diagrama de Estados
Maquina de Estados — Evento
draft→activePublicar invitacionactive→completedAuto-complete (cron)active→cancelledCancelar manualmentedraft→cancelledCancelar manualmente1.2 Descripción de Estados
| Estado | Descripción | Quien puede estar | Duracion tipica |
|---|---|---|---|
| DRAFT | Evento recien creado. El organizador configura detalles, crea invitación, agrega invitados. No tiene invitación publicada. | Todos los eventos nuevos | Dias a semanas |
| ACTIVE | El evento tiene al menos una invitación publicada. Los invitados pueden ver la invitación y responder RSVP. | Eventos con invitación PUBLISHED | Semanas a meses |
| COMPLETED | El evento termino. Se dispara automáticamente cuando endDate es menor o igual a now. Las invitaciones se cierran. | Eventos cuya fecha ya paso | Permanente |
| CANCELLED | El evento fue cancelado manualmente por el organizador. Las invitaciones se cierran y los workflows se pausan. | Eventos cancelados explicitamente | Permanente |
1.3 Estado Visual Derivado: EXPIRED (Expirado)
El estado Expirado no existe como valor en el enum EventStatus de la base de datos. Es un estado visual calculado en el frontend cuando se cumplen estás condiciones:
- El evento está en
COMPLETEDy nunca tuvo una invitación publicada (activatedAt === null) - O la fecha del evento ya paso, no tiene
activatedAt, y no está cancelado
Formula en el frontend (EventContext):
isEventExpired = (isEventCompleted && !event.activatedAt)
|| (isEventPast && !event.activatedAt && !isEventCancelled)
Diferencia con COMPLETED: Un evento COMPLETED fue publicado, vivido y finalizado normalmente. Un evento Expirado nunca llego a publicar su invitación — la fecha paso sin que el organizador completara la preparación.
Comportamiento: Mismo bloqueo que COMPLETED y CANCELLED — todas las acciones de modificación deshabilitadas, servicios bloqueados, solo lectura. El dashboard muestra un badge "Expirado" y la tarjeta de estado con icono de advertencia.
2. Transiciones Detalladas
2.1 DRAFT --> ACTIVE (Activación automática)
Esta transición no es manual. Se dispara automáticamente cuando una invitación del evento es publicada (estado PUBLISHED).
Servicio responsable: EventLifecycleService.activateEventOnPublish(eventId)
Flujo:
- El usuario aprueba la invitación (POST
/invitations/:id/approve) ApprovalWorkflowServicecambia la invitación aPUBLISHED- Se ejecuta
EventLifecycleService.activateEventOnPublish(eventId) - Si el evento está en
DRAFT, transiciona aACTIVE - Si el evento ya está en
ACTIVE(otra invitación previa), no hace nada
Validaciones:
- El evento debe existir y pertenecer a la organización
- El evento debe estar en estado
DRAFT - Debe haber al menos una invitación en estado
PUBLISHED
Efectos colaterales:
- Se activan los workflows de comunicación programados
- Los endpoints moviles del evento quedan habilitados
- El EventAccessCode ya está disponible (se género en creación)
2.2 ACTIVE --> COMPLETED (Auto-complete)
Transición automática ejecutada por un cron job.
Servicio responsable: EventSchedulerService
Frecuencia: Cada hora (0 * * * *)
Flujo:
- El cron busca eventos en estado
ACTIVEdondeendDatees menor o igual anow - Para cada evento encontrado:
- Cambia el estado a
COMPLETED - Cierra todas las invitaciones en
PUBLISHED(transición aCLOSED) - Pausa todos los workflows activos
- Registra
completedAtcon timestamp
- Cambia el estado a
Validaciones:
- Solo eventos en estado
ACTIVE endDatedebe ser menor o igual anow()
Efectos colaterales:
- Invitaciones cerradas (estado
CLOSEDconcloseReason: 'EVENT_COMPLETED') - Workflows pausados
- Campanas de comunicación en
SCHEDULEDse cancelan - Se dispara el trigger
POST_EVENTpara workflows configurados
2.3 ACTIVE/DRAFT --> CANCELLED (Cancelación manual)
Transición manual iniciada por el organizador.
Endpoint: PATCH /events/:id/cancel
Roles permitidos: OWNER, ADMIN
Flujo:
- El usuario envia la solicitud de cancelación
- Se valida que el evento no este ya en
COMPLETEDoCANCELLED - Se cambia el estado a
CANCELLED - Se ejecutan los efectos colaterales de cierre
Body: cancellationReason (string, obligatorio) — razon de la cancelación que se muestra en el dashboard
Validaciones:
- El evento debe estar en
DRAFToACTIVE - El usuario debe tener rol
OWNERoADMINen la organización - Se registra
cancelledAt,cancelledByycancellationReason
Efectos colaterales:
- Todas las invitaciones en
UNPUBLISHEDoPUBLISHEDse cierran (CLOSEDconcloseReason: 'EVENT_CANCELLED') - Todos los workflows activos se pausan
- Campanas en
SCHEDULEDoSENDINGse cancelan - Se envia notificación al equipo del evento
3. Creación del Evento
Al crear un evento, se generan automáticamente varios recursos asociados.
3.1 EventAccessCode
Cada evento recibe un código de acceso único para la app movil.
| Campo | Descripción |
|---|---|
code | 8 caracteres alfanumericos únicos (generado con nanoid) |
hashedPin | PIN de 4 digitos hasheado con bcrypt (para acceso HOST desde la app) |
isActive | Se activa al crear, se desactiva al cancelar/completar |
Uso: El host ingresa el código + PIN en la app movil para acceder como anfitrion del evento. Los invitados acceden via deep link o QR (sin PIN).
3.2 Flujo de Creación
Flujo de Creacion del Evento
4. Flujo de Publicación y Activación
El momento más importante del ciclo de vida: cuando una invitación se pública y el evento se activa.
Flujo de Publicacion y Activacion
5. Actores del Sistema
| Actor | Tipo | Acciones sobre eventos |
|---|---|---|
| Organizador (Owner/Admin) | Humano | Crear, editar, cancelar, gestionar invitados |
| EventSchedulerService | Sistema (cron) | Auto-completar eventos cuya fecha paso |
| EventLifecycleService | Sistema (reactivo) | Auto-activar evento al publicar invitación |
| ApprovalWorkflowService | Sistema (reactivo) | Disparar activación al aprobar invitación |
6. Restricciones y Limites
| Restriccion | Valor | Descripción |
|---|---|---|
| Max invitaciones por evento | 3 | Máximo 3 invitaciones (internas o externas) por evento |
| Max versiones por invitación | 50 | Solo aplica a invitaciones internas |
| EventAccessCode | Unico global | El código de 8 caracteres es único en toda la plataforma |
| PIN | 4 digitos | Hasheado con bcrypt, no recuperable |
| Cron auto-complete | Cada hora | EventSchedulerService ejecuta cada 60 minutos |
7. Archivos Clave
| Archivo | Ubicación | Responsabilidad |
|---|---|---|
events.service.ts | src/modules/events/ | CRUD de eventos, validaciones de negocio |
event-lifecycle.service.ts | src/modules/events/services/ | Activación automática al publicar invitación |
event-scheduler.service.ts | src/modules/events/services/ | Cron job de auto-complete cada hora |
event-access-code.service.ts | src/modules/events/services/ | Generación y validación de códigos de acceso |
events.controller.ts | src/modules/events/ | Endpoints REST del dominio eventos |
8. Diagrama de Flujo Completo
Flujo Completo — Ciclo de Vida del Evento
Borrador
Activo
Finalizacion
9. Consideraciones de Timezone
- Cron de auto-complete: Ejecuta cada hora en UTC. La comparacion
endDatemenor o igual anowusa UTC. - Fechas del evento: Se almacenan en UTC en la base de datos. La conversión a timezone local se hace en el frontend.
- Cierre de invitaciones por evento completado: Usa timezone
America/Mexico_Citypara el cron diario de medianoche que cierra invitaciones de eventos pasados (complementario al cron horario de auto-complete de eventos).
10. Relación con Otros Flujos
| Flujo relacionado | Relación |
|---|---|
| Ciclo de Vida de la Invitación | La publicación de invitación dispara la activación del evento |
| Flujo del Invitado | Los invitados solo pueden interactuar con eventos en estado ACTIVE |
| Flujo de Comunicaciones | Los workflows se activan al pasar a ACTIVE y se pausan al COMPLETED/CANCELLED |
| Flujo de Pagos | Los PaymentLinks solo funcionan para eventos ACTIVE |