Cierre formal · Bloques A y B

Verificado contra la base y el código de hoy, 2026-08-12 · evidencia por punto, no resumen · A4 fuera de alcance por decisión tuya

Parte 1 · Tabla de estado

PuntoEstadoEvidenciaQué falta
A5 · OrganizadoresPARCIALDirectorio 1172 vivos. Direcciones-como-nombre 0. Compuestos del lote (112) separados. Puntuación terminal 3.~28 compuestos con patrón "X y la Y" que no estaban en el lote original + 2 basuras (ver A5).
A6 · Placeholders ubicaciónPENDIENTE485 registros con placeholder en ubicacion_texto. Geo intacta (485 país, 484 ciudad/coords).Vaciar el texto placeholder de esos 485 (la geo se conserva). No lo toqué en esta ronda.
B1 · Procedencia + índiceOKColumnas fuente/id_fuente/url_fuente (text). Índice ux_eventos_fuente_idfuente. Eventos con fuente: 0.
B2 · Endpoint de ingestaOKPrueba corrida hoy: 4 casos correctos, 0 usuarios creados, tabla restaurada.
B3 · Aprobación en loteOKTandas de 6 en paralelo, fallo parcial no tumba el lote. Reusa PATCH por evento.Ojo volumen de correos (~150 a la cuenta de sistema), ver Parte 3.

Parte 2 · Verificación puntual

A5 · Organizadores

A6 · Placeholders

B1 · Procedencia

B2 · Prueba del endpoint (corrida hoy)

CasoResultado real
1. Evento válido nuevocreated · PENDING · código P-CO-999-26-00036
2. Mismo reenviado con cambioupdated · mismo código, no duplicó (nombre y ciudad se actualizaron)
3. País fuera de catálogo ("Wakanda")error · "país no reconocido en el catálogo"
4. Placeholder Luma en ubicacióncreated · ubicacion_texto = NULL (lo descartó)
Usuarios auth.users: 108 antes, 108 después (delta 0). Las 2 filas de prueba se borraron; fuente no nula global volvió a 0. La tabla quedó como estaba.

B3 · Aprobación en lote

Parte 3 · Respuestas

3.1 · Contrato del endpoint src/routes/api/admin/eventos/ingest/+server.ts

Ejemplo mínimo de request:
POST /api/admin/eventos/ingest   Authorization: Bearer <secret>
{ "fuente":"luma", "eventos":[ { "id_fuente":"evt-123", "nombre":"Demo Day", "fecha_inicio":"2026-09-10", "modalidad":"presencial", "pais_code":"Colombia", "ciudad":"Bogotá", "url_fuente":"https://lu.ma/xxx", "tematicas":[], "organizadores_raw":[{"rol":"Organizador","nombre":"Pygma"}] } ] }

3.2 · Publicación programada sin riesgo

Corrección (2026-08-12): mi reporte anterior estaba mal. El catálogo público (eventosPublicos.ts línea 172) filtra solo por status APPROVED y sin papelera, NO por publish_at. El propio código cita la regla de Frank (#6): la visibilidad depende exclusivamente de la aprobación, no de la fecha ni de publish_at. Un evento aprobado aparece de inmediato aunque su fecha sea futura. La aprobación en lote escribe publish_at, pero el catálogo lo ignora, así que los eventos NO quedan ocultos. No hay riesgo aquí.

3.3 · Eventos finalizados

Por el panel, un evento finalizado (fecha fin < hoy) es de solo lectura salvo super_admin. Pero el endpoint de ingesta usa service-role y sí puede actualizar un evento finalizado (no chequea la fecha): si el scraper reenvía uno ya terminado, lo actualiza sin fallar. No lo cambié, solo te confirmo el comportamiento.

3.4 · Geocodificación

El endpoint no geocodifica. Toma ubicacion_lat/lng si vienen; si mandás dirección sin coordenadas, el evento queda sin lat/lng. La geocodificación la tenés que resolver vos antes de enviar (o aceptar que esos queden sin punto en el mapa).

Parte 4 · Lo que falta para ingerir con seguridad

Bloquea o conviene resolver antes de la primera carga grande

Nota: el riesgo de "publish_at oculta eventos futuros" que reporté antes NO aplica; era un error mío de verificación, corregido en 3.2. La visibilidad depende solo de la aprobación.

Puede esperar (no bloquea la ingesta)

Riesgo que no preguntaste

El endpoint puede actualizar eventos ya finalizados (3.3). Si el scraper reprocesa ediciones viejas de Luma, podría tocar eventos que ya ocurrieron. Si no querés eso, se puede agregar un guard de "no actualizar si fecha fin < hoy". Hoy no está.
Cierre verificado con evidencia · 2026-08-12