Second (last) jQuery/BS4 JS blocker to the BS5 CSS swap. Replaces the `bootstrap-carousel-swipe` jQuery plugin + `$(...).carousel()` init with react-bootstrap's <Carousel> (native swipe, no jQuery) for both home carousels. - Preserves the progressive `.lazy` background mechanism (blur -> full image on slide-in): the old `slide.bs.carousel` handler becomes <Carousel onSlide>, which marks the incoming index in component state. - Keeps all per-slide class hooks (carousel-item-N, carousel-snd-item-N). - CSS ports in Index-custom.scss for react-bootstrap's BS5 markup: indicators render as <button> (not <li>), and prev/next labels use .visually-hidden (BS4 had .sr-only) -> add a shim so labels stay hidden on current BS4 CSS. - Drops the now-unused bootstrap-carousel-swipe dependency. Full-app build boots clean. Needs a visual staging check of the home page.
7.4 KiB
Pendiente — web "Todos contra el fuego" (rama meteor3-wip)
Estado a 2026-07-18. La migración Meteor 1.6 → 3.1 + MongoDB 7 está completa
y verificada (server async, React 18, web renderiza, smoke REST byte-idéntico).
Lo que falta, agrupado. Ver UPGRADE.md para el detalle de lo ya hecho.
1. Modernización de librerías react-* antiguas (deuda de front grande)
Funcionan en React 18 por compatibilidad heredada, pero ensucian la consola en desarrollo (no en producción) y bloquean el salto a React 19. Estado:
| Lib | De → A | Estado |
|---|---|---|
| react-helmet | 5.2 → react-helmet-async 2 | ✅ hecho |
| react-i18next + i18next | 7.4/10.5 → 14/23 | ✅ hecho |
| react-bootstrap | 0.31 → 2 | ✅ hecho (CSS sigue en Bootstrap 4) |
| reactstrap + 3 deps muertas | — | ✅ eliminadas (0 usos) |
| react-router-dom | 4.2 → 6.30 | ✅ hecho (history 5, HOC withRouterCompat) |
| react-leaflet + leaflet | 1.8/1.3 → 4.2/1.9 | ✅ hecho (Map→MapContainer, refs directas, useMap/useMapEvents; 4 plugins reimplementados: MapControl portal, GoogleMutantLayer, fullscreen, sleep/graphicscale vanilla; ver UPGRADE.md) |
| Bootstrap CSS/JS | 4.1 → 5 | ⏸️ diferida (carrusel/navbar jQuery BS4; ver UPGRADE.md) |
Lo verificado en navegador tras cada lib: /, /fires, /fire/archive/<hex>,
/login, /subscriptions + consola. Smoke REST byte-idéntico en cada paso.
Limpieza de warnings restantes YA hecha: defaultProps en componentes función →
parámetros por defecto; UNSAFE_componentWillReceiveProps (FromNow, FireStats,
Fires, SelectionMap) → getDerivedStateFromProps/componentDidUpdate; Reconnect
(banner Blaze meteorStatus con findDOMNode) → React nativo con
useTracker(Meteor.status); react-share 2→5 y react-progress-bar.js → progressbar.js
(ambos tiraban findDOMNode/defaultProps); y react-leaflet 1.8→4.2 (mapa central,
4 plugins reimplementados). Tras esto la consola tiene 0 warnings de React en las
rutas principales (verificado forzando re-render en / y /fires). Único resto para
React 19: el <Blaze serverFacts> de Status.js (findDOMNode), solo en /status (admin).
2. Deuda funcional / de calidad de la web (independiente de prod)
- Comentarios (feature React nueva): verificación manual en staging. El smoke
no llega a la UI. Los métodos (insert/edit/remove/like/dislike) y el embed
(
mediaAnalyzers) ya están cubiertos por mocha (test/server/comments.test.js), pero quedan por probar a mano en una página de fuego:- publicar / editar / borrar un comentario (UI React)
- like / dislike (toggle)
- render del embed de imagen y de YouTube
- email a otros comentaristas (
onCommentAdd.js, entrega real de correo)
- ✅
FireContainerendurecido (imports/ui/pages/Fires/Fires.js): elfindOne()sin selector ahora se acota por el_idde la URL en la rutaarchive(new Meteor.Collection.ObjectID(id)); en active/alert/hash cada publicación deja un único fire en minimongo, así que el read vacío es correcto. - ✅ Suite de tests con runner (
meteortesting:mocha).npm testcorremeteor test … --driver-package meteortesting:mocha(watch:npm run test-watch). Tests reescritos achai+ APIs async de Meteor 3 entest/server/*.test.js(server-only), incluyendo cobertura nueva de los métodos de comentarios. Jest yrest.test.js(ya cubierto porsmoke/) eliminados. 36 passing. Pendiente menor: portar los casos de token inválido (401/400) derest.test.jsal smoke. - ✅ Rate-limit de publications (
imports/startup/server/api.js): reglastype: 'subscription'víarateLimitSubscriptions— 5/1000ms enfireFrom*ycomments.forReference; 10/1000ms en las subs geo (map pan/zoom). - ✅ Google Maps con
loading=async(imports/startup/client/Gkeys.js): se envuelveGoogleMapsLoader.createUrlpara añadir el parámetro (el paquetegoogle-mapsnpm no expone hook). Verificar en staging que el mapa carga y el aviso de consola desaparece. - ✅
meteor-accounts-t9nactualizado a^2.6.0(es/en OK). El paquete sigue sin build gallego (gl), así que se mantiene el fallback gl→es documentado eni18n.js. Traducción gallega de la app (gl/common.json): 0 claves faltantes. - Salto Bootstrap 4→5 (CSS/JS) pendiente: react-bootstrap ya está en v2 y
corre sobre el CSS Bootstrap 4 actual (
alexwine:bootstrap-4) con un único shim.form-labelenforms.scss. Ya no quedan dependencias del JS jQuery de BS4 — los dos blockers se migraron a React:- ✅ Collapse del navbar (
Navigation.js+NavItem.js):data-toggle= "collapse"jQuery → estado React (useStateque alterna.show). Verificar en staging el menú móvil (<lg): abrir/cerrar y cierre al pulsar un enlace. - ✅ Carrusel del home (
Index.js):bootstrap-carousel-swipe(jQuery) +$(...).carousel()→<Carousel>de react-bootstrap con swipe nativo; se conserva el mecanismo.lazyde fondos (blur→full) víaonSlide. Depbootstrap-carousel-swipeeliminada. Ports de CSS enIndex-custom.scss: indicadoresli→button(markup BS5) y shim.visually-hidden. Verificar en staging el home: transiciones, swipe, indicadores, prev/next y carga progresiva de las imágenes de fondo. - Falta (el salto de CSS en sí, ya sin bloqueos de JS): importar
bootstrap@5SCSS+JS,ml-auto→ms-auto(y demás utilidades direccionales), revisarnew-age.scss/custom.scss/bootstrap-overrides.scssy retiraralexwine:bootstrap-4.
- ✅ Collapse del navbar (
- Limpieza menor: migración 217
// TODO remove falsepositives lowercase collection;prerender.jsgating comentado; sección per-fire del sitemap eliminada (era código muerto trasfiresMapEnabled=false).
3. Observabilidad (Sentry/GlitchTip) — casi cerrado
- ✅ Server-side reporta a GlitchTip; ✅ cliente vía túnel
/sentry-tunnel(esquiva el 503 de Cloudflare). DSN ensettings-development.json(gitignored). - Pendiente: poner el DSN en el
METEOR_SETTINGSde producción y confirmar que el servidor de prod alcanza GlitchTip (IPv4). Nota: el túnel es un relay acotado al proyecto propio (aceptable, documentado). - Consola de dev: warnings de librería restantes solo se van con el punto 1.
4. Cutover a producción (infra — fase 3, es lo grande)
- Migrar datos Mongo 3.2 → 7 (mongodump/restore) en el servidor real.
- Desplegar el stack (Docker) al servidor limpio vía el ansible de
Comunes — NO al viejo shiva. Ver
RUNBOOK.md(stack compose local validado). - Coordinar orden con notificaciones: la web NO debe desplegarse antes de que
el microservicio
tcef-notificationsemita en prod (si no, los usuarios dejan de recibir avisos). Ver dependencia enUPGRADE.md. - Secretos de prod (
METEOR_SETTINGS, no el fichero gitignored), cron del GeoLite2 City (MaxMind) en el nuevo host, proxy/TLS por el ansible compartido.
5. Fuera del repo web (bloquean el "hecho" global, pistas aparte)
- tcef-notifications: rollout por canal shadow→canary→full (FCM en canary superado; email y telegram pendientes) y redeploy del servicio actualizado.
- App móvil
fires_flutter: republicación en Play Store.
Regla de trabajo en todo lo anterior: commits locales atómicos en meteor3-wip,
smoke REST byte-idéntico tras cada cambio, verificación visual en navegador,
y NUNCA git push.