Wiki / Documentación interna / Plataforma

Sistema de tickets (interno)

ADR 018. Ver también la versión funcional de esta misma página.

Tablas

  • support_tickets: datos del reportante, urgencia, asunto (lista cerrada de 9 valores en src/config/tickets.ts), status (abierto/cerrado), y escalated_at/escalated_by como flag independiente del estado — no un tercer valor, para que un ticket escalado pueda seguir gestionándose y cerrarse sin dejar de estar escalado.
  • support_ticket_messages: hilo de respuestas, author_type ∈ sociedad/superadmin. Sin edición ni updated_at: es un registro de lo dicho, no un documento editable.

Único punto de entrada público

crear_ticket_soporte(p_society_slug, ...), security definer: valida que la sociedad exista, esté activa y tenga el módulo soporte encendido (global + por sociedad) antes de insertar nada. Encola notificar_ticket_soporte_creado y dispara la cola de inmediato.

Protección de campos del reportante

Trigger private.proteger_campos_ticket_soporte(): revierte nombre, correo, teléfono, urgencia, asunto y comentario originales en cualquier UPDATE — sin excepción para superadmin. Solo pueden cambiar status, escalated_at/by y resolved_at.

RLS

Quién Puede ver / actualizar
society_admin / society_staff Todos los tickets de su propia sociedad
superadmin Solo tickets con escalated_at is not null — nunca el listado completo de ninguna sociedad
anon Ninguno (sin política de SELECT; la única entrada es la función security definer)

Respuesta y escalado

  • responderTicket(): manda el correo directo al reportante (su dirección ya está en el propio ticket) — sin pasar por job_queue, a diferencia de una invitación que sí necesita el Admin API.
  • escalarTicket(): marca escalated_at/by y encola notificar_ticket_soporte_escalado — avisa a superadmin por correo.
  • Sin política de DELETE en ninguna de las dos tablas: un ticket se cierra, no se borra.
  • Altas, cambios de estado y cada mensaje disparan registrar_auditoria().

Entrada desde el login

Desde el 19/09/2026, si una sociedad tiene login_personalizado y soporte activos a la vez, la propia portada de acceso (/<societySlug>) muestra un botón "Soporte técnico" hacia /<societySlug>/soporte, reutilizando sociedad_soporte_por_slug() — la misma función que ya protegía la portada pública del formulario, sin ninguna comprobación nueva.