From 87cf83e54acc359c09b1783842e405eaf2378595 Mon Sep 17 00:00:00 2001 From: TheFlow Date: Sun, 12 Oct 2025 21:21:35 +1300 Subject: [PATCH] fix: improve category migration script with precise slug-based mapping - Replace fuzzy title matching with explicit slug-to-category mapping - Add 'advanced-topics' category for value pluralism and research docs - Redistribute deployment docs to appropriate categories - Move internal docs (Koha, Phase guides) to archived - Fixes docs.html sidebar categories not collapsing (4th attempt) - Root cause: Production MongoDB documents lacked category field --- scripts/migrate-doc-categories.js | 142 ++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100755 scripts/migrate-doc-categories.js diff --git a/scripts/migrate-doc-categories.js b/scripts/migrate-doc-categories.js new file mode 100755 index 00000000..0def6367 --- /dev/null +++ b/scripts/migrate-doc-categories.js @@ -0,0 +1,142 @@ +#!/usr/bin/env node +/** + * Migrate documents to new granular category structure + * + * New Categories: + * - getting-started: Introduction, core concepts, quick start, FAQ + * - technical-reference: API docs, implementation guides, code examples + * - research-theory: Research papers, theoretical foundations + * - case-studies: Real-world examples, failure modes, success stories + * - deployment-operations: Deployment guides, architecture, troubleshooting + * - business-leadership: Business cases, executive briefs, ROI analysis + * - downloads-resources: PDFs, sample configs, external links + */ + +// Load environment variables +require('dotenv').config(); + +const { getDb } = require('../src/utils/db.util'); + +// Slug-to-category mapping (precise, no fuzzy matching) +const slugToCategory = { + // Getting Started + 'introduction-to-the-tractatus-framework': 'getting-started', + 'core-concepts-of-the-tractatus-framework': 'getting-started', + 'value-pluralism-faq': 'getting-started', + + // Technical Reference + 'api-reference-complete': 'technical-reference', + 'openapi-specification': 'technical-reference', + 'implementation-guide': 'technical-reference', + 'tractatus-framework-implementation-guide': 'technical-reference', + 'api-python-examples': 'technical-reference', + 'api-javascript-examples': 'technical-reference', + 'technical-architecture-diagram': 'technical-reference', + 'technical-architecture': 'technical-reference', + 'tractatus-agentic-governance-system-glossary-of-terms': 'technical-reference', + 'comparison-matrix-claude-code-claudemd-and-tractatus-framework': 'technical-reference', + + // Research & Theory + 'organizational-theory-foundations-of-the-tractatus-framework': 'research-theory', + 'research-foundations-scholarly-review-and-context': 'research-theory', + 'executive-brief-tractatus-based-llm-architecture-for-ai-safety': 'research-theory', + 'structural-governance-for-agentic-ai-the-tractatus-inflection-point': 'research-theory', + 'tractatus-ai-safety-framework-core-values-and-principles': 'research-theory', + 'architectural-overview-and-research-status': 'research-theory', + + // Advanced Topics + 'pluralistic-values-research-foundations': 'advanced-topics', + 'pluralistic-values-deliberation-plan-v2': 'advanced-topics', + 'research-scope-feasibility-of-llm-integrated-tractatus-framework': 'advanced-topics', + 'research-topic-rule-proliferation-and-transactional-overhead-in-ai-governance': 'advanced-topics', + 'research-topic-concurrent-session-architecture-limitations-in-claude-code-governance': 'advanced-topics', + + // Case Studies + 'case-studies-real-world-llm-failure-modes': 'case-studies', + 'the-27027-incident-a-case-study-in-pattern-recognition-bias': 'case-studies', + 'our-framework-in-action-detecting-and-correcting-ai-fabrications': 'case-studies', + 'framework-governance-in-action-pre-publication-security-audit': 'case-studies', + 'when-frameworks-fail-and-why-thats-ok': 'case-studies', + 'real-world-ai-governance-a-case-study-in-framework-failure-and-recovery': 'case-studies', + + // Business & Leadership + 'ai-governance-business-case-template-tractatus-framework': 'business-leadership', + 'business-case-for-ai-governance-tractatus-framework': 'business-leadership', + 'executive-summary-tractatus-inflection-point': 'business-leadership', + 'implementation-roadmap-24-month-deployment-plan': 'business-leadership', + + // Archived + 'phase-2': 'archived', + 'phase-3': 'archived', + 'phase-5-poc-session-1-summary': 'archived', + 'phase-5-poc-session-2-summary': 'archived' +}; + +async function migrateCategories() { + console.log('šŸ”„ Migrating document categories to new structure...\n'); + + const db = await getDb(); + const collection = db.collection('documents'); + + // Get all documents + const documents = await collection.find({}).toArray(); + console.log(`šŸ“š Found ${documents.length} documents\n`); + + let updated = 0; + let errors = 0; + + for (const doc of documents) { + try { + // Use slug-based mapping (precise) + const newCategory = slugToCategory[doc.slug] || 'technical-reference'; + + // Update document if category changed + if (doc.category !== newCategory) { + await collection.updateOne( + { _id: doc._id }, + { + $set: { + category: newCategory, + 'metadata.date_updated': new Date() + } + } + ); + + console.log(`āœ… Updated: "${doc.title}"`); + console.log(` Category: ${doc.category || 'none'} → ${newCategory}\n`); + updated++; + } + } catch (error) { + console.error(`āŒ Error updating "${doc.title}":`, error.message); + errors++; + } + } + + console.log('\n' + '='.repeat(60)); + console.log('šŸ“Š Migration Summary:'); + console.log('='.repeat(60)); + console.log(`Total documents: ${documents.length}`); + console.log(`āœ… Updated: ${updated}`); + console.log(`ā­ļø Unchanged: ${documents.length - updated - errors}`); + console.log(`āŒ Errors: ${errors}`); + console.log('='.repeat(60)); + + // Show category breakdown + console.log('\nšŸ“‚ Category Breakdown:'); + const categoryCounts = await collection.aggregate([ + { $group: { _id: '$category', count: { $sum: 1 } } }, + { $sort: { count: -1 } } + ]).toArray(); + + categoryCounts.forEach(({ _id, count }) => { + console.log(` ${_id || 'none'}: ${count}`); + }); + + process.exit(0); +} + +// Run migration +migrateCategories().catch(error => { + console.error('āŒ Migration failed:', error); + process.exit(1); +});