This commit includes two major improvements to the documentation system: ## 1. Section Recategorization (UX Fix) **Problem**: 64 sections (24%) were incorrectly marked as "critical" and displayed at the bottom of documents, burying important foundational content. **Solution**: - Created intelligent recategorization script analyzing titles, excerpts, and document context - Reduced "critical" from 64 → 2 sections (97% reduction) - Properly categorized content by purpose: - Conceptual: 63 → 138 (+119%) - foundations, "why this matters" - Practical: 3 → 46 (+1433%) - how-to guides, examples - Technical: 111 → 50 (-55%) - true implementation details **UI Improvements**: - Reordered category display: Critical → Conceptual → Practical → Technical → Reference - Changed Critical color from amber to red for better visual distinction - All 22 documents recategorized (173 sections updated) ## 2. i18n Infrastructure (Phase 2) **Backend**: - DeepL API integration service with quota management and error handling - Translation API routes (GET /api/documents/:slug?lang=de, POST /api/documents/:id/translate) - Document model already supports translations field (no schema changes) **Frontend**: - docs-app.js enhanced with language detection and URL parameter support - Automatic fallback to English when translation unavailable - Integration with existing i18n-simple.js system **Scripts**: - translate-all-documents.js: Batch translation workflow (dry-run support) - audit-section-categories.js: Category distribution analysis **URL Strategy**: Query parameter approach (?lang=de, ?lang=fr) **Status**: Backend complete, ready for DeepL API key configuration **Files Modified**: - Frontend: document-cards.js, docs-app.js - Backend: documents.controller.js, documents.routes.js, DeepL.service.js - Scripts: 3 new governance/i18n scripts **Database**: 173 sections recategorized via script (already applied) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
2.7 KiB
JavaScript
66 lines
2.7 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const { MongoClient } = require('mongodb');
|
|
|
|
(async () => {
|
|
const client = await MongoClient.connect('mongodb://localhost:27017/tractatus_dev');
|
|
const db = client.db();
|
|
|
|
const docs = await db.collection('documents')
|
|
.find({visibility: 'public'}, {projection: {title: 1, slug: 1, sections: 1}})
|
|
.sort({order: 1})
|
|
.toArray();
|
|
|
|
console.log('═══════════════════════════════════════════════════════════');
|
|
console.log(' SECTION CATEGORY AUDIT - 22 Public Documents');
|
|
console.log('═══════════════════════════════════════════════════════════\n');
|
|
|
|
let totalDocs = 0;
|
|
let docsWithSections = 0;
|
|
const categoryStats = {};
|
|
|
|
docs.forEach(doc => {
|
|
totalDocs++;
|
|
|
|
if (!doc.sections || doc.sections.length === 0) {
|
|
console.log(`${doc.title}:`);
|
|
console.log(' ⚠️ NO SECTIONS (traditional view)\n');
|
|
return;
|
|
}
|
|
|
|
docsWithSections++;
|
|
const categories = {};
|
|
doc.sections.forEach(s => {
|
|
const cat = s.category || 'uncategorized';
|
|
categories[cat] = (categories[cat] || 0) + 1;
|
|
categoryStats[cat] = (categoryStats[cat] || 0) + 1;
|
|
});
|
|
|
|
console.log(`${doc.title}:`);
|
|
console.log(` Sections: ${doc.sections.length}`);
|
|
Object.entries(categories).sort((a,b) => b[1] - a[1]).forEach(([cat, count]) => {
|
|
const percent = Math.round(count / doc.sections.length * 100);
|
|
console.log(` - ${cat}: ${count} (${percent}%)`);
|
|
});
|
|
console.log('');
|
|
});
|
|
|
|
console.log('═══════════════════════════════════════════════════════════');
|
|
console.log(' OVERALL STATISTICS');
|
|
console.log('═══════════════════════════════════════════════════════════\n');
|
|
console.log(`Total documents: ${totalDocs}`);
|
|
console.log(`Documents with sections: ${docsWithSections}`);
|
|
console.log(`Documents without sections: ${totalDocs - docsWithSections}\n`);
|
|
|
|
console.log('Category distribution across ALL sections:');
|
|
const sortedStats = Object.entries(categoryStats).sort((a,b) => b[1] - a[1]);
|
|
const totalSections = sortedStats.reduce((sum, [,count]) => sum + count, 0);
|
|
|
|
sortedStats.forEach(([cat, count]) => {
|
|
const percent = Math.round(count / totalSections * 100);
|
|
console.log(` - ${cat}: ${count} sections (${percent}%)`);
|
|
});
|
|
|
|
console.log('\n');
|
|
await client.close();
|
|
})();
|