4.3 KiB
Dominio Event
Propósito
Administra los eventos de un tenant, sus fechas y sus redes sociales.
Modelo
Tenant tiene muchos Event. Cada evento tiene título, subtítulo, descripción,
ubicación, texto de fechas y published_at. Sus fechas se guardan en event_dates
mediante event_id. El catálogo social_media define las plataformas;
event_social_media guarda la URL y el orden de cada cuenta del evento.
exact_location guarda opcionalmente un objeto JSON con latitude (-90 a 90)
y longitude (-180 a 180). location sigue siendo la dirección legible.
events.address_id es una referencia opcional a addresses.id: Event::address()
obtiene su dirección y Address::events() permite reutilizar una dirección en varios
eventos. Al borrar una dirección, el vínculo queda en NULL y se conserva el evento.
La migración 2026_09_30_000200_add_address_id_to_events agrega el vínculo.
2026_09_30_000300_copy_event_locations_to_addresses copia location a
address_text y las coordenadas de exact_location a latitude y longitude, con
el label Ubicación del evento. Solo copia eventos sin address_id y con texto de
ubicación; no modifica los campos ni los timestamps originales, ni vincula la
dirección al tenant. Si faltan texto y coordenadas, el vínculo queda en NULL.
Los datos inválidos, incluidas coordenadas sin texto de dirección, detienen la
copia y revierten las inserciones para evitar una migración parcial. Las migraciones
deben ejecutarse explícitamente por quien administra la base.
Las respuestas públicas, administrativas y el evento del bootstrap incluyen
address con id, label, address_text, latitude y longitude. Las coordenadas
se serializan como números o null. Los campos anteriores de la respuesta conservan
sus valores originales; el frontend lee la ubicación y coordenadas desde address.
El guardado administrativo de
location y exact_location también actualiza addresses; si una dirección está
compartida con otro evento o con un tenant, se crea una copia para el evento editado.
El tenant devuelve addresses con is_main y main_address. El storefront usa
todas las direcciones en contacto, la principal en el footer y la propia del evento
en sus tarjetas, cabecera y mapa. Solo se agregan al mapa las direcciones con ambas
coordenadas.
La migración 2026_09_18_000500_restore_events crea un evento por cada tenant que
tenía datos de evento o fechas, y migra las fechas y redes correspondientes.
2026_09_18_000600_associate_active_event_social_media copia al evento activo las
redes del tenant que falten, sin sobrescribir las URL propias del evento. El seeder
de Fiesta Fútbol Infantil hace lo mismo cuando crea el evento en una base nueva.
Storefront
onticketmuestra el evento señalado portenants.active_event_id.onticket_multi_eventpermite varios eventos publicados y mantienetenants.active_event_idenNULL. La presentación y gestión de esos eventos en el frontend quedan pendientes de diseño.
active_event_id selecciona el evento del storefront de evento único; no indica
si está publicado. La asignación de este campo y los cambios de tipo de storefront
se administran directamente en la base de datos. La aplicación no valida ni
automatiza esas operaciones.
Cuando hay un evento activo, el campo social_media del bootstrap usa sus redes,
igual que event.social_media. Las actualizaciones de redes de ese tenant también
se guardan en el evento. Sin evento activo se conservan las redes propias del tenant.
API
Los endpoints de AdminApp usan auth:sanctum y adminapp.tenant:
GET/PUT /v1/adminapp/tenant/event: acceso al evento seleccionado para el storefront de evento único.POST /v1/adminapp/tenant/event-dates: crea una fecha para ese evento.POST /v1/adminapp/tenant/event-dates/{eventDate}/rescheduleyPOST /v1/adminapp/tenant/event-dates/{eventDate}/suspend: cambios de fecha.
El bootstrap del tenant entrega event para el evento seleccionado. No entrega
una lista de eventos ni existe todavía una pantalla para gestionarlos.
Dependencias
Las fechas se vinculan con variantes de Catalog, que a su vez pueden generar
tickets. Los avisos por suspensión y reprogramación se construyen dinámicamente
después de excluir los cambios que el usuario ya vio tres veces.