Documentacion tecnica del backend NestJS que expone la API REST de Nvito.
Framework: NestJS 11 | ORM: Prisma | Auth: Clerk | Queue: Bull/Redis | Payments: Stripe
La API esta compuesta por 39 modulos de dominio organizados en 9 dominios funcionales, mas 6 modulos de infraestructura (45 modulos totales).
Dominio Modulos Descripcion Core auth, organizations, users, roles, admin, packages, healthAutenticacion, multitenancy, RBAC y administracion del sistema Eventos events, event-types, event-services, contracts, clientsCiclo de vida de eventos, catalogo de tipos, servicios habilitados, contratos de venta y gestion de clientes Invitaciones invitations, sections, templates, html-generationCreacion, edicion visual, plantillas artesanales y compilacion HTML Invitados guests, guest-groups, rsvp, tablesGestion de invitados, grupos familiares, confirmaciones y asignacion de mesas Features locations, itinerary, qr-passes, gift-registry, accommodation, background-music, musicFuncionalidades opcionales habilitables por evento Media media, storage, custom-domainSubida de archivos a R2, galeria, audio guestbook y dominios personalizados IA ai-generationGeneracion y modificacion de invitaciones con IA (OpenAI/Anthropic) Comunicaciones notifications, notification-channels, communications, queue, schedulerEnvio de emails/WhatsApp/push, colas Bull y tareas programadas Pagos paymentsIntegracion con Stripe: links de pago, webhooks, historial Movil mobile, mobile-authEndpoints dedicados para app movil, auth independiente de Clerk Analitica analyticsTracking de vistas, RSVP analytics y metricas por evento
Modulo Funcion PrismaModuleConexion a PostgreSQL con soporte multi-tenant CommonModuleServicios compartidos: EncryptionService, CacheService, OrganizationResolverService, RedisThrottlerStorage ActivityLogModuleSistema de auditoria global (tabla audit_log) PermissionsModuleSistema RBAC con permisos granulares MetricsModuleMetricas de rendimiento y uso del sistema ConfigModuleConfiguracion centralizada con validacion Zod WinstonModuleLogging con rotacion diaria de archivos ThrottlerModuleRate limiting respaldado por Redis
Todos los endpoints tienen el prefijo global /v1. Las rutas marcadas con "Public" no requieren autenticacion.
Health /v1GET /v1/healthVerificar estado de salud de la API y sus dependencias (BD, Redis, memoria)
Auth — Webhooks /v1POST /v1/webhooks/clerkRecibir y procesar webhooks de Clerk para sincronizar usuarios (creacion, actualizacion, eliminacion)
Auth — Validacion de Invitaciones /v1GET /v1/auth/validate-invitation/:tokenValidar token de invitacion de registro (verifica existencia, estado y expiracion)
Organizations — Admin Panel /v1GET /v1/organizations[ADMIN] Listar todas las organizaciones del sistema con paginacion y busqueda
POST /v1/organizations[SUPER ADMIN] Crear nueva organizacion en Clerk y en la base de datos
GET /v1/organizations/:id[ADMIN] Obtener detalles completos de una organizacion por ID
GET /v1/organizations/:id/stats[ADMIN] Obtener estadisticas detalladas de una organizacion
PATCH /v1/organizations/:id[SUPER ADMIN] Actualizar cualquier campo de una organizacion incluyendo plan y limites
DELETE /v1/organizations/:id[SUPER ADMIN] Soft-delete de una organizacion por ID
Organizations — Tenant /v1GET /v1/organizations/currentObtener la organizacion actual del usuario autenticado
PATCH /v1/organizations/currentActualizar la organizacion actual (solo Owner)
GET /v1/organizations/statsObtener estadisticas de uso de la organizacion actual
Users /v1GET /v1/users/me/statusObtener estado de activacion de la cuenta del usuario actual (accesible por usuarios inactivos)
GET /v1/users/me/permissionsObtener todos los roles y permisos del usuario autenticado
GET /v1/users/me/organizationObtener la organizacion del usuario actual
GET /v1/users/meObtener perfil completo del usuario actual con organizacion y permisos
GET /v1/usersListar usuarios de la organizacion actual con paginacion y filtros
GET /v1/users/:idObtener detalle de un usuario especifico de la organizacion
PATCH /v1/users/:id/roleActualizar el rol de un usuario (solo Owner)
DELETE /v1/users/:idEliminar un usuario con soft delete (solo Owner)
Roles — Asignacion y Gestion /v1POST /v1/roles/assignAsignar un rol a un usuario (requiere permiso roles:assign:org)
PATCH /v1/roles/:roleIdActualizar el tipo de rol de un usuario (requiere permiso roles:assign:org)
DELETE /v1/roles/:roleIdRevocar un rol de un usuario (requiere permiso roles:revoke)
GET /v1/roles/users/:userIdListar todos los roles de un usuario (requiere SUPER_ADMIN, ORG_OWNER u ORG_ADMIN)
Roles — Colaboradores de Evento /v1GET /v1/roles/events/:eventId/collaboratorsListar todos los colaboradores de un evento
POST /v1/roles/events/:eventId/inviteInvitar a un colaborador a un evento (requiere permiso roles:assign:event)
GET /v1/roles/events/:eventId/invitationsListar todas las invitaciones de colaboradores de un evento
Roles — Invitaciones de Colaborador /v1GET /v1/roles/invitations/pendingListar invitaciones de colaborador pendientes del usuario actual
POST /v1/roles/invitations/:token/acceptAceptar una invitacion de colaborador usando el token
POST /v1/roles/invitations/:token/rejectRechazar una invitacion de colaborador
DELETE /v1/roles/invitations/:invitationIdCancelar una invitacion pendiente (requiere permiso roles:assign:org)
Admin — System Health /v1GET /v1/admin/healthObtener estado de salud del sistema (BD, Redis, colas, metricas de proceso, estadisticas)
GET /v1/admin/health/storageObtener uso de almacenamiento por organizacion (top organizaciones)
GET /v1/admin/health/activityObtener actividad reciente del sistema (registros de auditoria)
Admin — Usuarios /v1GET /v1/admin/users[ADMIN] Listar todos los usuarios del sistema con paginacion y filtros
GET /v1/admin/users/:id[ADMIN] Obtener detalles completos de un usuario especifico
PATCH /v1/admin/users/:id[ADMIN] Actualizar datos de un usuario desde el panel de administracion
DELETE /v1/admin/users/:id[SUPER ADMIN] Desactivar un usuario del sistema
Admin — Invitaciones (Pre-registros) /v1POST /v1/admin/users/invite[ADMIN] Crear invitacion (pre-registro) para un nuevo usuario
GET /v1/admin/users/invitations[ADMIN] Listar invitaciones (pre-registros) del sistema con filtros
GET /v1/admin/users/invitations/:id[ADMIN] Obtener detalles de una invitacion especifica
DELETE /v1/admin/users/invitations/:id[SUPER ADMIN] Cancelar una invitacion pendiente
POST /v1/admin/users/invitations/:id/resend[ADMIN] Reenviar email de invitacion y extender fecha de expiracion
Admin — Roles y Estadisticas /v1GET /v1/admin/roles[ADMIN] Listar todas las asignaciones de roles del sistema
GET /v1/admin/stats[ADMIN] Obtener metricas generales del sistema
GET /v1/admin/organizations/:orgId/events[ADMIN] Listar eventos de una organizacion (para selector de roles)
Packages — Paquetes de Servicios /v1GET /v1/admin/packages[ADMIN] Listar todos los paquetes de servicios con conteo de eventos
GET /v1/admin/packages/:id[ADMIN] Obtener detalle de un paquete con estadisticas de uso
POST /v1/admin/packages[SUPER ADMIN] Crear un nuevo paquete de servicios
PATCH /v1/admin/packages/:id[SUPER ADMIN] Actualizar un paquete existente (el slug no se puede cambiar)
DELETE /v1/admin/packages/:id[SUPER ADMIN] Eliminar un paquete (solo si no tiene eventos activos o en borrador)
GET /v1/admin/packages/:id/impact[ADMIN] Obtener analisis de impacto antes de eliminar o desactivar un paquete
GET /v1/admin/packages/:id/events[ADMIN] Listar eventos que usan un paquete especifico
POST /v1/admin/packages/backfill[SUPER ADMIN] Backfill de packageId en EventServiceConfigs historicos que tienen basePreset pero no packageId
POST /v1/eventsCrear un nuevo evento
GET /v1/eventsListar eventos con paginacion y filtros
GET /v1/events/:idObtener detalle de un evento por ID
PATCH /v1/events/:idActualizar un evento. Bloqueado si la invitacion esta publicada o cerrada.
DELETE /v1/events/:idEliminar un evento (soft delete)
GET /v1/events/:id/invitationsObtener invitaciones de un evento
POST /v1/events/:id/cancelCancelar un evento manualmente. Cierra todas las invitaciones activas.
GET /v1/events/:id/can-reopenVerificar si las invitaciones del evento pueden ser reabiertas
GET /v1/events/:id/calendar.icsDescargar archivo ICS para agregar el evento al calendario (publico, sin autenticacion)
GET /v1/events/:id/calendar-linksObtener URLs de Google Calendar, Outlook e ICS para el evento (publico)
GET /v1/events/:id/report.pdfGenerar y descargar reporte post-evento en PDF
GET /v1/events/:id/guestbook.pdfGenerar y descargar PDF compilatorio del guestbook del evento
GET /v1/event-typesListar todos los tipos de eventos disponibles
GET /v1/event-types/:idObtener tipo de evento por ID
GET /v1/event-types/slug/:slugObtener tipo de evento por slug
GET /v1/events/:eventId/servicesObtener la configuracion de servicios del evento
POST /v1/events/:eventId/servicesCrear la configuracion de servicios del evento
PATCH /v1/events/:eventId/servicesActualizar la configuracion de servicios del evento
DELETE /v1/events/:eventId/servicesEliminar la configuracion de servicios (vuelve a default)
POST /v1/events/:eventId/services/toggleHabilitar o deshabilitar un servicio individual
POST /v1/events/:eventId/services/apply-presetAplicar un preset de paquete al evento
POST /v1/events/:eventId/services/analyze-impactAnalizar el impacto de deshabilitar servicios
POST /v1/events/:eventId/services/analyze-preset-changeAnalizar el impacto de cambiar a un preset diferente
POST /v1/events/:eventId/services/cleanupLimpiar datos de servicios deshabilitados (solo eventos en DRAFT)
GET /v1/events/:eventId/services/check/:serviceTypeVerificar si un servicio especifico esta habilitado
GET /v1/event-services/definitionsObtener todas las definiciones de servicios disponibles (publico)
GET /v1/event-services/presetsObtener todos los presets de paquetes disponibles (publico)
POST /v1/admin/contractsRegistrar un nuevo contrato de venta
GET /v1/admin/contractsListar contratos con paginacion y filtros
GET /v1/admin/contracts/available-eventsObtener eventos disponibles que aun no tienen contrato
GET /v1/admin/contracts/:idObtener detalle de un contrato
PATCH /v1/admin/contracts/:idActualizar un contrato (todos los campos excepto eventId son opcionales)
DELETE /v1/admin/contracts/:idEliminar un contrato (requiere Super Admin)
GET /v1/admin/sales/summaryObtener KPIs de ventas del periodo indicado
GET /v1/admin/sales/by-packageObtener ingresos agrupados por paquete
GET /v1/admin/sales/by-serviceObtener servicios mas demandados
GET /v1/admin/sales/trendsObtener tendencias de ventas por periodo
POST /v1/admin/clientsRegistrar un nuevo cliente en la organizacion
GET /v1/admin/clientsListar clientes con paginacion y filtros
GET /v1/admin/clients/:idObtener detalle de un cliente
PATCH /v1/admin/clients/:idActualizar un cliente (todos los campos opcionales)
DELETE /v1/admin/clients/:idEliminar un cliente via soft delete (requiere Super Admin)
POST /v1/invitationsCrear una nueva invitacion para un evento
GET /v1/invitations/:idObtener detalle de una invitacion por ID
PATCH /v1/invitations/:idActualizar una invitacion existente
DELETE /v1/invitations/:idEliminar una invitacion
POST /v1/invitations/:id/publishPublicar una invitacion haciendola accesible publicamente
POST /v1/invitations/:id/unpublishDespublicar una invitacion, removiendola del acceso publico
POST /v1/invitations/:id/closeCerrar una invitacion publicada
POST /v1/invitations/:id/reopenReabrir una invitacion cerrada (CLOSED a PUBLISHED). Solo si la fecha del evento no ha pasado.
POST /v1/invitations/:id/duplicateDuplicar una invitacion existente creando una copia
GET /v1/invitations/templatesObtener catalogo de templates artesanales disponibles (publico)
GET /v1/invitations/templates/:templateIdObtener metadatos de un template artesanal por su ID (publico)
GET /v1/invitations/variantsObtener catalogo de variantes de secciones agrupadas por tipo (publico)
GET /v1/invitations/loader-stylesObtener catalogo de estilos de pantalla de carga cinematica (publico)
GET /v1/invitations/transition-stylesObtener catalogo de estilos de transicion fullpage (publico)
GET /v1/invitations/public/:slugObtener invitacion publicada por slug (acceso publico)
GET /v1/invitations/slug/:slugObtener invitacion por slug (acceso publico)
POST /v1/invitations/:id/preview-tokenGenerar token JWT para previsualizacion publica de la invitacion (expira en 15 min)
GET /v1/invitations/preview/:tokenObtener previsualizacion compilada de invitacion por token (publico)
POST /v1/invitations/:id/render-draftRenderizar borrador de invitacion a HTML sin guardar en S3 (para preview en editor visual)
POST /v1/invitations/:id/generate-htmlGenerar HTML de la invitacion y subir a S3. Retorna URLs de los archivos.
POST /v1/invitations/:id/publish-htmlGenerar y publicar HTML de la invitacion (genera si es necesario y cambia estado a PUBLISHED)
POST /v1/invitations/:id/export-pngExportar invitacion como imagen PNG. Renderiza con navegador headless y sube a S3/R2.
POST /v1/invitations/:id/versionsCrear una nueva version snapshot del estado actual de la invitacion
GET /v1/invitations/:id/versionsObtener historial de versiones de una invitacion
GET /v1/invitations/:id/versions/statsObtener estadisticas de versiones de una invitacion
GET /v1/invitations/:id/versions/compareComparar dos versiones y obtener las diferencias
GET /v1/invitations/:id/versions/:versionNumberObtener una version especifica por su numero
POST /v1/invitations/:id/versions/:versionNumber/rollbackRestaurar la invitacion a una version anterior (crea una nueva version en el proceso)
POST /v1/invitations/:id/submit-for-approvalEnviar invitacion para aprobacion (IN_CONSTRUCTION a UNPUBLISHED)
POST /v1/invitations/:id/approveAprobar invitacion y publicarla (UNPUBLISHED a PUBLISHED)
POST /v1/invitations/:id/rejectRechazar invitacion o solicitar cambios (UNPUBLISHED a IN_CONSTRUCTION)
GET /v1/invitations/:id/approval-historyObtener historial de acciones de aprobacion de una invitacion
POST /v1/invitations/externalCargar una invitacion externa (HTML pre-diseñado)
PUT /v1/invitations/:id/external/reuploadRe-cargar el HTML de una invitacion externa existente (solo en estado IN_CONSTRUCTION)
GET /v1/invitations/:id/external/downloadDescargar el HTML original de una invitacion externa
POST /v1/invitations/:invitationId/sectionsCrear una nueva seccion en la invitacion
PATCH /v1/invitations/:invitationId/sections/:sectionIdActualizar una seccion existente de la invitacion
DELETE /v1/invitations/:invitationId/sections/:sectionIdEliminar una seccion de la invitacion
PUT /v1/invitations/:invitationId/sections/reorderReordenar las secciones de una invitacion
GET /v1/admin/templatesListar templates con paginacion y filtros
GET /v1/admin/templates/statsObtener estadisticas del catalogo de templates
GET /v1/admin/templates/variantsObtener catalogo de variantes de seccion disponibles
GET /v1/admin/templates/variants/:sectionTypeObtener variantes de un tipo de seccion especifico
GET /v1/admin/templates/:idObtener detalle de un template
POST /v1/admin/templatesCrear un nuevo template (estado DRAFT)
PATCH /v1/admin/templates/:idActualizar un template (el slug no se puede cambiar)
DELETE /v1/admin/templates/:idEliminar un template con soft delete y limpieza de archivos S3 (requiere Super Admin)
PATCH /v1/admin/templates/:id/statusCambiar estado de un template (DRAFT, ACTIVE, ARCHIVED)
POST /v1/admin/templates/:id/duplicateDuplicar un template existente
POST /v1/admin/templates/:id/buildEnsamblar HTML del template y subir a S3
POST /v1/admin/templates/:id/previewCompilar preview del template con sus datos de ejemplo
POST /v1/admin/templates/previewCompilar preview ad-hoc sin template guardado
Guests /v1POST /v1/guestsCrear un nuevo invitado para un evento
POST /v1/guests/importImportar invitados desde archivo CSV
GET /v1/guests/event/:eventIdListar invitados de un evento con paginacion y filtros
GET /v1/guests/event/:eventId/summaryObtener resumen de conteos de invitados por estado
GET /v1/guests/event/:eventId/dietaryObtener resumen de restricciones alimentarias de invitados
GET /v1/guests/:idObtener detalle de un invitado por ID
PATCH /v1/guests/:idActualizar datos de un invitado
DELETE /v1/guests/:idEliminar un invitado (soft delete)
Guest Groups /v1POST /v1/guest-groupsCrear un nuevo grupo de invitados
GET /v1/guest-groups/event/:eventIdListar todos los grupos de invitados de un evento
GET /v1/guest-groups/:idObtener detalle de un grupo con sus invitados
PATCH /v1/guest-groups/:idActualizar un grupo de invitados
DELETE /v1/guest-groups/:idEliminar grupo de invitados. Los invitados se desvinculan pero no se eliminan
RSVP /v1POST /v1/rsvpCrear o actualizar RSVP (endpoint PUBLICO, sin autenticacion)
GET /v1/rsvp/event/:eventIdListar RSVPs de un evento con paginacion y filtros
GET /v1/rsvp/event/:eventId/statsObtener estadisticas de RSVP de un evento
Tables /v1POST /v1/events/:eventId/tablesCrear una nueva mesa para un evento
GET /v1/events/:eventId/tablesListar todas las mesas de un evento con conteo de asignaciones
GET /v1/events/:eventId/tables/statsObtener estadisticas de mesas del evento
GET /v1/events/:eventId/tables/:idObtener detalle de una mesa con invitados asignados
PATCH /v1/events/:eventId/tables/:idActualizar una mesa
DELETE /v1/events/:eventId/tables/:idEliminar una mesa
POST /v1/events/:eventId/tables/:tableId/assignAsignar un invitado a una mesa
DELETE /v1/events/:eventId/tables/:tableId/assign/:guestIdDesasignar un invitado de una mesa
POST /v1/events/:eventId/tables/bulk-assignAsignar multiples invitados a mesas de forma masiva
Locations /v1POST /v1/locationsCrear una nueva ubicacion para un evento
GET /v1/locations/event/:eventIdListar todas las ubicaciones de un evento
GET /v1/locations/:idObtener detalle de una ubicacion
PATCH /v1/locations/:idActualizar una ubicacion
DELETE /v1/locations/:idEliminar una ubicacion
POST /v1/locations/geocodeConvertir direccion a coordenadas usando Mapbox
POST /v1/locations/reverse-geocodeConvertir coordenadas a direccion usando Mapbox
Itinerary /v1POST /v1/events/:eventId/itineraryCrear un nuevo item de itinerario
GET /v1/events/:eventId/itineraryListar todos los items del itinerario ordenados por hora y orden
GET /v1/events/:eventId/itinerary/:idObtener detalle de un item de itinerario
PATCH /v1/events/:eventId/itinerary/:idActualizar un item de itinerario
DELETE /v1/events/:eventId/itinerary/:idEliminar un item de itinerario
PUT /v1/events/:eventId/itinerary/reorderReordenar items del itinerario
QR Passes /v1POST /v1/events/:eventId/qr-passesGenerar pase QR para un invitado
POST /v1/events/:eventId/qr-passes/bulkGenerar pases QR masivamente para multiples invitados
POST /v1/events/:eventId/qr-passes/check-inCheck-in de un invitado escaneando codigo QR
GET /v1/events/:eventId/qr-passesListar todos los pases QR de un evento
GET /v1/events/:eventId/qr-passes/statsObtener estadisticas de pases QR del evento
GET /v1/events/:eventId/qr-passes/recent-check-insObtener check-ins recientes del evento
GET /v1/events/:eventId/qr-passes/downloadDescargar todos los pases QR como PDF
PATCH /v1/events/:eventId/qr-passes/:passId/cancelCancelar un pase QR
GET /v1/events/:eventId/qr-passes/guest/:guestIdObtener pase QR de un invitado especifico
Gift Registry /v1GET /v1/events/:eventId/gift-registryObtener o crear la configuracion de mesa de regalos del evento
PATCH /v1/events/:eventId/gift-registryActualizar configuracion de mesa de regalos
POST /v1/events/:eventId/gift-registry/itemsCrear un item en la mesa de regalos (tienda externa)
GET /v1/events/:eventId/gift-registry/itemsListar todos los items de la mesa de regalos
GET /v1/events/:eventId/gift-registry/items/:itemIdObtener detalle de un item de la mesa de regalos
PATCH /v1/events/:eventId/gift-registry/items/:itemIdActualizar un item de la mesa de regalos
DELETE /v1/events/:eventId/gift-registry/items/:itemIdEliminar un item de la mesa de regalos (soft delete)
POST /v1/events/:eventId/gift-registry/bank-accountsCrear una cuenta bancaria para la mesa de regalos
GET /v1/events/:eventId/gift-registry/bank-accountsListar todas las cuentas bancarias de la mesa de regalos
GET /v1/events/:eventId/gift-registry/bank-accounts/:accountIdObtener detalle de una cuenta bancaria
PATCH /v1/events/:eventId/gift-registry/bank-accounts/:accountIdActualizar una cuenta bancaria
DELETE /v1/events/:eventId/gift-registry/bank-accounts/:accountIdEliminar una cuenta bancaria (soft delete)
Accommodation /v1GET /v1/events/:eventId/accommodationObtener o crear la configuracion de hospedaje del evento
PUT /v1/events/:eventId/accommodationActualizar configuracion general de hospedaje
POST /v1/events/:eventId/accommodation/hotelsCrear un hotel asociado al hospedaje
PUT /v1/events/:eventId/accommodation/hotels/:hotelIdActualizar un hotel
DELETE /v1/events/:eventId/accommodation/hotels/:hotelIdEliminar un hotel (soft delete)
POST /v1/events/:eventId/accommodation/transportCrear una opcion de transporte
PUT /v1/events/:eventId/accommodation/transport/:optionIdActualizar una opcion de transporte
DELETE /v1/events/:eventId/accommodation/transport/:optionIdEliminar una opcion de transporte (soft delete)
Background Music /v1GET /v1/events/:eventId/background-musicObtener o crear la configuracion de musica de fondo del evento
PUT /v1/events/:eventId/background-musicActualizar configuracion general de musica de fondo
POST /v1/events/:eventId/background-music/tracksCrear una pista de musica
PUT /v1/events/:eventId/background-music/tracks/:trackIdActualizar una pista de musica
DELETE /v1/events/:eventId/background-music/tracks/:trackIdEliminar una pista de musica (soft delete)
POST /v1/events/:eventId/background-music/tracks/reorderReordenar pistas de musica
POST /v1/events/:eventId/background-music/upload-urlObtener URL presignada para subir archivo de audio (max 20MB)
POST /v1/events/:eventId/background-music/confirm-uploadConfirmar subida de archivo de audio y validar contenido
Music /v1POST /v1/music/invitation/:invitationIdAgregar pista de musica a una invitacion
GET /v1/music/invitation/:invitationIdListar pistas de musica de una invitacion
GET /v1/music/invitation/:invitationId/summaryObtener resumen del playlist de una invitacion
GET /v1/music/:id/invitation/:invitationIdObtener detalle de un track musical
PATCH /v1/music/:id/invitation/:invitationIdActualizar un track musical
DELETE /v1/music/:id/invitation/:invitationIdEliminar un track musical
POST /v1/music/invitation/:invitationId/reorderReordenar tracks del playlist
PATCH /v1/music/:id/invitation/:invitationId/toggle-activeAlternar estado activo/inactivo de un track
Media /v1POST /v1/events/:eventId/media/upload-urlObtener URL presignada para subir archivo multimedia
POST /v1/events/:eventId/media/confirm-uploadConfirmar subida y crear registro de media en BD
POST /v1/events/:eventId/media/bulk-uploadCrear multiples registros de media de forma masiva
GET /v1/events/:eventId/mediaListar todos los archivos multimedia del evento
GET /v1/events/:eventId/media/storage-usageObtener estadisticas de uso de almacenamiento
GET /v1/events/:eventId/media/recentObtener archivos subidos recientemente
GET /v1/events/:eventId/media/invitation-assetsObtener assets de diseno de invitacion (fondos)
GET /v1/events/:eventId/media/communication-assetsObtener assets para campanas de comunicacion
GET /v1/events/:eventId/media/galleryObtener fotos de galeria para seccion de invitacion
GET /v1/events/:eventId/media/gallery/statsObtener estadisticas de la galeria
POST /v1/events/:eventId/media/gallery/reorderReordenar imagenes de la galeria
GET /v1/events/:eventId/media/audio-guestbookObtener grabaciones del libro de audio de invitados
GET /v1/events/:eventId/media/audio-guestbook/statsObtener estadisticas del libro de audio
GET /v1/events/:eventId/media/guest-uploadsObtener archivos subidos por invitados
GET /v1/events/:eventId/media/guest-uploads/statsObtener estadisticas de uploads de invitados
GET /v1/events/:eventId/media/guest-messagesObtener mensajes de texto (felicitaciones) de invitados
GET /v1/events/:eventId/media/guest-messages/statsObtener estadisticas de mensajes de invitados
PATCH /v1/events/:eventId/media/guest-messages/:id/readMarcar un mensaje de invitado como leido
GET /v1/events/:eventId/media/countContar media por categoria
GET /v1/events/:eventId/media/:idObtener detalle de un archivo multimedia
PATCH /v1/events/:eventId/media/:idActualizar metadatos de un archivo multimedia
DELETE /v1/events/:eventId/media/:idEliminar un archivo multimedia (borra de R2 + soft delete en BD)
Custom Domain /v1POST /v1/events/:eventId/custom-domainCrear dominio personalizado para un evento
GET /v1/events/:eventId/custom-domainObtener dominio personalizado del evento
PUT /v1/events/:eventId/custom-domainActualizar dominio personalizado
DELETE /v1/events/:eventId/custom-domainEliminar dominio personalizado
POST /v1/events/:eventId/custom-domain/verifyVerificar configuracion DNS del dominio personalizado
AI Generation /v1POST /v1/ai-generation/generateGenerar invitacion completa a partir de un prompt de texto
POST /v1/ai-generation/generate-from-designGenerar invitacion a partir de un archivo de diseno (imagen o PDF, max 20MB)
POST /v1/ai-generation/modifyModificar invitacion existente usando IA conversacional
POST /v1/ai-generation/rewrite-toneReescribir textos de invitacion con un tono especifico
GET /v1/ai-generation/generations/:idObtener detalle de una generacion especifica
GET /v1/ai-generation/generationsListar todas las generaciones de IA de la organizacion
GET /v1/ai-generation/quotaObtener informacion de cuota y uso de generaciones de IA
Notificaciones /v1POST /v1/notifications/send-emailEnviar una notificacion por email
GET /v1/notificationsListar notificaciones con paginacion y filtros
GET /v1/notifications/statisticsObtener estadisticas de notificaciones (enviadas, fallidas, pendientes)
GET /v1/notifications/recentObtener notificaciones recientes
GET /v1/notifications/:idObtener detalle de una notificacion por ID
POST /v1/notifications/:id/retryReintentar envio de una notificacion fallida
Comunicaciones /v1POST /v1/communications/send-invitationEnviar invitacion digital (link) a invitados seleccionados
POST /v1/communications/send-reminderEnviar recordatorio RSVP a invitados pendientes
POST /v1/communications/send-messageEnviar mensaje personalizado a invitados
POST /v1/communications/send-save-the-dateEnviar Save the Date con imagen a invitados
POST /v1/communications/send-rsvp-chatbotEnviar campana RSVP por WhatsApp chatbot
POST /v1/communications/preview-messageGenerar preview de un mensaje antes de enviarlo
POST /v1/communications/estimate-recipientsEstimar cantidad de destinatarios segun filtros
POST /v1/communications/check-duplicateVerificar si existe campana duplicada reciente
GET /v1/communications/guests/:guestId/communicationsHistorial de comunicaciones enviadas a un invitado
GET /v1/communications/campaignsListar campanas de comunicacion de un evento
GET /v1/communications/campaigns/:idObtener detalle de una campana de comunicacion
GET /v1/communications/campaigns/:id/messagesObtener mensajes individuales de una campana
GET /v1/communications/statisticsEstadisticas de comunicacion de un evento
POST /v1/communications/messages/:id/retryReintentar envio de un mensaje fallido
Comunicaciones - Webhooks /v1POST /v1/communications/webhooks/twilioWebhook de actualizaciones de estado de mensajes desde Twilio/WhatsApp
POST /v1/communications/webhooks/twilio/incomingWebhook de mensajes entrantes de WhatsApp para el chatbot RSVP
Plantillas de Comunicacion /v1POST /v1/communications/templatesCrear una nueva plantilla de comunicacion
GET /v1/communications/templatesListar plantillas de comunicacion con filtros
GET /v1/communications/templates/:idObtener detalle de una plantilla
PATCH /v1/communications/templates/:idActualizar una plantilla de comunicacion
DELETE /v1/communications/templates/:idArchivar una plantilla (soft delete)
POST /v1/communications/templates/:id/duplicateDuplicar una plantilla existente
POST /v1/communications/templates/:id/set-defaultMarcar plantilla como predeterminada para su tipo de campana
Workflows de Comunicacion /v1POST /v1/communication-workflowsCrear un nuevo workflow de comunicacion automatica
GET /v1/communication-workflowsListar workflows de un evento
GET /v1/communication-workflows/:idObtener detalle de un workflow
PATCH /v1/communication-workflows/:idActualizar un workflow (no se puede cambiar eventId ni trigger)
DELETE /v1/communication-workflows/:idEliminar un workflow
PATCH /v1/communication-workflows/:id/toggleActivar o pausar un workflow
Gestion de Colas /v1GET /v1/queue/statsObtener estadisticas de una cola de mensajes
GET /v1/queue/job/:jobIdObtener estado de un job por ID
POST /v1/queue/job/:jobId/retryReintentar un job fallido
DELETE /v1/queue/job/:jobIdEliminar un job de la cola
POST /v1/queue/pausePausar una cola de mensajes
POST /v1/queue/resumeReanudar una cola de mensajes pausada
POST /v1/queue/cleanLimpiar jobs completados de una cola (mas de 1 hora)
Pagos - Admin /v1POST /v1/admin/payments/linksGenerar link de pago para un contrato
GET /v1/admin/paymentsListar pagos de un evento con filtros y paginacion
GET /v1/admin/payments/:idObtener detalle de un pago
GET /v1/admin/contracts/:contractId/payment-linksListar links de pago de un contrato con resumen financiero
PATCH /v1/admin/payment-links/:linkId/cancelCancelar un link de pago activo
Pagos - Mobile (Cash Fund) /v1POST /v1/mobile/payments/cash-fund/intentCrear PaymentIntent para contribucion al cash fund (sobre de dinero digital)
POST /v1/mobile/payments/cash-fund/:paymentId/confirmConfirmar pago del cash fund
Pagos - Publico /v1GET /v1/pay/verify-sessionVerificar estado de Checkout Session con Stripe
GET /v1/pay/:tokenValidar link de pago y obtener datos del contrato
POST /v1/pay/:token/checkoutCrear Stripe Checkout Session para procesar el pago
Pagos - Webhooks /v1POST /v1/webhooks/stripeWebhook de eventos de Stripe (checkout.session.completed, payment_intent.succeeded, etc.)
Autenticacion Movil /v1POST /v1/mobile/auth/loginLogin como anfitrion con codigo de evento y PIN
POST /v1/mobile/auth/guest-accessAcceso como invitado con token unico (via deep link o QR)
POST /v1/mobile/auth/refreshRenovar tokens de acceso (rotacion segura)
POST /v1/mobile/auth/logoutCerrar sesion movil
POST /v1/mobile/auth/register-pushRegistrar token de push notifications (Expo)
GET /v1/mobile/auth/meObtener informacion de la sesion actual
Codigos de Acceso de Eventos /v1GET /v1/events/:eventId/access-codesListar codigos de acceso del evento
POST /v1/events/:eventId/access-codesCrear codigo de acceso con PIN autogenerado (visible una sola vez)
POST /v1/events/:eventId/access-codes/:codeId/regenerate-pinRegenerar PIN de un codigo de acceso (visible una sola vez)
POST /v1/events/:eventId/access-codes/:codeId/send-whatsappEnviar credenciales de acceso por WhatsApp al cliente del evento
PATCH /v1/events/:eventId/access-codes/:codeIdActualizar codigo de acceso (activar/desactivar)
DELETE /v1/events/:eventId/access-codes/:codeIdEliminar codigo de acceso
Mobile - Eventos /v1GET /v1/mobile/events/:idObtener datos del evento (filtrado segun rol HOST/GUEST)
GET /v1/mobile/events/:id/statsEstadisticas del evento en tiempo real (solo HOST)
GET /v1/mobile/events/:id/servicesServicios habilitados del evento
GET /v1/mobile/events/:id/itineraryItinerario del evento
GET /v1/mobile/events/:id/locationsUbicaciones del evento
GET /v1/mobile/events/:id/gift-registryMesa de regalos del evento
GET /v1/mobile/events/:id/accommodationInformacion de hospedaje del evento
GET /v1/mobile/events/:id/rsvp/statsEstadisticas RSVP del evento
Mobile - Check-in /v1POST /v1/mobile/events/:eventId/check-inEscanear QR y registrar check-in (solo HOST)
POST /v1/mobile/events/:eventId/check-in/manualCheck-in manual por nombre de invitado (solo HOST)
GET /v1/mobile/events/:eventId/check-in/statsEstadisticas de check-in en vivo (solo HOST)
GET /v1/mobile/events/:eventId/check-in/recentCheck-ins recientes (solo HOST)
Mobile - Invitados /v1GET /v1/mobile/events/:eventId/guestsLista de invitados con estados (solo HOST)
GET /v1/mobile/events/:eventId/guests/statsResumen de invitados del evento (solo HOST)
GET /v1/mobile/events/:eventId/guests/offline/qr-passesQR passes para cache offline en check-in sin internet (solo HOST)
GET /v1/mobile/events/:eventId/guests/me/qr-passObtener mi pase QR de invitado (solo GUEST)
GET /v1/mobile/events/:eventId/guests/:guestIdDetalle completo de un invitado (solo HOST)
Mobile - Media /v1GET /v1/mobile/events/:eventId/galleryGaleria de fotos del evento
GET /v1/mobile/events/:eventId/gallery/my-countCantidad de fotos subidas por el invitado (solo GUEST)
POST /v1/mobile/events/:eventId/gallery/upload-urlObtener URL presignada para subir foto a la galeria
POST /v1/mobile/events/:eventId/galleryRegistrar foto subida en la galeria
GET /v1/mobile/events/:eventId/audio-guestbookMensajes de audio del guestbook
POST /v1/mobile/events/:eventId/audio-guestbook/upload-urlObtener URL presignada para subir audio al guestbook
POST /v1/mobile/events/:eventId/audio-guestbookRegistrar audio subido al guestbook
PATCH /v1/mobile/events/:eventId/audio-guestbook/:audioId/approveAprobar mensaje de audio del guestbook (solo HOST)
GET /v1/mobile/events/:eventId/messagesMensajes de texto de invitados (solo HOST)
GET /v1/mobile/events/:eventId/messages/my-countCantidad de mensajes enviados por el invitado (solo GUEST)
POST /v1/mobile/events/:eventId/messagesDejar mensaje de texto para los anfitriones (solo GUEST)
Mobile - Sharing /v1GET /v1/mobile/events/:eventId/sharing/countdownGenerar card de countdown del evento para compartir
GET /v1/mobile/events/:eventId/sharing/confirmedGenerar card de confirmacion para compartir (solo GUEST confirmado)
GET /v1/mobile/events/:eventId/sharing/highlightGenerar card con datos clave del evento para compartir
Mobile - Mesas /v1GET /v1/mobile/events/:eventId/tablesLista de mesas con asignaciones de invitados (solo HOST)
GET /v1/mobile/events/:eventId/tables/statsEstadisticas de ocupacion de mesas (solo HOST)
Analiticas /v1POST /v1/events/:eventId/analytics/trackRegistrar evento de analitica (endpoint publico para nvito-invitations)
GET /v1/events/:eventId/analytics/overviewVista general de analiticas del evento
GET /v1/events/:eventId/analytics/guestsAnaliticas de invitados del evento
GET /v1/events/:eventId/analytics/rsvpAnaliticas de RSVP del evento
GET /v1/events/:eventId/analytics/engagementPuntajes de engagement por visitante
GET /v1/events/:eventId/analytics/timelineAnaliticas de actividad a lo largo del tiempo
GET /v1/events/:eventId/analytics/invitations/:invitationId/summaryResumen de analiticas de una invitacion especifica
GET /v1/events/:eventId/analytics/invitations/:invitationId/detailedAnaliticas detalladas de una invitacion especifica
GET /v1/events/:eventId/analytics/channel-effectivenessMetricas de efectividad por canal (email vs WhatsApp)
GET /v1/events/:eventId/analytics/best-send-timeAnalisis del mejor horario de envio de comunicaciones
GET /v1/events/:eventId/analytics/response-funnelEmbudo de respuestas (enviado, entregado, abierto, RSVP)
Configurado globalmente en main.ts para validar todos los DTOs entrantes:
app . useGlobalPipes (
new ValidationPipe ({
whitelist : true , // Elimina propiedades no declaradas en el DTO
forbidNonWhitelisted : true , // Rechaza requests con propiedades no declaradas
transform : true , // Transforma payloads al tipo del DTO
transformOptions : {
enableImplicitConversion : true , // Convierte tipos automaticamente
},
}),
);
Filtro de excepciones que sanitiza errores en produccion para evitar exponer detalles internos del sistema al cliente.
Interceptor global que registra automaticamente acciones criticas de modificacion:
Metodos auditados : POST, PATCH, PUT, DELETE (no GET)
Paths criticos : /users, /events, /guests, /invitations, /organizations, /templates, /rsvp, /locations, /itinerary, /tables
Solo audita : Requests autenticados (con usuario)
No bloquea : La auditoria es asincrona, no afecta el tiempo de respuesta
Registra : userId, organizationId, action (create/update/delete), resource, resourceId, IP, userAgent, metadata (path, method, body sanitizado)
Para Super Admin : Resuelve organizationId desde el recurso o evento padre via consulta a BD
Prefijo global: /v1
Ejemplo: http://localhost:3000/v1/events
Disponible solo en entornos no-produccion :
URL: /api/docs
Incluye documentacion interactiva con esquemas de request/response, autenticacion Bearer y tags por modulo.
Middleware Funcion Helmet Headers de seguridad (CSP, HSTS, X-Frame-Options, noSniff) CORS Origen validado contra whitelist; wildcard prohibido en produccion Compresion gzip Comprime responses > 1KB (reduce bandwidth 70-90%) Body limits Maximo 20MB para JSON y URL-encoded (para uploads) Headers adicionales X-Permitted-Cross-Domain-Policies, Referrer-Policy, Permissions-Policy
ClerkAuthGuard - Autenticacion JWT (valida token de Clerk, resuelve usuario en BD)
UserThrottlerGuard - Rate limiting (100 req/min por usuario o IP)
RoleGuard - Autorizacion basada en roles RBAC
Todos los modulos siguen el mismo patron estandar de NestJS:
src/modules/events/
events.module.ts # Registra controller, services e imports
events.controller.ts # Recibe HTTP, valida DTO, delega al service
events.service.ts # Logica de negocio principal (facade)
services/ # Sub-servicios con responsabilidad unica (SRP)
event-query.service.ts # Consultas de lectura
event-mutation.service.ts # Operaciones de escritura
event-capacity.service.ts # Calculo de capacidad
event-admin-query.service.ts # Consultas admin
dto/
create-event.dto.ts # Validacion de entrada con class-validator
update-event.dto.ts # DTO parcial (PartialType)
query-events.dto.ts # Parametros de paginacion y filtros
Los modulos complejos extraen logica en sub-servicios dentro de un directorio services/. El servicio principal actua como facade, delegando a sub-servicios especializados:
Modulo Sub-servicios Responsabilidad eventsevent-query, event-mutation, event-capacity, event-admin-querySeparacion lectura/escritura/admin organizationsorganization-adminMetodos Super Admin separados del tenant analyticsevent-analytics, invitation-analytics, report-data, pdf-builderAnaliticas por dominio y generacion de reportes invitationsinvitation-lifecycle, invitation-section, version-manager, approval-workflow, preview-token, png-exportCiclo de vida, secciones, versiones, aprobacion ai-generationprompt-builder, schema-section-builder, vision-provider, design-extraction, ai-modification, generation-cost, enrich-prompt, ai-provider-orchestrator, invitation-schema-builderPipeline de generacion IA communicationscampaign-query, invitation-dispatcher, message-dispatcher, recipient-filter, reminder-message-dispatcher, recipient-estimator, spam-prevention, smart-routing, message-preview, communication-templateEnvio por tipo, filtrado, templates, preview, spam prevention y routing paymentspayment-link, stripe-webhookLinks de pago y webhooks Stripe tablestable-assignment, table-statsAsignacion y estadisticas mobilemobile-events, mobile-guests, mobile-check-in, mobile-media, mobile-sharing, card-generatorEndpoints movil por dominio adminadmin-statistics, admin-user, admin-invitationPanel de administracion html-generationtemplate-compiler, schema-compiler, template-builder, html-optimizer, artisan-template-registryPipeline de compilacion HTML qr-passesqr-generation, qr-check-inGeneracion y validacion QR guestsguest-statsEstadisticas de invitados contractscontract-analyticsAnaliticas de contratos mediamedia-analyticsAnaliticas de media event-servicesevent-service-toggleToggle de servicios
Total: 61 sub-servicios distribuidos en 17 modulos, lo que mantiene cada archivo enfocado en una sola responsabilidad.
@ Module ({
imports : [ PrismaModule , CommonModule ],
controllers : [ EventsController ],
providers : [ EventsService ],
exports : [ EventsService ], // Exporta el service para uso en otros modulos
})
export class EventsModule {}
@ ApiTags ( 'events' )
@ ApiBearerAuth ()
@ Controller ( 'events' )
@ UseGuards ( ClerkAuthGuard )
export class EventsController {
constructor ( private readonly eventsService : EventsService ) {}
@ Post ()
@ UseGuards ( PermissionsGuard )
@ RequirePermission ( PERMISSIONS . EVENTS_CREATE_ORG )
async create (
@ CurrentUser () user : AuthenticatedUser ,
@ Body () createEventDto : CreateEventDto ,
) {
return this . eventsService . create ( organizationId , user . userId , createEventDto );
}
}
@ Injectable ()
export class EventsService {
constructor ( private readonly prisma : PrismaService ) {}
async create ( orgId : string , userId : string , dto : CreateEventDto ) {
return this . prisma . event . create ({
data : {
... dto ,
organizationId : orgId ,
createdBy : userId ,
},
});
}
}
export class CreateEventDto {
@ IsString ()
@ IsNotEmpty ()
@ MaxLength ( 200 )
name : string ;
@ IsUUID ()
eventTypeId : string ;
@ IsDateString ()
date : string ;
@ IsOptional ()
@ IsString ()
@ MaxLength ( 2000 )
description ? : string ;
}
ThrottlerModule . forRootAsync ({
imports : [ CommonModule ],
useFactory : ( redisStorage : RedisThrottlerStorage ) => ({
throttlers : [{ ttl : 60000 , limit : 100 }], // 100 requests por minuto
storage : redisStorage , // Respaldado por Redis
}),
inject : [ RedisThrottlerStorage ],
}),
Limite global : 100 peticiones por minuto
Tracking : Por usuario autenticado (userId) o por IP (para endpoints publicos)
Storage : Redis (compatible con multiples instancias del servidor)
Excepciones : El endpoint /health usa @SkipThrottle() para bypasear el limite
Override por endpoint : El webhook de Clerk tiene limite personalizado de 50 req/min via @Throttle({ default: { limit: 50, ttl: 60000 } })
Todos los DTOs utilizan decoradores de class-validator para validar datos de entrada:
@IsString(), @IsNumber(), @IsUUID(), @IsEmail() - Validacion de tipos
@IsNotEmpty(), @IsOptional() - Campos requeridos vs opcionales
@MaxLength(), @MinLength(), @Min(), @Max() - Limites de longitud/valor
@IsDateString(), @IsEnum() - Formatos especificos
@ValidateNested() con @Type() - Objetos anidados
Se usa class-transformer para transformar payloads entrantes:
enableImplicitConversion: true convierte strings a numeros, booleanos, etc.
@Type(() => Number) para transformar tipos en objetos anidados
@Exclude() para omitir campos sensibles en respuestas
Las variables de entorno se validan al arranque con un schema Zod en config/env.validation.ts:
const envSchema = z . object ({
DATABASE_URL : z . string (). min ( 1 , 'DATABASE_URL es requerida' ),
NODE_ENV : z . enum ([ 'development' , 'staging' , 'production' , 'test' ]). default ( 'development' ),
PORT : z . coerce . number (). int (). positive (). default ( 3000 ),
CLERK_SECRET_KEY : z . string (). min ( 1 ),
CLERK_PUBLISHABLE_KEY : z . string (). min ( 1 ),
REDIS_URL : z . string (). default ( 'redis://localhost:6379' ),
// ... mas variables
});
Si alguna variable requerida falta o es invalida, la aplicacion no arranca y muestra un mensaje claro del error.
Patron Uso Ejemplo Create{Entity}DtoCreacion de recurso CreateEventDtoUpdate{Entity}DtoActualizacion parcial (PartialType) UpdateEventDtoQuery{Entity}DtoParametros de lista/busqueda/paginacion QueryEventsDto{Action}{Entity}DtoAcciones especificas AssignGuestDto, ToggleServiceDto{Entity}ResponseDtoFormato de respuesta GenerationResultDto
Metrica Cantidad Modulos totales 45 (39 de dominio + 6 de infraestructura) Controladores 49 Servicios 136 (75 principales + 61 sub-servicios) Endpoints HTTP 369 DTOs 100 Guards 11 Interceptors 3 Processors (Bull) 3 (email, whatsapp, push) Filtros 1 (GlobalExceptionFilter) Modelos Prisma 51 Enums Prisma 36 Tests 207 suites / 3311+ tests (100% green) Cobertura servicios 116/116 (100%) Cobertura controllers 48/48 (100%) -- excluye 2 controllers publicos sin logica testeable Cobertura guards 11/11 (100%)
Para referencia cruzada, las metricas del panel de administracion:
Metrica Cantidad Test suites 133 Tests individuales 1,347 (100% green) Framework de tests Vitest 4.x + Testing Library Server Actions 16 archivos (todos con Zod validation) API Services 33 archivos con tests React Query Hooks 35+ archivos con tests Esquemas Zod 15 (todos con tests) Componentes UI (shadcn) 41+ React Compiler Habilitado CSP Headers Configurados Accesibilidad aria-sort, aria-label, keyboard nav
Archivo Ruta App Module nvito-api/src/app.module.tsBootstrap nvito-api/src/main.tsAudit Interceptor nvito-api/src/common/interceptors/audit.interceptor.tsEnv Validation nvito-api/src/config/env.validation.tsThrottler Guard nvito-api/src/common/throttler/user-throttler.guard.tsRedis Storage nvito-api/src/common/throttler/redis-throttler.storage.tsGlobal Exception Filter nvito-api/src/common/filters/global-exception.filter.ts