Files
indiekit-server/scripts/patch-webmention-sender-reset-stale.mjs
Sven c0b9878033 fix(webmention): silence retry noise for all livefetch versions, bump stale migration to v10
retry patch: regex now matches [patched:livefetch] and [patched:livefetch:vN]
so it silently skips for any livefetch version, not just v2.

reset-stale: bump to v10 to retry posts stuck during v5 rollout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:56:02 +01:00

81 lines
2.6 KiB
JavaScript

/**
* One-time migration: reset posts that were incorrectly marked as webmention-sent
* with empty results because the live page was not yet deployed when the poller fired.
*
* Runs at startup but only executes once (guarded by a migrations collection entry).
* After running, the patch-webmention-sender-livefetch.mjs v2 fix prevents recurrence.
*/
import { MongoClient } from "mongodb";
import config from "../indiekit.config.mjs";
const MIGRATION_ID = "webmention-sender-reset-stale-v10";
const mongodbUrl = config.application?.mongodbUrl;
if (!mongodbUrl) {
console.log("[patch] webmention-sender-reset-stale: no MongoDB URL, skipping");
process.exit(0);
}
const client = new MongoClient(mongodbUrl, { connectTimeoutMS: 5000 });
try {
await client.connect();
const db = client.db();
// Check if this migration has already run
const migrations = db.collection("migrations");
const alreadyRun = await migrations.findOne({ _id: MIGRATION_ID });
if (alreadyRun) {
console.log("[patch] webmention-sender-reset-stale: already run, skipping");
process.exit(0);
}
// Find posts marked as webmention-sent with all-zero/empty results.
// These were silently marked by the bug (failed fetch → empty results).
// Match both old format (counts = 0) and new v1.0.6+ format (empty arrays).
const posts = db.collection("posts");
const result = await posts.updateMany(
{
"properties.webmention-sent": true,
$or: [
// Old format: numeric counts all zero
{
"properties.webmention-results.sent": 0,
"properties.webmention-results.failed": 0,
"properties.webmention-results.skipped": 0,
},
// New format: detail arrays all empty
{
"properties.webmention-results.details.sent": { $size: 0 },
"properties.webmention-results.details.failed": { $size: 0 },
"properties.webmention-results.details.skipped": { $size: 0 },
},
],
},
{
$unset: {
"properties.webmention-sent": "",
"properties.webmention-results": "",
},
},
);
console.log(
`[patch] webmention-sender-reset-stale: reset ${result.modifiedCount} post(s) for retry`,
);
// Record that this migration has run
await migrations.insertOne({
_id: MIGRATION_ID,
ranAt: new Date().toISOString(),
modifiedCount: result.modifiedCount,
});
} catch (error) {
console.error(`[patch] webmention-sender-reset-stale: error — ${error.message}`);
// Non-fatal: don't block startup
} finally {
await client.close().catch(() => {});
}