Skip to content

Vinculando eventos a asistencia

Hay una separación limpia en GCM entre lo que está en el calendario y quién asistió. El calendario contiene eventos — fechas con títulos, horas, lugares. Las listas de asistencia hacen referencia a reuniones — plantillas recurrentes que describen un tipo de encuentro. El vínculo entre ambos es intencional, indirecto y vale la pena entenderlo antes de empezar a configurar cualquiera de los dos.

La asistencia nunca apunta a un evento

Mira la tabla attendances y no encontrarás una columna event_id:

sql
attendances(
  id, member_id, meeting_id, attendance_date,
  organization_id, org_unit_id,
  ministry_id, school_id,
  created_at, updated_at, deleted_at
)

La fila de la lista apunta a una reunión y a una fecha de asistencia. Eso es todo. El hecho de que también exista un evento de calendario en esa fecha es irrelevante para la base de datos — la asistencia vive en su propio mundo, unida por fecha y tipo de reunión, no por una clave foránea a events.

Es una decisión de diseño deliberada. Si la asistencia apuntara a eventos, cada servicio recurrente crearía miles de filas de "ocurrencia" en la base de datos para darle a la asistencia algo a lo que apuntar. En cambio, los eventos recurrentes permanecen como una sola fila con una RRULE, y las reuniones se reutilizan en cientos de fechas. El costo: un evento de Servicio Dominical en el calendario y una reunión de Servicio Dominical en la configuración de asistencia no tienen vínculo automático. Comparten un nombre y un espíritu; el sistema no sabe que están conectados.

Dos escenarios para la asistencia

En la práctica, la asistencia se registra de dos formas, y ambas pasan por las reuniones:

Servicios recurrentes — solo reuniones

Para tu Servicio Dominical, oración del miércoles, célula semanal — cualquier cosa que ocurre con un ritmo constante — no necesitas un evento de calendario en absoluto. Configura una reunión, luego registra asistencia contra ella desde el flujo de asistencia individual, la pantalla de asistencia masiva, o la estación de check-in. Cada fila de asistencia recibe meeting_id = <Servicio Dominical> y attendance_date = <ese domingo>.

El calendario no necesita mostrar estas fechas, porque el encuentro está implícito en la reunión. Los miembros y operadores saben que el Servicio Dominical es a las 10 AM del domingo — no necesitan un punto en el calendario para eso.

Fechas especiales — evento de calendario + reunión ad-hoc opcional

Para eventos únicos contra los que también quieres rastrear asistencia — un retiro de líderes, una noche con orador invitado, una campaña de evangelización — crea el evento de calendario para visibilidad, luego ya sea:

  • Reutiliza una reunión existente. Si el retiro cuenta como una reunión de liderazgo, registra asistencia contra tu reunión existente de Liderazgo en la fecha del retiro. La lista cae limpiamente.
  • Crea una reunión temporal. Si el evento no encaja en ningún tipo de reunión existente, agrega una reunión como Eventos especiales, configura su alcance apropiadamente y registra asistencia contra ella. Etiqueta la fecha en tus notas si el nombre de la reunión es demasiado genérico para identificarla después.

De cualquier forma, el evento de calendario impulsa los recordatorios y la planificación visual; la reunión impulsa la lista.

¿Por qué no asistencia contra el evento directamente?

La respuesta pragmática: los eventos y las reuniones tienen ciclos de vida diferentes. Un evento es un plan de fecha — puede ser cancelado, reprogramado mediante una excepción, o movido por completo. Una lista es un registro histórico — una vez que las personas se han registrado, la fila no debería moverse solo porque cambiaron los datos de planificación.

Si la asistencia apuntara a los eventos:

  • Eliminar un evento de calendario huérfanaría las listas o las eliminaría en cascada.
  • Editar la fecha del evento recalcularía la fecha de cada lista, lo cual está mal para un registro de auditoría.
  • Los eventos recurrentes tendrían que materializar cada ocurrencia en una fila real antes de que la asistencia pudiera referenciarla.

Apuntar a las reuniones evita todo eso. Las reuniones cambian rara vez (y cuando lo hacen, los cambios de alcance son deliberados). Los eventos cambian a menudo, y esa volatilidad queda contenida en la superficie del calendario donde pertenece.

Reglas de deduplicación

Algunas reglas mantienen las listas limpias ante re-importaciones, check-ins duplicados y guardados dobles accidentales:

  1. Una fila por (member_id, meeting_id, attendance_date) por org. Un índice único lo impone. Guardar la misma asistencia dos veces — mismo miembro, misma reunión, misma fecha — hace silenciosamente un no-op en el segundo guardado.
  2. Solo borrado lógico. Eliminar una fila de la lista pone deleted_at en vez de removerla. El índice único trata las filas eliminadas lógicamente como no conflictivas, así que una fila eliminada-y-vuelta-a-añadir funciona como se espera.
  3. Las filas con is_sample = true se excluyen de los reportes. La asistencia de demostración sembrada lleva la bandera para que no contamine los números reales cuando salgas en vivo.
  4. Las columnas de org y org-unit se sellan al insertar. No se recalculan si mueves al miembro a otra sede después — el registro histórico permanece exacto al momento del check-in.

La estación de check-in y la asistencia masiva ambas dependen de estas reglas para ser idempotentes: pulsa enviar dos veces, escanea el mismo QR dos veces, sube el mismo CSV — el conteo de filas permanece correcto.

¿Y la asistencia de ministerio y escuela?

La tabla attendances lleva columnas opcionales ministry_id y school_id para listas que pertenecen a una reunión específica de ministerio o sesión de escuela. Estas se configuran cuando el linked_entity_type de la reunión es ministry o school, y permiten que el módulo de reportes divida los totales por ministerio o por escuela.

Para un ensayo del equipo de adoración que cuenta tanto como reunión de ministerio como reunión regular, elige uno. No registres doble en dos filas de reunión — inflarás los totales. El patrón más limpio es una sola reunión vinculada al ministerio, y reportes que agregan por ministry_id.

Cuando el calendario y la asistencia divergen

Si el calendario muestra un evento y nunca se registra asistencia, está bien — la mayoría de los eventos son informativos. Si existe asistencia para una fecha sin un evento de calendario correspondiente, también está bien — las reuniones recurrentes no necesitan puntos en el calendario.

El caso a vigilar es que ambos existan y describan cosas ligeramente diferentes. Un evento de calendario titulado "Servicio Dominical @ 10am" y una reunión titulada "Servicio Matutino" se refieren al mismo encuentro, pero los reportes y recordatorios los tratan como independientes. Elige una convención de nombrado consistente y mantenla en ambas superficies — tu yo futuro haciendo una auditoría de asistencia te lo agradecerá.