feat(news): harden news002 image gate after main merge
Memind CI / Test, build, and release guards (push) Has been cancelled

Reject weak or unreachable source images, auto-promote lead cards for
structure audit, and relax push gates while keeping text-only cards.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-09-22 09:34:00 +08:00
parent 67951c1862
commit 58003e88a0
7 changed files with 263 additions and 53 deletions
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env node
/**
* 就地修复 news002 页面:校验/重拉配图,剔除无图卡,写回 public HTML。
*
* H5_ROOT=/Users/john/Project/Memind node scripts/repair-news002-page-images.mjs
* H5_ROOT=... node scripts/repair-news002-page-images.mjs --slug daily-news-0921
*/
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { loadH5Environment } from './load-env.mjs';
import {
auditNews002ImageCoverage,
enrichNews002HtmlWithSourceImages,
pruneNews002ImagelessStoryCards,
} from '../wechat-news-morning-images.mjs';
loadH5Environment(import.meta.dirname);
const DEFAULT_USER = 'a70ff537-8908-486e-9b6c-042e07cc25db';
async function main() {
const slugArg = process.argv.find((arg) => arg.startsWith('--slug='));
const slug = slugArg ? slugArg.slice('--slug='.length) : 'daily-news-0921';
const userId = process.env.H5_WECHAT_NEWS_MORNING_DRAFT_USER_ID?.trim() || DEFAULT_USER;
const h5Root = process.env.H5_ROOT?.trim() || path.join(import.meta.dirname, '..');
const pagePath = path.join(h5Root, 'MindSpace', userId, 'public', `${slug}.html`);
if (!fs.existsSync(pagePath)) {
console.error(`page not found: ${pagePath}`);
process.exit(1);
}
const before = fs.readFileSync(pagePath, 'utf8');
const enriched = await enrichNews002HtmlWithSourceImages(before, {
timeoutMs: Number(process.env.MEMIND_NEWS_MORNING_IMAGE_META_TIMEOUT_MS ?? 8000) || 8000,
concurrency: Number(process.env.MEMIND_NEWS_MORNING_IMAGE_META_CONCURRENCY ?? 8) || 8,
});
const display = pruneNews002ImagelessStoryCards(enriched.html);
fs.writeFileSync(pagePath, display.html);
const audit = auditNews002ImageCoverage(display.html, { requireTemplateStructure: true });
console.log(JSON.stringify({
pagePath,
enriched: {
resolvedCount: enriched.resolvedCount,
rejectedCount: enriched.rejectedCount ?? 0,
removedCards: enriched.removedCards ?? 0,
},
display: {
removedCards: display.removedCards,
removedSections: display.removedSections,
},
audit,
}, null, 2));
if (!audit.ok) process.exit(2);
}
main().catch((error) => {
console.error(error instanceof Error ? error.message : error);
process.exit(1);
});