Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
Seguimiento de proyectos de construcción con mapas y fichas técnicas
Translation pending
AI summary · website content
BusinessJavaScript · CSSGitHub @IgeophysicistOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Sitio estático (HTML/CSS/JS sin build step) publicado en GitHub Pages.
| Ruta | Contenido |
|---|---|
index.html | Portal: accesos, sección "Esta semana" y colaboradores (data/colaboradores.json). |
cartera-mixtos/ | Panel de proyectos mixtos: listado, filtros, mapa y resumen. Ver su README. |
cartera-mixtos-2/ | Mixtos 2da Ronda: la misma página que Mixtos (usa sus scripts y estilos) con sus propios datos, filtro de Región y estatus de cada trámite. Su acceso en el portal está oculto hasta liberarla (<template id="accesoMixtos2"> en index.html). Ver su README. |
cartera-cpel/ | Ficha por proyecto de la cartera CPEL. Ver su README. |
cartera-anteproyectos/ | Ficha por anteproyecto (mismo diseño que Cartera CPEL). Su acceso en el portal está oculto hasta liberarla (<template id="accesoAnteproyectos"> en index.html). Ver su README. |
assets/js/shared/ | Módulos compartidos por las tres páginas (ver abajo). |
assets/js/shared/)text-utils.js: normalizar nombres (para vincular Excel ↔ KML y
buscar), escapar HTML, leer números y fechas. Las fechas siempre se
crean en hora local para que el 1 de enero no se convierta en el 31
de diciembre del año anterior.kml-parser.js: parser KML mínimo (Point, LineString, Polygon).base-map.js: mapa Leaflet con capas satelital/calles y aviso cuando
no cargan las imágenes.regiones.js: capa de referencia "Regiones" de ambos mapas (ver
abajo).dialog.js: abre y cierra paneles emergentes (Escape, foco y
aria-hidden).Los datos se siguen editando en los Excel de cada tablero
(cartera-cpel/data/datos_proyectos.xlsx,
cartera-cpel/data/HITOS_CARTERA_CPEL.xlsx (hitos de pago, ver
cartera-cpel/README.md), cartera-mixtos/data/DATOS_MIXTOS.xlsx,
cartera-mixtos-2/data/DATOS_MIXTOS_2.xlsx,
cartera-anteproyectos/data/datos_anteproyectos.xlsx). Las páginas no leen el Excel:
leen un JSON que se genera y valida automáticamente.
.github/workflows/datos.yml) revisa el
Excel con scripts/build-data.js.Qué se revisa (scripts/data-rules.js):
| Errores (bloquean la publicación) | Avisos (solo se reportan) |
|---|---|
| Falta una columna que usa la página (renombrada o borrada) | Proyecto sin ubicación en el KML (no sale en el mapa) |
| Porcentaje que no es número o fuera de 0–100 | |
| Fecha que no se puede leer | |
| Proyecto repetido | |
| Imagen que no existe o que no es JPG/PNG, p. ej. HEIC (Cartera) | |
| Excel guardado antes que el ya publicado (copia vieja; para volver a esa versión a propósito, ábrela y guárdala de nuevo) |
Las celdas vacías y los marcadores de dato pendiente ("SIN DATO", "N/A", "PENDIENTE", "POR DEFINIR", "-") no son errores.
Las imágenes de encabezado (cartera-cpel/data/CARTERA-CPEL/) se suben
tal cual, aunque sean fotos pesadas de celular. La Action Datos las
optimiza (scripts/imagenes.js): ancho máximo de 1200 px, giradas
según la cámara, sin metadatos (se borra la ubicación GPS de las
fotos) y con el mismo nombre, así que la columna imagen del Excel
no cambia. Sube la versión ligera en un commit "Optimiza imágenes de
Cartera CPEL". Las que ya están optimizadas no se tocan, y el original
queda en el historial de GitHub.
Usa JPG o PNG. Las fotos HEIC del iPhone no se ven en Chrome ni en Android: la validación las marca como error. Para que el iPhone guarde JPG: Ajustes → Cámara → Formatos → "Más compatible".
No edites los JSON a mano: se sobrescriben con cada Excel. Para
revisar un Excel antes de subirlo: npm install y luego npm run data
(valida, regenera y optimiza imágenes) o npm run data:check (solo
revisa).
La hoja "CAPEX" de DATOS_MIXTOS.xlsx trae, además, el desglose de
trámites copiado de la hoja "Base de Datos" del Excel de Estado de
Proyectos: name_BD (nombre en esa hoja, solo de control) y las columnas
DI_P … AFAC_LT (avance de cada trámite en Parque y LT, con el signo %).
cartera-mixtos/assets/js/tramites.js (iguales a la
fila 52 de "Base de Datos"): Derechos inmobiliarios 10 %, Estudios de
interconexión 10 %, MIA–DTU 20 %, ETJ 10 %, MISSE 20 %, Consulta indígena
10 %, INAH/PEMEX/CONAGUA/AFAC 5 % cada uno; Global = 80 % Parque + 20 % LT.cartera-mixtos-2/data/DATOS_MIXTOS_2.xlsx, hoja BASE_DE_DATOS
(encabezados en la fila 3; ver scripts/mixtos2.js): además del avance de
cada trámite (DI_P … AFAC_LT) trae su estatus (DI_P_ESTATUS …
AFAC_LT_ESTATUS), elegido de la lista de la hoja REGLAS.
ESTATUS en tramites.js).data/MIXTOS_2.kml) cada punto se llama como el ID_VUPE
del proyecto; la página muestra el nombre de la columna "Proyecto".El botón Presentación de Mixtos (en celular, en la barra de abajo
entre Mapa y Resumen; en computadora, en la barra superior) abre el PDF
cartera-mixtos/presentacion/presentación_mixtos.pdf en una ventana,
diapositiva por diapositiva, con el botón Descargar PDF. Con zoom
(pellizcando la pantalla) las diapositivas se redibujan nítidas.
cartera-mixtos/presentacion/
con el nombre exacto presentación_mixtos.pdf (reemplaza al anterior;
también sirve sin acento, presentacion_mixtos.pdf). No pasa
por la Action "Datos" ni se revisa: se publica tal cual.sw.js): verlo pide conexión; descargarlo lo deja en el dispositivo.data/historial.json de cada tablero (scripts/historial.js) según
la fecha de guardado del Excel (hora de México). Lo guardado después
dentro de la misma semana reemplaza ese punto (cada Excel trae la
hoja completa). Subir solo un KML (sin cambiar el Excel) no agrega
puntos.
assets/js/shared/trend.js), es decir, el ritmo reciente
proyectado. En Cartera el resumen muestra el ritmo en pts/semana,
cuándo llegaría a 100% y cuánto llevaría en la fecha de operación (con
menos de 4 cortes, la fecha se marca como estimación preliminar). En
Mixtos solo dice si Global avanzó, disminuyó o se mantuvo en el
último corte, sin fechas estimadas: esos proyectos aún son volátiles.
La tendencia no sustituye al programa de obra.data/historial.json (o pídeselo a quien mantenga el sitio).Los mapas de Mixtos y Cartera CPEL tienen la casilla Regiones en el selector de capas (el de Satelital / Calles). Muestra los polígonos de regiones solo como referencia visual: cada región con su color, debajo de los proyectos, con su nombre al acercarse. Empieza apagada, cada dispositivo recuerda si la dejó encendida y el archivo se descarga solo al encenderla.
assets/capas/regiones.kmz (~10 MB, demasiado para un
celular).assets/capas/regiones.geojson (< 1 MB),
generado con npm run regiones (simplifica los contornos a ~50 m)..kmz, corre
npm run regiones y sube los dos archivos.Sección del portal, debajo de los accesos, que se arma sola con los
datos que genera la Action (assets/js/semana-resumen.js calcula y
assets/js/semana-portal.js pinta):
cartera-mixtos/data/actualizaciones.json,
que la Action llena sola en cada subida que cambia Parque o grupo
(scripts/historial.js).Cada nombre abre la ficha del proyecto. Si los datos no cargan, la sección no aparece.
Enlaces directos: la dirección de cada tablero refleja lo que se está viendo, así que basta con copiarla y compartirla:
cartera-cpel/?proyecto=ph-chicoasen-iicartera-mixtos/?proyecto=san-simon-solar (ficha abierta) o
una vista filtrada, p. ej. ?tecnologia=EO%20-%20Eólica&q=noria&tab=mapa.El identificador sale del nombre del proyecto (sin acentos ni símbolos). Si alguien abre un enlace sin sesión, después de la contraseña llega a la misma vista.
"Datos al …": es la fecha en que se guardó por última vez el Excel de cada tablero (Cartera: en el encabezado del proyecto; Mixtos: bajo el título de la barra superior). Se actualiza sola al subir un Excel nuevo; no hay que capturarla.
El sitio se puede instalar en el celular o la computadora como una app
(manifest.json + íconos en assets/img/icon-*.png).
sw.js (Service Worker, registrado por assets/js/shared/pwa.js):
/data/: Excel, KML,
JSON) nunca se guardan, así que sin conexión las páginas abren
pero sin datos.window.PWA.recargarSiHayRed
en pwa.js); si vuelve a fallar, muestra su mensaje de error, sin
recargas sin fin.VERSION en sw.js solo se cambia si se modifica la lógica del
propio sw.js (borra lo guardado por la versión anterior).functions/_middleware.js protege todo el sitio (páginas, scripts,
Excel, KML e imágenes) con una sola contraseña compartida. Solo
funciona cuando el sitio se publica en Cloudflare Pages; en GitHub
Pages ese archivo no hace nada y el sitio queda abierto.
Crea una cuenta en https://dash.cloudflare.com (de preferencia con un correo institucional o compartido del área).
Workers & Pages → Create y busca la opción de Pages (pestaña "Pages" o el enlace "Looking to deploy Pages? Get started") → Import an existing Git repository → este repositorio → Begin setup.
⚠️ No uses "Import a repository" de Workers. Eso crea un Worker, no un proyecto de Pages: el despliegue corre
npx wrangler deploy, ignora la carpetafunctions/(el sitio quedaría sin contraseña) e intenta publicarnode_modules, por lo que falla con "Asset too large". Si te pasa, borra ese Worker (Settings → Delete) y crea el proyecto de Pages.
Configuración de compilación:
| Campo | Valor |
|---|---|
| Production branch | main |
| Framework preset | None |
| Build command | vacío |
| Build output directory | vacío (la raíz); si no lo acepta, / |
En Environment variables (advanced) agrega
SKIP_DEPENDENCY_INSTALL = 1, para que Cloudflare no instale ni
publique las herramientas de desarrollo (node_modules).
En el log del despliegue no deben aparecer
npx wrangler deploy ni Installing project dependencies, y debe
detectar la carpeta functions. El primer despliegue muestra
"Falta configurar SITE_PASSWORD": es lo esperado.
En el proyecto: Settings → Variables and Secrets → Add, tipo
Secret, nombre SITE_PASSWORD, con la contraseña como valor.
Agrégala para Production y también para Preview (si falta, esas
versiones quedan cerradas con un aviso).
Deployments → Retry deployment para que tome la contraseña.
Comprueba en https://<proyecto>.pages.dev:
No escribas el link de Cloudflare ni la contraseña en el repositorio (README, commits, datos) mientras sea público.
Usa una frase larga (4–5 palabras) como contraseña: el formulario espera 1.5 s tras cada intento fallido, pero no bloquea por IP.
Settings → Variables and Secrets → edita SITE_PASSWORD → Deployments
→ Retry deployment. Todas las sesiones abiertas se cierran.
Si en GitHub el check "Cloudflare Pages" de un commit de main se queda
en "Building" por mucho tiempo (normalmente tarda menos de un minuto):
Deployments → abre esa publicación → Retry deployment. Si Cloudflare dice
que ya terminó pero el sitio no cambió, revisa cuál está marcada como
Production. Si la publicación ya no existe, cualquier commit nuevo en
main arranca una publicación desde cero.
npx wrangler pages dev . --binding SITE_PASSWORD="contraseña de prueba"
# abre http://127.0.0.1:8788/
python3 -m http.server 8000
# abre http://localhost:8000/
Requiere Node.js 22:
npm install
npm run check # ESLint + pruebas de los scripts y del middleware de contraseña
npm run test:e2e # pruebas en el navegador (ver abajo)
npm run check corre en GitHub Actions (.github/workflows/ci.yml) en
cada push y pull request.
tests/e2e/ (Playwright) abre el sitio en Chromium con el mismo motor de
Cloudflare Pages (wrangler pages dev, con una contraseña de prueba,
nunca la real) y lo recorre en celular y computadora:
Comparan contra los JSON del repositorio, así que no fallan porque
cambien los datos; sí fallan si una página se rompe. Corren solas en
GitHub (.github/workflows/navegador.yml) en cada PR, en cada push a
main (también al subir un Excel) y a mano desde Actions → Navegador
→ Run workflow. No bloquean la publicación. Si fallan, la
ejecución guarda en Artifacts ("pruebas-navegador") capturas y un
trace de cada prueba fallida (se abre con npx playwright show-trace).
Para correrlas en tu computadora: npx playwright install chromium (una
vez) y npm run test:e2e.
/cartera-mixtos/data/DATOS_MIXTOS.xlsx no se descarga.Comparte el link y la contraseña por canales distintos y avisa la fecha en que dejará de funcionar el link de GitHub Pages.
Llegada esa fecha: desactiva GitHub Pages (Settings → Pages) y vuelve privado este repositorio (Settings → General → Change visibility). Mientras el repositorio sea público, los Excel y KML se pueden descargar directo desde GitHub sin contraseña.
Haz un cambio pequeño (p. ej. en este README) y confirma que aparece una publicación nueva en Deployments. Si no, en GitHub: Settings → Applications → Cloudflare Workers and Pages → Configure, y agrega este repositorio.