Files
memind/scripts/backfill-plaza-cover-urls.mjs
T
john ed910a68ca
Memind CI / Test, build, and release guards (push) Has been cancelled
chore(plaza): add 103 backfill scripts for cover URLs and hero thumbnails
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-29 16:15:45 +08:00

93 lines
2.9 KiB
JavaScript

#!/usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { createDbPool } from '../db.mjs';
import { resolvePlazaPublicationCoverUrl } from '../plaza-posts.mjs';
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
const shouldWrite = process.argv.includes('--write');
const batchPrefix = (() => {
const idx = process.argv.indexOf('--batch-prefix');
return idx >= 0 ? String(process.argv[idx + 1] ?? '').trim() : '';
})();
function loadEnvFile(filePath) {
if (!fs.existsSync(filePath)) return;
for (const line of fs.readFileSync(filePath, 'utf8').split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
const eq = trimmed.indexOf('=');
if (eq < 0) continue;
const key = trimmed.slice(0, eq).trim();
const value = trimmed.slice(eq + 1).trim();
if (!process.env[key]) process.env[key] = value;
}
}
loadEnvFile(path.join(root, '../../.env.local'));
loadEnvFile(path.join(root, '.env'));
const pool = createDbPool();
const params = [];
let batchFilter = '';
if (batchPrefix) {
batchFilter = ' AND p.workspace_relative_path LIKE ?';
params.push(`public/${batchPrefix}%`);
}
const [rows] = await pool.query(
`SELECT pp.id, pp.title, pp.cover_url, pp.user_slug, pp.status,
pr.public_url, pr.url_slug
FROM plaza_posts pp
JOIN h5_publish_records pr ON pr.id = pp.publication_id
JOIN h5_page_records p ON p.id = pr.page_id
WHERE pp.status IN ('published', 'pending_review', 'rejected')
${batchFilter}
ORDER BY pp.published_at DESC, pp.id DESC`,
params,
);
const updates = rows
.map((row) => ({
id: row.id,
title: row.title,
from: String(row.cover_url ?? ''),
to: resolvePlazaPublicationCoverUrl({
inputCoverUrl: row.cover_url,
publicUrl: row.public_url,
publicationUrlSlug: row.url_slug,
userSlug: row.user_slug,
}),
publicUrl: String(row.public_url ?? ''),
}))
.filter((row) => row.to && row.from !== row.to);
console.log(
`${shouldWrite ? '写入模式' : 'Dry-run'}:共扫描 ${rows.length} 条帖子,命中 ${updates.length} 条待补封面。`,
);
for (const row of updates.slice(0, 20)) {
console.log(`- ${row.id} | ${row.title}`);
console.log(` ${row.from || '(empty)'} -> ${row.to}`);
}
if (updates.length > 20) {
console.log(`... 其余 ${updates.length - 20} 条省略`);
}
if (shouldWrite && updates.length > 0) {
const now = Date.now();
for (const row of updates) {
await pool.query(`UPDATE plaza_posts SET cover_url = ?, updated_at = ? WHERE id = ?`, [
row.to,
now,
row.id,
]);
}
console.log(`已更新 ${updates.length} 条帖子封面。`);
} else if (!shouldWrite) {
console.log('未写入数据库;如需正式回填,请执行: node scripts/backfill-plaza-cover-urls.mjs --write');
}
await pool.end();