todos-contra-el-fuego-web/smoke
vjrj 8fa10e47c7 WIP: Meteor 2.5 -> 3.1 migration (package resolution done; build blocked)
Reaches release METEOR@3.1 with all package-version conflicts resolved against a
modern dockerized MongoDB 7 (replica set). NOT yet building — parked here.

Done:
- MongoDB 7 single-node replica set (docker, port 27019) as the fuegos DB,
  decoupled from the shared rsmain 3.2 (unblocks Meteor 3's mongodb driver).
- meteor update --release 3.1 resolves after swapping dead packages:
  mongo-livedata removed; facts -> facts-base; saucecode:timezoned-synced-cron
  -> quave:synced-cron; aldeed:collection2-core -> aldeed:collection2@4.0.4;
  mys:fonts removed (pinned caching-compiler@1.0.0); fourseven:scss 4.14.1 ->
  5.0.0 (Dart Sass, no node-sass) + sass installed; nimble-restivus vendored
  package loosened to accounts-password 2.x||3.x.
- Network: meteor-tool node 22 needs NODE_OPTIONS='--dns-result-order=ipv4first
  --no-network-family-autoselection' to reach warehouse.meteor.com (Happy
  Eyeballs picks an unreachable IPv6 otherwise).
- smoke/smoke.sh generalized to mongosh + configurable port for Mongo 7.

Blocked on (remaining Meteor 3 work):
1. Client bundle linker: 'Runtime is not available, but it uses features needing
   the runtime: underscore' — an old client atmosphere package needs replacing.
2. Server async/await migration (Rest.js + helpers + methods + publications +
   comments + subsUnion + migrations to *Async; no Fibers).
3. Patch vendored restivus to await async endpoint handlers.
4. cron.js SyncedCron import (quave), facts.js Facts import (facts-base).
5. React 16 -> 18 render root (createRoot).
6. SCSS @import/@use + lighten/darken -> color.adjust (dart-sass deprecations).
2026-07-13 23:25:29 +02:00
..
snapshots smoke: REST API regression harness + baseline snapshots (Meteor 1.6.1.1) 2026-07-13 19:42:55 +02:00
README.md smoke: REST API regression harness + baseline snapshots (Meteor 1.6.1.1) 2026-07-13 19:42:55 +02:00
run.js smoke: REST API regression harness + baseline snapshots (Meteor 1.6.1.1) 2026-07-13 19:42:55 +02:00
seed.js smoke: REST API regression harness + baseline snapshots (Meteor 1.6.1.1) 2026-07-13 19:42:55 +02:00
smoke.sh WIP: Meteor 2.5 -> 3.1 migration (package resolution done; build blocked) 2026-07-13 23:25:29 +02:00

REST smoke test

Regression harness for the REST API in imports/api/Rest/Rest.js — the API the Flutter app (fires_flutter/lib/models/fires_api.dart) depends on.

It calls every Flutter-consumed endpoint against a locally running dev server with deterministic seed data, normalizes the intrinsically volatile fields (uptime, generated ids, insert timestamps) and compares the responses to committed snapshots in smoke/snapshots/.

It must stay green after every Meteor upgrade escala. The snapshots are the contract: any drift is treated as an upgrade bug.

Reproducible local startup

  1. MongoDB (prod parity = 3.2; a dev-only instance in Docker):

    docker run -d --name tcef-mongo32 -p 27018:27017 mongo:3.2
    
  2. Meteor dev server (from the repo root):

    export PATH="$HOME/.meteor:$PATH"
    export MONGO_URL="mongodb://localhost:27018/fuegos"
    meteor --settings settings-development.json --port 3100
    

    settings-development.json carries a dev-only private.internalApiToken (dev-smoke-token) which is what enables the REST API. Without it the API routes are not even registered (see Rest.js).

    Note: IPGeocoder.js degrades gracefully when the MaxMind GeoLite2 DB is absent (it is provisioned by cron in production) so the server boots in a clean checkout.

Running the smoke test

./smoke/smoke.sh            # seed + compare against baseline snapshots
./smoke/smoke.sh --update   # seed + regenerate the baseline snapshots

Env overrides: MONGO_CONTAINER (default tcef-mongo32), MONGO_DB (fuegos), BASE_URL (http://localhost:3100).

What is covered

Snapshot Endpoint Flutter call
status_uptime GET status/uptime
status_active_fires_count GET status/active-fires-count
status_last_fire_check GET status/last-fire-check
status_last_fire_detected GET status/last-fire-detected
status_subs_public_union GET status/subs-public-union/:token getMonitoredAreas
fires_in GET fires-in/:token/:lat/:lng/:km
fires_in_full GET fires-in-full/:token/:lat/:lng/:km getFiresInLocation
mobile_users_post POST mobile/users createUser
mobile_subscriptions_post POST mobile/subscriptions subscribe
mobile_subscriptions_all GET mobile/subscriptions/all/:token/:mobileToken fetchYourLocations
mobile_subscriptions_delete DELETE mobile/subscriptions/:token/:mobileToken/:subsId unsubscribe
mobile_falsepositive_post POST mobile/falsepositive markFalsePositive

Normalized (volatile) fields

Compared structurally but blanked to a placeholder because they cannot be deterministic: status/uptimems; mobile/usersuserId, username, upsertResult.insertedId; mobile/subscriptions/allowner, createdAt, updatedAt; mobile/falsepositiveupsert.insertedId.

Everything else (ids of seeded docs, geometries, counts, jsend envelope, field names and types) is asserted byte-for-byte.