fix: auto-publish approved blog submissions on approval

Approved user submissions now import into the blog automatically, with a
backfill script for existing approvals and a WebSocket polyfill so backend
Nostr relay queries work on Node 20.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
bbe
2026-06-28 23:38:48 +02:00
co-authored by Cursor
parent a6a2b113ee
commit 99380ef6aa
8 changed files with 306 additions and 62 deletions
@@ -0,0 +1,64 @@
// One-time backfill: publish any APPROVED submissions that never got a blog
// Post (they predate auto-publish-on-approval). Idempotent — already-imported
// submissions are skipped, so it is safe to re-run.
//
// Usage (from backend/):
// npm run backfill-submissions
import { prisma } from '../src/db/prisma';
import { importPostFromNostr, resolveSubmissionImport } from '../src/services/postImport';
async function main() {
const approved = await prisma.submission.findMany({
where: { status: 'APPROVED' },
orderBy: { createdAt: 'asc' },
});
console.log(`Found ${approved.length} APPROVED submission(s).`);
let imported = 0;
let skipped = 0;
let failed = 0;
for (const submission of approved) {
const label = `"${submission.title}" (${submission.id})`;
try {
const importInput = await resolveSubmissionImport(submission);
if (!importInput) {
console.warn(` FAILED ${label}: could not resolve Nostr event from relays.`);
failed++;
continue;
}
const existing = await prisma.post.findUnique({
where: { nostrEventId: importInput.nostrEventId },
});
if (existing) {
console.log(` SKIP ${label}: already published (slug: ${existing.slug}).`);
skipped++;
continue;
}
const post = await importPostFromNostr(importInput);
console.log(` IMPORT ${label}: published (slug: ${post?.slug}).`);
imported++;
} catch (err) {
console.error(` FAILED ${label}:`, err);
failed++;
}
}
console.log(`\nDone. Imported: ${imported}, Skipped: ${skipped}, Failed: ${failed}.`);
}
main()
.then(async () => {
await prisma.$disconnect();
// The Nostr relay pool keeps websockets open, which would otherwise keep the
// process alive after the work is done.
process.exit(0);
})
.catch(async (err) => {
console.error('Backfill error:', err);
await prisma.$disconnect();
process.exit(1);
});