tractatus/scripts/fix-blog-dates.js
TheFlow 2211f8156a feat(blog): add scripts for date fixes, categories, and governance banners
Three scripts to support blog system improvements:

1. fix-blog-dates.js
   - Fixes empty {} published_at values in database
   - Sets proper ISODate values for 3 blogs
   - Also updates moderation.approved_at for consistency

2. add-blog-categories.js
   - Adds category field to all blog posts
   - Maps content to standardized categories (Framework Updates,
     Implementation, Case Studies)
   - Enables category filtering functionality

3. add-vetting-notice-to-architectural-boundaries.js
   - Adds comprehensive human vetting notice
   - Documents AI-curated content review process
   - Shows governance working end-to-end with inst_017 compliance

Applied to both tractatus_dev and tractatus_prod databases.

Ref: SESSION_HANDOFF_2025-10-23_WEBSITE_AUDIT.md
2025-10-23 10:55:50 +13:00

107 lines
3 KiB
JavaScript

/**
* Fix Blog Published Dates
* Replace empty {} objects with proper ISO date strings
*/
const { MongoClient } = require('mongodb');
const DEV_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017';
const DEV_DB = process.env.MONGODB_DB || 'tractatus_dev';
// Date assignments based on blog content context
const DATE_FIXES = [
{
slug: 'scaling-tractatus-roadmap',
date: new Date('2025-10-15T10:00:00Z'), // Mid-October (roadmap blog)
title: 'How to Scale Tractatus: Breaking the Chicken-and-Egg Problem'
},
{
slug: 'introducing-tractatus-framework',
date: new Date('2025-10-05T09:00:00Z'), // Early October (inaugural post)
title: 'Introducing the Tractatus Framework'
},
{
slug: 'why-ai-safety-requires-architectural-boundaries-not-just-training',
date: new Date('2025-10-22T20:00:00Z'), // Just fixed and deployed today
title: 'Why AI Safety Requires Architectural Boundaries'
}
];
async function fixDates() {
const client = new MongoClient(DEV_URI);
try {
console.log('📅 Fixing Blog Published Dates\n');
console.log('═'.repeat(70));
await client.connect();
const db = client.db(DEV_DB);
const collection = db.collection('blog_posts');
let fixedCount = 0;
for (const fix of DATE_FIXES) {
console.log(`\n📄 ${fix.title}`);
console.log(` Slug: ${fix.slug}`);
const blog = await collection.findOne({ slug: fix.slug });
if (!blog) {
console.log(` ❌ Blog not found`);
continue;
}
// Check if published_at is empty object or invalid
const currentDate = blog.published_at;
const needsFix = !currentDate ||
(typeof currentDate === 'object' && Object.keys(currentDate).length === 0) ||
currentDate.toString() === '[object Object]';
if (needsFix) {
const result = await collection.updateOne(
{ slug: fix.slug },
{
$set: {
published_at: fix.date,
'moderation.approved_at': fix.date // Also update approval date for consistency
}
}
);
if (result.modifiedCount === 1) {
console.log(` ✅ Fixed: ${fix.date.toISOString()}`);
fixedCount++;
} else {
console.log(` ❌ Update failed`);
}
} else {
console.log(` ⚠️ Already has valid date: ${currentDate}`);
}
}
console.log('\n' + '═'.repeat(70));
console.log(`\n✨ Complete: ${fixedCount}/${DATE_FIXES.length} dates fixed\n`);
return fixedCount > 0;
} catch (error) {
console.error('❌ Error:', error.message);
throw error;
} finally {
await client.close();
}
}
// Run if called directly
if (require.main === module) {
fixDates()
.then((success) => {
process.exit(success ? 0 : 1);
})
.catch(error => {
console.error('\n💥 Failed:', error);
process.exit(1);
});
}
module.exports = { fixDates, DATE_FIXES };