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.
This commit is contained in:
vjrj 2026-07-14 07:06:07 +02:00
parent 66bab7a43b
commit 0ff9848cd4
8 changed files with 20493 additions and 15709 deletions

View file

@ -49,7 +49,6 @@ aldeed:schema-deny
dburles:collection-helpers
reywood:publish-composite
facts-base@1.0.2
gadicohen:sitemaps
nspangler:autoreconnect
quave:synced-cron
# lmachens:kadira

View file

@ -47,7 +47,6 @@ flowkey:raven@1.1.0
fortawesome:fontawesome@4.7.0
fourseven:scss@5.0.0
gadicc:blaze-react-component@2.0.1
gadicohen:sitemaps@0.0.17
geojson-utils@1.0.12
github-oauth@1.4.2
google-oauth@1.4.5

View file

@ -241,6 +241,16 @@ MONGO_CONTAINER=tcef-mongo7 MONGO_SHELL=mongosh MONGO_PORT=27019 ./smoke/smoke.s
async, `users.findOneAsync` for the username. `onCommentAdd` mail fan-out:
`users.find().forEach``forEachAsync`. Still fire-and-forget from the
insert. Comments UI staging verification pending (pre-existing note below).
- ✅ **fixtures.js re-enabled**`@cleverbeagle/seeder` (sync Mongo, no Meteor
3 support) **removed from package.json** and replaced with a small in-repo
async seeder: idempotent, dev-only (staging opts in with `TCEF_SEED=1`);
same accounts as before (`admin@admin.com` / 5 test users / 5 Documents
each). Verified: `fixtures: 6 dev users ensured` on boot.
- ✅ **sitemaps.js re-enabled**`gadicohen:sitemaps` (pre-0.9 API, dead on
Meteor 3) **removed from .meteor/packages**; `/sitemap.xml` is now a small
`WebApp.connectHandlers` handler serving the same static page list (the
per-fire section of the old handler was behind `firesMapEnabled = false`,
i.e. dead code, and was dropped). Verified serving on dev.
### Still TODO before the web (not just REST) is fully deployable on 3.x
- **React 16 → 18** render root + verify ancient react-* libs.

View file

@ -1,54 +1,71 @@
import seeder from '@cleverbeagle/seeder';
/* eslint-disable no-await-in-loop */
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import Documents from '../../api/Documents/Documents';
const documentsSeed = userId => ({
collection: Documents,
environments: ['development', 'staging'],
noLimit: true,
modelCount: 5,
model(dataIndex) {
return {
owner: userId,
title: `Document #${dataIndex + 1}`,
body: `This is the body of document #${dataIndex + 1}`,
};
},
});
/*
* Dev/staging fixtures. Replaces @cleverbeagle/seeder (sync Mongo, no Meteor 3
* support) with a small async seeder: idempotent (find-before-create), only
* runs outside production.
*/
seeder(Meteor.users, {
environments: ['development', 'staging'],
noLimit: true,
data: [{
const USERS = [
{
email: 'admin@admin.com',
password: 'password',
profile: {
name: {
first: 'Andy',
last: 'Warhol',
profile: { name: { first: 'Andy', last: 'Warhol' } },
roles: ['admin']
},
},
roles: ['admin'],
data(userId) {
return documentsSeed(userId);
},
}],
modelCount: 5,
model(index, faker) {
const userCount = index + 1;
return {
email: `user+${userCount}@test.com`,
...[
['Frida', 'Kahlo'],
['Joaquín', 'Sorolla'],
['Maruja', 'Mallo'],
['Remedios', 'Varo'],
['Pablo', 'Picasso']
].map(([first, last], i) => ({
email: `user+${i + 1}@test.com`,
password: 'password',
profile: {
name: {
first: faker.name.firstName(),
last: faker.name.lastName(),
},
},
roles: ['user'],
data(userId) {
return documentsSeed(userId);
},
};
},
profile: { name: { first, last } },
roles: ['user']
}))
];
const DOCUMENTS_PER_USER = 5;
async function ensureUser({ email, password, profile, roles }) {
const existing = await Meteor.users.findOneAsync({ 'emails.address': email });
const userId = existing
? existing._id
: await Accounts.createUserAsync({ email, password, profile });
if (!existing && roles) {
await Meteor.users.updateAsync(userId, { $set: { roles } });
}
return userId;
}
async function ensureDocuments(userId) {
const count = await Documents.find({ owner: userId }).countAsync();
if (count > 0) return;
for (let i = 0; i < DOCUMENTS_PER_USER; i += 1) {
await Documents.insertAsync({
owner: userId,
title: `Document #${i + 1}`,
body: `This is the body of document #${i + 1}`
});
}
}
Meteor.startup(async () => {
// dev always; staging opts in with TCEF_SEED=1 (the old seeder's
// 'staging' environment had no reliable detection either).
if (!Meteor.isDevelopment && process.env.TCEF_SEED !== '1') return;
try {
for (const user of USERS) {
const userId = await ensureUser(user);
await ensureDocuments(userId);
}
console.log(`fixtures: ${USERS.length} dev users ensured`);
} catch (e) {
console.warn(`fixtures: seeding failed: ${e}`);
}
});

View file

@ -3,19 +3,13 @@ import './catchExceptions';
import './i18n';
import './accounts';
import './api';
// Meteor 3 debt: '@cleverbeagle/seeder' (dev/staging fixtures) uses sync Mongo
// (findOne) and has no Meteor 3 async support. Disabled — not needed for the
// REST smoke test. Re-implement dev fixtures with *Async if desired.
// import './fixtures';
import './fixtures';
import './email';
import '/imports/api/Comments/server';
import './IPGeocoder';
import './migrations';
import './facts';
// Meteor 3 debt: gadicohen:sitemaps@0.0.17 uses the pre-0.9 package API and no
// longer exports the `sitemaps` global on Meteor 3. Disabled (SEO sitemap, not
// on the REST path). Replace with a maintained sitemap approach if needed.
// import './sitemaps';
import './sitemaps';
import './subsUnion';
import './prerender';
import './feedback';

View file

@ -1,44 +1,37 @@
/* global sitemaps */
/* eslint-disable import/no-absolute-path */
import { Meteor } from 'meteor/meteor';
import { WebApp } from 'meteor/webapp';
import Fires from '/imports/api/Fires/Fires';
import Comments from '/imports/api/Comments/Comments';
/*
* /sitemap.xml own implementation replacing gadicohen:sitemaps (pre-0.9
* package API, dead on Meteor 3). Static pages only: the per-fire section of
* the old handler was behind `firesMapEnabled = false` (dead code) and was
* dropped; see git history if it's ever wanted back.
*/
const firesMapEnabled = false;
const PAGES = [
'/fires',
'/login',
'/signup',
'/recover-password',
'/credits',
'/terms',
'/license',
'/privacy',
'/about'
];
sitemaps.add('/sitemap.xml', () => {
const today = new Date();
function xmlEscape(s) {
return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
const out = [];
out.push({ page: '/fires', lastmod: today });
out.push({ page: '/login', lastmod: today });
out.push({ page: '/signup', lastmod: today });
out.push({ page: '/recover-password', lastmod: today });
out.push({ page: '/credits', lastmod: today });
out.push({ page: '/terms', lastmod: today });
out.push({ page: '/license', lastmod: today });
out.push({ page: '/privacy', lastmod: today });
out.push({ page: '/about', lastmod: today });
// When user has public page
/* const users = Meteor.users.find().fetch();
_.each(users, function(user) {
out.push({
page: '/persona/' + user.username,
lastmod: user.updatedAt
});
}); */
if (firesMapEnabled) {
Fires.find({}, { limit: 100, sort: { createdAt: -1 } }).fetch().forEach((fire) => {
// Search the last comment of tha fire
const lastComment = Comments.findOne({ referenceId: `fire-${fire._id}` }, { sort: { createdAt: -1 } });
out.push({
page: `/fire/archive/${fire._id._str}`,
lastmod: lastComment ? lastComment.createdAt : fire.updatedAt
});
});
}
return out;
WebApp.connectHandlers.use('/sitemap.xml', (req, res) => {
const lastmod = new Date().toISOString().slice(0, 10);
const urls = PAGES.map((page) => {
const loc = xmlEscape(Meteor.absoluteUrl(page.replace(/^\//, '')));
return ` <url>\n <loc>${loc}</loc>\n <lastmod>${lastmod}</lastmod>\n </url>`;
}).join('\n');
const body = `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>\n`;
res.writeHead(200, { 'Content-Type': 'application/xml; charset=utf-8' });
res.end(body);
});

20231
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,6 @@
"dependencies": {
"@babel/runtime": "^7.29.7",
"@cleverbeagle/dates": "^0.5.1",
"@cleverbeagle/seeder": "^1.3.1",
"@turf/buffer": "^5.1.5",
"babel-runtime": "^6.26.0",
"bcrypt": "^1.0.3",