feat(ti/proyectos): ingiere la columna ID que el área agregó en V
El área creó la columna el 2026-09-04, al final de la hoja y con formato
PRY-<n>. La posición no es un detalle: el espejo IMPORTRANGE de TABLEAU 2025
sigue fijado a A1:S, así que una columna en V no lo altera. Puesta en A, el
espejo habría dejado de traer Actividades Clave sin que nada fallara a la
vista — la misma clase de pérdida silenciosa de la que salimos con el cambio de
fuente.
La ingesta ya toleraba la columna extra (lee por nombre de encabezado), pero no la guardaba. Ahora sí:
-
id_externo VARCHAR(40), indexada. Se llama así y noidporqueides el PK autoincremental de la tabla, que se regenera en cada sync. Mismo nombre que usatratospara la misma idea. - Identifica la FILA (proyecto + empresa), no el proyecto: 161 IDs para 109 proyectos distintos, porque "Implementación SINUBE" vive en 22 empresas y cada una es su propia fila. Coherente con la decisión del área de que un registro es una fila.
- Entra al contrato de encabezados, que pasa de 21 a 22. Es la llave sobre la que se van a apoyar el alta desde el portal, la edición y la Bitácora del área: si desapareciera, seguir cargando en silencio sería lo peor posible.
Sin UNIQUE, a propósito. _safe_replace hace DELETE + INSERT de la tabla
completa: un ID duplicado en la hoja reventaría el INSERT y dejaría el tablero
congelado en la carga anterior para toda el área. En su lugar
_revisa_ids_digitalizacion reporta duplicados y blancos en el resultado del
sync y en el log. Es la diferencia con la guarda de encabezados, que sí frena:
un encabezado perdido NULifica una columna entera sin que nada lo delate; un ID
repetido es un dato visible, corregible en la hoja, y el tablero ni lo usa.
Verificado contra la hoja real: 161/161 con ID, 161 distintos, cero duplicados, cero vacíos, contrato 22/22. Y el detector probado con IDs repetidos y vacíos.
Nota para quien ordene la hoja: los IDs no llevan ceros a la izquierda, así que
el máximo alfabético es PRY-99, no PRY-161. El siguiente ID hay que
calcularlo por el número.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com Claude-Session: https://claude.ai/code/session_01QNs55ksY91Ppf1sefCTVae