Commit graph

484 commits

Author SHA1 Message Date
e5f7a0f4be fix(maps): entregar el mapa solo cuando tiene tamano real (MapReady)
MapReady entregaba el mapa en el useEffect de montaje, cuando el contenedor
puede no tener tamano todavia. En FiresMap eso hacia que getBounds() lanzara;
el catch solo avisaba ("Failed to set map bounds and scale") y mapSize nunca
se seteaba, con lo que la suscripcion de fuegos por viewport NI SE CREABA:
loading eterno y tile-pane vacio (0 capas) pese a haber 7470 fuegos.

Evidencia: en Meteor.connection._subscriptions solo aparecian activefirestotal,
activefiresuniontotal, settings y userData — ninguna por localizacion.

Ahora se entrega via map.whenReady() + invalidateSize(), solo cuando getSize()
no es 0, con reintento en el evento resize y entrega unica (flag delivered).

Toca el componente compartido por todos los mapas: al desplegar hay que
re-verificar /fires, /zones, /subscriptions, home y detalle de fuego.
SIN DESPLEGAR todavia (la imagen viva es la de 01:33, sin este cambio).
2026-07-28 07:46:19 +02:00
c50690cc8a fix(maps): evitar carrera MapReady/DDP que dejaba el mapa en gris
En react-leaflet v4 la capa union no se dibujaba (mundo gris a zoom 0) en
/zones, /subscriptions y el bloque Participa cuando los datos DDP llegaban
despues de montar el mapa. Se anade reintento en componentDidUpdate y se
endurece la guarda, con flag de instancia para el ajuste de bounds.
2026-07-28 00:35:11 +02:00
1ef0012af9 bootstrap: BS5 sweep follow-ups (form-group, drop popper.js@1)
Post-swap hardening after a full BS4-removed-class sweep of the codebase:
- LocationAutocomplete passed `root: 'form-group'` to react-places-autocomplete;
  BS5 removed `.form-group` (it gave the bottom margin) -> use `mb-3`.
- Drop the unused `popper.js@1` dependency (react-bootstrap bundles
  @popperjs/core@2). No source imports it.

Sweep otherwise clean: no other BS4-only utility/component classes remain in JSX
or SCSS. Full-app build boots clean.
2026-07-22 10:12:49 +02:00
bddfb392c1 bootstrap: swap BS4 (alexwine) CSS for bootstrap@5 npm
Completes the Bootstrap 4->5 migration now that every jQuery/BS4 widget is React
(navbar, carousel, dropdowns) — plus the feedback toggle here (Feedback.js:
global `$('#feedback-form').toggle()` -> React state).

- Load Bootstrap 5 CSS from the `bootstrap` npm package in client/index.js
  (imported first so app + component styles and react-bootstrap override it).
- Remove the `alexwine:bootstrap-4` meteor package (BS4 CSS + jQuery + BS4 JS).
  jQuery for jquery-validation still comes from the npm `jquery` dep.
- Utility renames to BS5: ml-auto->ms-auto, float-right->float-end,
  btn-block->w-100, data-toggle->data-bs-toggle (FromNow tooltip).
- forms.scss `.form-label` is no longer a shim (BS5 ships it); comment updated.

Full-app build boots clean; server suite 36 passing. Needs a visual staging pass
across all pages (BS4->5 shifts grid gutters/typography); forms should improve
since react-bootstrap v2 already emitted BS5 markup.
2026-07-22 05:55:34 +02:00
9ff9abacc3 bootstrap: lang/type dropdowns jQuery -> react-bootstrap <Dropdown>
The false-positive-type selector (Fires.js) and the language selector
(Profile.js) used Bootstrap's jQuery dropdown (`data-toggle="dropdown"`), the
last widgets depending on the BS4 jQuery JS that goes away with the CSS swap.
Replace both with react-bootstrap <Dropdown>/<Dropdown.Toggle>/<Dropdown.Item>
(open/close in React, no jQuery). Keeps the `.lang-selector` hook and `.btn-group`
layout; works on the current BS4 CSS.

Full-app build boots clean.
2026-07-22 01:01:59 +02:00
f775d4ac26 bootstrap: home carousel jQuery plugin -> react-bootstrap <Carousel>
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.
2026-07-22 00:13:10 +02:00
8dead27d22 bootstrap: navbar collapse jQuery -> React state (BS4->5 prep)
Bootstrap's jQuery collapse (`data-toggle="collapse"` in Navigation.js, plus the
per-NavItem `data-target=".navbar-collapse.show"` auto-close) disappears when we
drop `alexwine:bootstrap-4` for `bootstrap@5`. Replace it with a React `useState`
that toggles `.show`, and close the mobile menu via an onClick on the nav <ul>.

Works on the current BS4 CSS (`.collapse.show` is pure CSS; jQuery only added the
height animation) and removes one of the two jQuery/BS4 JS blockers to the CSS
swap (the home carousel is the other). Also drops the dead sr-only toggler button
that targeted a non-existent id. No CSS changes.
2026-07-21 23:04:02 +02:00
6b6f02d92d quality: web debt batch (tests runner, FireContainer, rate-limit, maps, i18n)
Independent-of-prod quality debt from PENDIENTE.md §2:

- test: migrate broken Jest -> meteortesting:mocha. Tests rewritten to chai +
  Meteor 3 async APIs, moved to test/server/ (server-only). test/server/
  00-setup.test.js re-runs the collection2/accounts init that `meteor test`
  skips (no server/main.js). New comments method + mediaAnalyzers coverage.
  Dropped rest.test.js (removed meteor/http; covered by smoke/). 36 passing.
- fix: scope FireContainer read by the URL _id on the archive route instead of
  a selector-less FiresCollection.findOne() (imports/ui/pages/Fires/Fires.js).
- feat: rate-limit abusable publications via rateLimitSubscriptions (fireFrom*
  and comments.forReference 5/1000ms; geo subs 10/1000ms).
- perf: append loading=async to the Google Maps loader URL (Gkeys.js).
- deps: meteor-accounts-t9n 2.0 -> 2.6 (no gl build -> keep gl->es fallback,
  documented); add 3 missing gl/common.json keys (0 missing now).
- deps: drop jest/babel/enzyme, add chai.
2026-07-21 22:59:06 +02:00
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
b710388f50 refactor: LoadingBar via progressbar.js + ref (drops react-progress-bar.js findDOMNode)
react-progress-bar.js (unmaintained wrapper) rendered the progress line
through findDOMNode. Reimplemented LoadingBar with progressbar.js directly
(the wrapper's own underlying dep) via a ref + useEffect — same thin line
(strokeWidth 2, #5A7636), no findDOMNode. Promoted progressbar.js to a
direct dependency and removed react-progress-bar.js. Verified progressbar.js
draws its SVG in-browser; findDOMNode gone from /fires and home; REST smoke
byte-identical.
2026-07-21 14:24:32 +02:00
0abf5b4f02 deps: react-share 2 -> 5 (drops its defaultProps warnings)
react-share 2.0 shipped function components with defaultProps (CreatedButton,
Icon) -> React-19-blocking warnings on fire-detail pages. v5 is React-18-safe
and drops them. Removed the GooglePlusShareButton/Icon (Google+ is dead;
removed from react-share in v4+); the other 6 buttons (Facebook, Twitter,
Telegram, WhatsApp, Reddit, Email) are API-compatible. Browser-verified 6
buttons render, no defaultProps warnings. REST smoke byte-identical.
2026-07-21 14:14:48 +02:00
258723ea72 refactor: Reconnect banner Blaze -> native React (drops findDOMNode)
Reconnect rendered the Blaze meteorStatus template via
gadicc:blaze-react-component, whose bridge uses the deprecated findDOMNode
(warned on every page since it's always mounted). Reimplemented natively
with useTracker(Meteor.status) + a countdown effect, same behaviour and
reusing 255kb:meteor-status's .meteor-status CSS. Also dropped the dead
Blaze import from App.js.

Remaining findDOMNode warnings are third-party only: react-progress-bar.js
(LoadingBar) and Status.js's Blaze serverFacts (/status admin page).
Browser-verified home renders, no banner while connected, no new errors.
REST smoke byte-identical.
2026-07-21 14:08:52 +02:00
229b2cb233 cleanup: UNSAFE_componentWillReceiveProps -> modern lifecycles (React 19)
The 4 class components on UNSAFE_componentWillReceiveProps converted:
- FromNow, FireStats: state is a pure mirror of props -> getDerivedStateFromProps
- Fires: split the derived state (getDerivedStateFromProps) from the URL-
  canonicalization side effect (componentDidUpdate, guarded by prevProps) so
  the side effect never runs inside the pure gDSFP
- SelectionMap: marker is also locally draggable, so gDSFP would clobber a
  drag -> componentDidUpdate guarded on a real center/distance value change
  (no clobber, no setState loop), merged with the existing fit()

Browser-verified: /fires count, fire detail + FromNow, active-fire URL
canonicalizes to /fire/archive/:id, home SelectionMap renders stably (no
render loop). No UNSAFE_ warnings remain from our code. REST smoke
byte-identical.
2026-07-21 14:03:44 +02:00
4ddaa0d8ec cleanup: defaultProps -> JS default params on our function components
React 19 drops defaultProps on function components. Converted the 9 of
ours that used it (App, Navigation, ReSendEmail, Reconnect, OAuthLoginButton,
PageHeader, Page, EditDocument, EditSubscription) to destructured default
params; App defaults userId/emailAddress in its withTracker instead (it
spreads {...props} widely). Class components keep defaultProps (still
supported). The only defaultProps warnings left are from the react-share
npm package (CreatedButton/Icon), not our code. REST smoke byte-identical.
2026-07-21 13:54:02 +02:00
5661e129fb fix: NaN in /fires 'active fires in map' count (react-i18next 14 <Trans>)
react-i18next 14 reserves `count` as the pluralization variable and no
longer interpolates it from a <Trans> object child, so <strong>{{count:N}}</strong>
left {{count,number}} unresolved -> the number formatter ran on undefined ->
"NaN". (t() and the countTotal var were unaffected; regression from the
i18next 10->23 / react-i18next 7->14 bump.)

Renamed the variable count -> inMap in FiresMap.js and in the
activeFireInMapCount value of the es/en/gl locales (the string has no plural
forms, so count was only an unlucky name). Browser-verified: /fires now shows
the real count; home/zones/fire-detail render with no real errors. REST smoke
byte-identical.
2026-07-21 13:45:59 +02:00
e2d13ca64c deps: react-router-dom 4 -> 6 (history 5, react-router-bootstrap 0.26)
Removes the Router/Switch/Route/Link/LinkContainer legacy-context
warnings. Keeps the shared history singleton (used outside React by
NotificationsObserver + Utils/location) via unstable_HistoryRouter, and
bridges v6 hooks back to v4-shaped history/match/location props with a
new withRouterCompat HOC so the ~20 class pages stay untouched.

- <Switch> -> <Routes>, component= -> element=
- Authenticated/Public -> guard components (children or <Navigate replace>)
- LocationListener -> useLocation + useEffect function
- regex route /fire/:type(active|archive|alert)/:id -> /fire/:type/:id
- history.listen callback is ({ location }) in history v5

Browser-verified: SPA nav, /subscriptions->/login auth redirect,
deep-link /fire/archive/:id (params), browser back/forward. REST smoke
byte-identical.
2026-07-21 13:00:15 +02:00
a1a1b9a801 deps: react-bootstrap 0.31 -> 2 (Bootstrap 5 CSS deferred as debt)
Removes the largest batch of React-19-blocking warnings: the 0.31
components (Grid, FormGroup, ControlLabel, Navbar.Header/Brand, Checkbox,
SafeAnchor) all leaned on legacy context / defaultProps.

29 files converted: Grid->Container, FormGroup/ControlLabel/FormControl/
HelpBlock -> Form.Group/Label/Control/Text, Checkbox -> Form.Check (label
as prop), bsStyle->variant (default->secondary), bsSize->size,
pull-right->float-end. Custom Col.js now re-exports v2's Col; custom
NavItem.js rewritten self-contained (no SafeAnchor/createChainedFunction);
Navigation.js drops react-bootstrap Navbar (raw markup anyway).

CSS stays on Bootstrap 4 (alexwine:bootstrap-4) for now: the BS4->5 jump
is entangled with the jQuery carousel/swipe + navbar-collapse and is
tracked as separate debt in UPGRADE.md. Only .form-label needed a shim
(forms.scss). Browser-verified home carousel+navbar, signup form + terms
checkbox, login form; REST smoke byte-identical.
2026-07-21 12:44:46 +02:00
12bdbe8fed deps: i18next 10 -> 23, react-i18next 7 -> 14
Modernizes the whole i18n stack:
- 48 translate([], {wait:true}) / translate() HOCs -> withTranslation()
- react.wait:true -> react.useSuspense:false
- whitelist -> supportedLngs; added compatibilityJSON: 'v3' so our
  natural-language keys + v3 _plural layout keep working (custom
  separators ss/eth/dj preserved)
- backends: xhr -> i18next-http-backend (client), sync-fs ->
  i18next-fs-backend (server); dropped i18next-localstorage-cache
  (was enabled:false); languagedetector 2 -> 8
- ReSendEmail: <Interpolate> (removed in v10) -> <Trans values={{email}}/>,
  dropped the removed bare t export
- saveMissing handler signature (lngs, ns, key, fallbackValue)

Silences the per-component Translate/I18n legacy-context warnings.
Browser-verified es/en switch and <Trans> interpolation on /fires;
REST smoke byte-identical.
2026-07-18 06:28:41 +02:00
f1eae84e25 deps: react-helmet -> react-helmet-async 2
react-helmet 5 is unmaintained and breaks under React 18 StrictMode.
Same <Helmet> API in the 15 pages; HelmetProvider wraps <App/> in the
client entry. Browser-verified: per-page titles, meta description and
hreflang alternates all inject. REST smoke byte-identical.
2026-07-18 06:14:14 +02:00
f51acf4d78 deps: drop dead npm packages (reactstrap, sidebarv2, hash-link, pure-render-mixin)
None of them is imported anywhere: reactstrap 5.0.0-alpha.3 was never
adopted (react-bootstrap covers the UI), react-leaflet-sidebarv2 and
react-addons-pure-render-mixin were never used, and react-router-hash-link
only survived as a commented-out import in Index.js.
2026-07-18 06:02:49 +02:00
a997aa7cae cleanup: silence our own React dev-console warnings
UNSAFE_ rename of our 4 componentWillReceiveProps (FireStats, Fires, FromNow,
SelectionMap) and Authenticated/Public component propType func -> elementType.
Rest of the console noise is legacy react-* dev-mode warnings, absent in prod.
2026-07-18 05:47:44 +02:00
9feaca9d0b fix: fire ids leaked into URLs as ObjectID("...") on Mongo 7
Fire collections use idGeneration:'MONGO', so _id is a Mongo.ObjectID whose
toString() is ObjectID("<hex>"), not the bare hex. Interpolating _id into a
URL produced /fire/archive/ObjectID("c0..."), which no route matches -> the
fire-detail page 404'd. New hexId() helper returns the 24-char hex for an
ObjectID (and passes plain strings through); applied at the three string-context
sites: the map-marker click URL (MarkListeners), the active->archive redirect,
and the comments referenceId (Fires.js). Left falsePositives.insert untouched —
its check() expects a Meteor.Collection.ObjectID, so it takes the object.

Verified in browser: /fire/archive/<hex> and /fire/active/<hex> render the
detail page (map + comments), URL stays clean hex, no ObjectID( anywhere.
2026-07-17 18:31:59 +02:00
c6c22643c1 scss: migrate @import -> @use, lighten/darken -> color.adjust (dart-sass)
Silences the dart-sass deprecation warnings that flooded every build:
- All @import of local partials (colors, mixins, and the CSS-emitting
  partials) -> @use '...' as * (partials are pure defs, so 'as *' keeps the
  global names and the ~25 call sites unchanged). Added explicit @use './colors'
  to bootstrap-overrides.scss and cookies-eu.scss, which used -palette*
  transitively (broke under @use's scoping).
- lighten(c, x%) -> color.adjust(c, $lightness: x%) and darken -> negative,
  with @use 'sass:color' in the 6 affected files.
Compiles clean (byte-for-byte CSS behavior preserved).
2026-07-17 18:18:04 +02:00
62ac2fbd9c sentry: tunnel client events through the app to dodge Cloudflare's 503
GlitchTip is behind Cloudflare, which answers the browser's cross-site ingest
POSTs with 503 (no CORS headers -> 'Failed to fetch'); server-side requests
pass. The browser SDK now posts envelopes same-origin to /sentry-tunnel, and
the server forwards them to GlitchTip:
- imports/startup/server/sentryTunnel.js: WebApp handler that relays the raw
  envelope to <dsn>/api/<project>/envelope/?sentry_key=<key> over IPv4
  (family:4 avoids Happy-Eyeballs picking Cloudflare's unroutable IPv6 on
  IPv4-only hosts). GlitchTip authenticates by the sentry_key query, so the
  key is derived from the DSN and passed explicitly.
- client ravenLogger: tunnel: '/sentry-tunnel'.
Verified: POST /sentry-tunnel -> 200 (envelope reaches GlitchTip).
2026-07-17 18:17:47 +02:00
4ca7e198d3 meteor3: raven -> @sentry/node + @sentry/browser
flowkey:raven (Sentry legacy SDK) is dead on Meteor 3 and, with the old
sentry.comunes.org DSN unreachable, spammed the boot log with 502s on every
exception. Replaced by the modern SDKs (8.x) behind the same ravenLogger.log()
facade so the 6 call sites are unchanged. Empty DSN -> plain console logger
(same behavior as before).

End-to-end verified against a real backend: GlitchTip deployed on aaron
(Sentry-compatible, fits in ~1.5GB vs Sentry's 16GB), fronted at
sentry.comunes.org. A test exception sent from the dev server appeared in
GlitchTip within seconds. REST smoke byte-identical (12/12).
2026-07-16 12:20:02 +02:00
1f1f5c697d meteor3: port all 18 migration up() bodies to async
percolate:migrations 2.0.1 awaits async up(), so historical migrations
now run on Meteor 3: fetchAsync + for..of instead of cursor forEach,
insert/update/remove -> *Async, _ensureIndex -> createIndexAsync,
Accounts.createUser -> createUserAsync, awaited rawCollection indexes.

Verified: empty Mongo 7 DB migrates 0->18 cleanly (indexes + industry
registries created, control unlocked at v18); pre-marking version=18 is
no longer needed (UPGRADE.md updated). REST smoke stays byte-identical.
2026-07-14 11:36:30 +02:00
1892c0ead0 meteor3: React 16 -> 18.3 with createRoot
react/react-dom ^18.3.1 (--legacy-peer-deps for the pinned ancient react-*
libs, which still work on 18 via legacy context but gate React 19). Client
entry uses createRoot. Browser-verified on / and /fires; REST smoke
byte-identical (12/12).
2026-07-14 11:32:37 +02:00
eb3aec82ae meteor3: purge dead client packages — web UI renders on 3.1
alanning:roles removed (client crashed the whole bundle; plain user.roles
checks instead), selaias:cookie-consent replaced by in-repo React banner,
publish-performant-counts vendored with countAsync, Meteor.autorun dropped
(App)/Tracker.autorun (FiresMap), and the map publications not covered by
the REST smoke (activefiresmyloc, activefiresunionmyloc, fireAlerts,
oauth.verifyConfiguration) converted to async APIs.

Verified in browser: / and /fires render with map + cookie banner, zero
uncaught exceptions. REST smoke byte-identical (12/12).
2026-07-14 11:32:19 +02:00
0ff9848cd4 meteor3: re-enable fixtures and sitemaps with async/Meteor-3 implementations
fixtures: drop @cleverbeagle/seeder (sync Mongo, unmaintained) for a small
idempotent async seeder (same dev accounts). sitemaps: drop dead
gadicohen:sitemaps for a WebApp.connectHandlers /sitemap.xml with the same
static page list (the per-fire section was already disabled). Verified on
dev boot: 6 users ensured, sitemap serving; REST smoke byte-identical.
2026-07-14 07:06:07 +02:00
66bab7a43b meteor3: Comments methods and mail fan-out to async
comments.insert/edit/remove/like/dislike use *Async collection APIs;
requireOwner/toggle helpers are async; onCommentAdd iterates users with
forEachAsync. subscriptions.* methods were already async. REST smoke stays
byte-identical (12/12).
2026-07-14 06:52:32 +02:00
feaf66fe34 meteor3: web Fires publications to async (findOneAsync/countAsync/awaited firesUnion)
fireFromId, fireFromAlertId, fireFromActiveId and fireFromHash now use the
async collection APIs and async publish handlers (so try/catch catches
rejections). falsePositivesMyloc/industriesMyloc/comments.forReference are
cursor-only and needed no change. Verified over raw DDP against the seeded
dev Mongo 7; REST smoke stays byte-identical (12/12).
2026-07-14 06:52:08 +02:00
637a749e8d meteor3: REST API async migration COMPLETE — smoke green on Meteor 3.1 + Mongo 7
All 12 Flutter REST endpoints byte-identical to the 1.6.1.1 baseline, running on
Meteor 3.1 against dockerized MongoDB 7. The 3.x jump works end-to-end.

- Rest.js: every endpoint action -> async; all Mongo calls -> *Async
  (findOneAsync/countAsync/fetchAsync/upsertAsync/removeAsync).
- Helpers to async: countRealFires (accepts array|cursor, forEachAsync->for-of),
  firesUnion (fetchAsync), fireFromHash/findOrCreateFire (await, dropped Fibers
  Promise.await), subscriptionsInsert/subscriptionsRemove, upsertFalsePositive,
  falsePositives.insert, subscriptions.update method, countFiresInRegions.
- getFires: countAsync() on a $near cursor throws on the mongodb 6 driver
  ($near not allowed in the aggregation countDocuments uses) -> fetch once and
  use array length for total.
- Route order: json-routes 3.0 matches in registration order, so
  mobile/subscriptions/all/:token/:mobileToken is now registered BEFORE
  :token/:mobileToken/:subsId (else GET .../all/x/y hit the delete-only route).
2026-07-14 06:21:35 +02:00
b37069c3e5 WIP(meteor3): server BOOTS on 3.1 + Mongo 7; restivus async-patched
Major milestone: the Meteor 3.1 server boots and runs against dockerized
MongoDB 7, and the REST framework responds (status/uptime OK).

- collection2 v4: import its eager entry 'meteor/aldeed:collection2/static.js'
  from new eager files server|client/00-collection2-init.js so main.js runs and
  patches attachSchema before collections load (v4 is fully lazy, no main module).
- fixtures.js disabled: @cleverbeagle/seeder uses sync Mongo, no Meteor 3 support
  (dev fixtures, not needed for smoke). Debt.
- sitemaps.js disabled: gadicohen:sitemaps@0.0.17 pre-0.9 API, no 'sitemaps'
  global on Meteor 3. Debt (SEO).
- Vendored restivus patched for async endpoints: route handler is async and
  awaits _callEndpoint; _callEndpoint awaits the action + auth/role checks.

NEXT: Rest.js endpoints + helpers (countRealFires/firesUnion/whichAreFalsePositives/
fireFromHash/subscriptionsInsert/upsertFalsePositive) still use sync Mongo
(.count()/.findOne()/.fetch()/.insert()/.upsert()) -> convert to *Async, then
smoke test against Mongo 7.
2026-07-14 06:11:00 +02:00
25dc1b99c0 WIP(meteor3): boot progresses past linker + several async fixes
Past the client-bundle underscore linker (pin underscore@1.6.4) and now working
through the server async/await migration on Meteor 3.1 + Mongo 7:

- Removed fibers (imports/startup/server/fibers.js + import) — gone in Meteor 3.
- accounts/oauth.js: upsert -> upsertAsync (top-level await).
- migrations.js: startup async + await Migrations.migrateTo (async in 2.x).
  mongo7 marked at version 18 so historical up() bodies (still sync Mongo) don't
  run — prod data restores already-migrated. Documented.
- subsUnion.js: fully async (fetchAsync/findOneAsync/countAsync/upsertAsync,
  observeAsync with async callbacks).
- facts.js: dropped dead sync findOne.
- email.js: ostrio:mailer 2.5 is a default export (was named import); dropped
  removed static MailTime.Template (built-in default '{{{html}}}').

NEXT wall + remaining chain (multi-session):
1. aldeed:collection2@4.2.0 needs simpl-schema 3.x (app has 1.x) -> 'attachSchema
   is not a function'. Requires upgrading npm simpl-schema to 3.x and migrating
   all collection schemas (SimpleSchema.RegEx.Id etc.) across ~8 files.
2. Rest.js + helpers (countRealFires/firesUnion/whichAreFalsePositives/
   fireFromHash/subscriptionsInsert/upsertFalsePositive) -> *Async.
3. Patch vendored restivus to await async endpoint handlers.
4. methods/publications/comments to async; cron SyncedCron(quave)/Facts imports.
5. alanning:roles@1.2.10 + gadicohen:sitemaps@0.0.17 warn incompatible -> bump.
6. React 16 -> 18 render root.

Run with: NODE_OPTIONS='--dns-result-order=ipv4first --no-network-family-autoselection'
MONGO_URL='mongodb://localhost:27019/fuegos?replicaSet=rs0'
2026-07-13 23:46:45 +02:00
cd570b9d9c escala 2+3: Meteor 1.8.3 -> 2.3 (Mongo 3.2 compatible), dead-package remediation
Reaches Meteor 2.3 building + running against Mongo 3.2, REST smoke test
byte-identical to the 1.6.1.1 baseline (all 12 Flutter endpoints green).

Dead/abandoned Atmosphere packages removed or replaced (the upgrade blockers):
- arkham:comments-ui (no Meteor 2.x build; pinned accounts-password@1.x):
  reimplemented the fire-page comments as a React feature:
    imports/api/Comments/ (collection, server methods, publication, media
    analyzers, new-fire-comment email) + imports/ui/components/Comments/CommentsBox.
    Comment text now rendered as safe plain text + image/youtube embed (was
    markdown-to-HTML). Wired into Fires.js; sitemaps.js + migration v11 updated
    to the new collection. Old Blaze/startup comments files deleted.
- nimble:restivus (REST API; pinned accounts-password@1.3.3, CoffeeScript source
  that crashes this build host): vendored as a local package
  packages/nimble-restivus with the .coffee precompiled to plain JS and the
  accounts-password constraint loosened to 2.x. REST behavior unchanged
  (verified by smoke test). This also dropped the entire iron:router stack.
- maximum:server-transform (+ peerlibrary:*, meteorhacks:zones/inject-initial):
  unused; removal broke Meteor.publishTransformed in FalsePositives publications
  -> replaced with plain Meteor.publish (no transform was configured).
- less, markdown (no source files), and the dead test stack
  (meteortesting:mocha, practicalmeteor:chai, xolvio:cleaner) which transitively
  pulled coffeescript@1.0.17 — the build plugin that crashed meteor-tool
  (node_contextify assertion) on this machine. Removing it unblocked the build.
- fourseven:scss 4.5.4 -> 4.14.1 (node-sass 4.5.3 doesn't build on node 12).

npm-mongo driver at 2.3 is 3.9.x — still compatible with the production Mongo
3.2 replica set.
2026-07-13 22:24:09 +02:00
dc8a05a0d4 notif: remove code migrated to tcef-notifications microservice
The push/email notification processing now lives in the tcef-notifications
service (fases 1a-1c). Removed from the web:
- imports/startup/server/notificationsObserver.js (observe Notifications -> processNotif)
- imports/modules/server/notificationsProcess.js (node-gcm push + notif emails)
- the 'Process pending notif' SyncedCron job in cron.js
- node-gcm dependency (dead Google API since jun-2024)

subsUnion.js is KEPT: it feeds the subs-public-union SiteSettings that the REST
API (status/subs-public-union) serves to the Flutter app; it is not part of the
notifications pipeline.

DEPLOY ORDERING (see UPGRADE.md): production must not run this build until the
tcef-notifications service is emitting in prod — otherwise notifications stop.
REST smoke test green (byte-identical).
2026-07-13 19:45:13 +02:00
296dab4f38 smoke: REST API regression harness + baseline snapshots (Meteor 1.6.1.1)
Adds a standalone Node smoke test (smoke/) that exercises every REST endpoint
consumed by the Flutter app against a seeded local dev server and compares
responses to committed snapshots. This is the safety net for the Meteor upgrade:
it must stay byte-identical after every escala.

- smoke/seed.js: deterministic Mongo seed (fixed ObjectIds, geo indexes)
- smoke/run.js: calls endpoints, normalizes volatile fields, diffs snapshots
- smoke/smoke.sh: seed + run wrapper
- smoke/snapshots/: baseline captured on Meteor 1.6.1.1
- IPGeocoder.js: degrade gracefully when MaxMind DB absent (dev boot)
- settings-development.json: dev-only internalApiToken to enable the REST API
- .meteorignore: exclude smoke/ from the Meteor server build
2026-07-13 19:42:55 +02:00
39415808bf Fase 1a: flag de cutover notifDisabledChannels en processNotif
Guard reversible al inicio de processNotif: los canales listados en
settings.private.notifDisabledChannels (p.ej. ['mobile','web']) los gestiona el
microservicio tcef-notifications, y el observer/cron viejos los ignoran.
Exclusion mutua por canal sin desplegar codigo (solo editar settings).
ES5-compatible (Meteor 1.6 / Node 8).
2026-07-13 00:10:39 +02:00
2a31435135 Refactor server startup: elimina segfaults, añade leaflet-workaround
Retira import './segfaults' (workaround de crash obsoleto) y añade
leaflet-workaround.js (shims global window/document/navigator para
render de Leaflet en servidor). Ajustes menores en publications de
FalsePositives y subsUnion.
2026-07-12 23:26:16 +02:00
vjrj
4cbbe65fa3 Fix wrong grey tiles 2022-08-13 19:37:56 +02:00
vjrj
b9457fe141 Minor changes in fires union 2018-12-23 13:31:41 +01:00
vjrj
1fdf86dd47 Union of subs 'null' when app is initialized 2018-11-18 16:24:49 +01:00
vjrj
5f9a84dfd7 Unify don't calc boundaries of empty union 2018-11-18 15:45:14 +01:00
vjrj
564b9e8ead Trying to fix race condition in i18n load 2018-11-18 15:43:48 +01:00
vjrj
df51368d50 Better log in error 2018-11-18 15:05:04 +01:00
vjrj
8903c765e3 Minor refactor 2018-11-18 14:27:51 +01:00
vjrj
266707052c Better error message 2018-11-18 14:27:34 +01:00
vjrj
3f8bc3666b Fixed index DOM warning. Google Play btn height 2018-11-18 13:08:36 +01:00
vjrj
6abe668740 Added fires union (wip) 2018-11-18 11:48:03 +01:00
vjrj
7b5f17fbe8 Added activeFiresUnion (wip) 2018-10-28 20:27:38 +01:00