todos-contra-el-fuego-web/PENDIENTE.md
vjrj bc778bfd97 deps: react-leaflet 1.8 -> 4.2 (+ leaflet 1.9) — the last legacy react-* lib
Ground-up hooks rewrite of the app's core map. Removes the final batch of
React-19-blocking warnings (legacy context on Map/LayersControl/TileLayer/
Marker/CircleMarker/Circle/Tooltip + ReactDOM.render from the old controls).

Core: <Map> -> <MapContainer>; .leafletElement refs (6 files) -> the map/
layer instances directly, via a <MapReady> child (useMap) + plain refs on
Marker/Circle/GeoJSON; controlled viewport (onViewportChanged + state.center/
zoom) -> <MapEvents> (useMapEvents moveend/zoomend) + imperative setView;
onClick -> eventHandlers={{click}}; Path styling -> pathOptions/style;
subsUnion takes the L.Map directly.

The 4 v1-only plugins reimplemented (new in-repo helpers under Maps/):
- react-leaflet-control -> MapControl (L.Control + createPortal)
- react-leaflet-google  -> GoogleMutantLayer (createLayerComponent +
  leaflet.gridlayer.googlemutant; Google Maps API already loaded by Gkeys)
- react-leaflet-fullscreen -> createControlComponent + leaflet.fullscreen
- leaflet-sleep / leaflet-graphicscale kept as vanilla (work on leaflet 1.9)

Browser-verified: /fires (tiles, OSM+Google layer switch, custom control,
fullscreen, graphic scale, pan/zoom -> re-fetch, no NaN), fire detail
(GeoJSON rect + fitBounds), home (3 maps coexist; SelectionMap draggable
marker -> updatePosition + distance circle). Console now shows 0 React
warnings on home/fires. REST smoke byte-identical.
2026-07-21 18:45:15 +02:00

106 lines
6 KiB
Markdown

# 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.** No la
cubre el smoke. Probar en una página de fuego: publicar/editar/borrar,
like/dislike, embed de imagen y YouTube, y el email a otros comentaristas.
- **`FireContainer` usa `FiresCollection.findOne()` sin selector**
(`imports/ui/pages/Fires/Fires.js`): puede devolver un doc de una suscripción
previa. Endurecer filtrando por el `_id` de la URL. (Preexistente, no bloquea,
pero conviene antes de prod.)
- **Suite de tests sin runner.** El stack de test (meteortesting:mocha, chai…)
se eliminó en la migración 2.x (arrastraba coffeescript que crasheaba el build).
Quedan tests Jest en `test/` (`rest.test.js`, `email.test.js`, …) y
`npm test → jest`, pero hay que **verificar/actualizar** que pasan sobre el
código async de Meteor 3. Hoy la ÚNICA red automática es `smoke/`.
- **Rate-limit de publications** pendiente (`imports/startup/server/api.js:18`).
- **Google Maps** se carga sin `loading=async` (aviso de rendimiento); el loader
`google-maps` npm es viejo → valorar el loader async moderno.
- **i18n de cuentas (`meteor-accounts-t9n`, T9n):** paquete antiguo aún usado
(Login, VerifyEmail, i18n). Verificar que funciona en Meteor 3; traducción
gallega (gl) incompleta (varios TODO en `i18n.js`).
- **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-label` en `forms.scss`. El salto a Bootstrap 5 npm está diferido
porque el carrusel del home (`bootstrap-carousel-swipe`, jQuery/BS4) y el
collapse del navbar dependen del JS jQuery de BS4 (`data-toggle`, `data-slide`).
Al hacerlo: importar `bootstrap@5` SCSS+JS, reescribir el carrusel (BS5 trae
swipe nativo → quitar el plugin), `data-toggle``data-bs-toggle`,
`ml-auto``ms-auto`, revisar `new-age.scss`/`custom.scss`/`bootstrap-overrides.scss`.
- **Limpieza menor:** migración 217 `// TODO remove falsepositives lowercase
collection`; `prerender.js` gating comentado; sección per-fire del sitemap
eliminada (era código muerto tras `firesMapEnabled=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 en `settings-development.json` (gitignored).
- Pendiente: poner el DSN en el `METEOR_SETTINGS` de **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-notifications` emita en prod (si no, los usuarios dejan
de recibir avisos). Ver dependencia en `UPGRADE.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`.