const fs = require('fs'); const path = require('path'); const catalogPath = path.resolve(__dirname, '../docs/features/SMART_PACKAGES_COMPLETE_CATALOG.md'); const catalog = fs.readFileSync(catalogPath, 'utf8'); const lines = catalog.split(/\r?\n/); const packages = []; let current = null; let section = null; const finalizeCurrent = () => { if (current) { current.materialCount = current.materials.length; current.taskCount = current.tasks.length; packages.push(current); } }; for (const raw of lines) { const line = raw.trimEnd(); if (line.startsWith('#### ')) { finalizeCurrent(); const headerMatch = line.match(/####\s+(.*?)(\s+\(ID:\s*(\d+)\))?$/); current = { title: headerMatch ? headerMatch[1].trim() : line.slice(4).trim(), id: headerMatch && headerMatch[3] ? parseInt(headerMatch[3], 10) : null, category: null, difficulty: null, timer: null, auto: null, materials: [], tasks: [], warnings: [], hasMaterialsSection: false, hasTasksSection: false }; section = null; continue; } if (!current) continue; if (line.startsWith('**Kategori:**')) { const parts = line.split('**'); const match = line.match(/\*\*Kategori:\*\*\s*([^|]+)\|?\s*(?:\*\*Sværhed:\*\*\s*([^|]+))?\s*(?:\|\s*\*\*Timer:\*\*\s*([^|]+))?/); if (match) { current.category = match[1]?.trim() || null; current.difficulty = match[2]?.trim() || null; current.timer = match[3]?.trim() || null; } continue; } if (line.startsWith('**Timer:**')) { const match = line.match(/\*\*Timer:\*\*\s*(.+)/); if (match) { current.timer = match[1].trim(); } continue; } if (line.startsWith('**Auto-beregning:**')) { const match = line.match(/\*\*Auto-beregning:\*\*\s*(.+)/); if (match) { current.auto = match[1].trim(); } continue; } if (line.startsWith('**Materialer')) { section = 'materials'; current.hasMaterialsSection = true; continue; } if (line.startsWith('**Opgaver')) { section = 'tasks'; current.hasTasksSection = true; continue; } if (line.startsWith('---') || line === '') { section = null; continue; } if (section === 'materials' && line.startsWith('-')) { current.materials.push(line.slice(1).trim()); continue; } if (section === 'tasks' && /^[0-9]+\.\s+/.test(line)) { current.tasks.push(line.replace(/^[0-9]+\.\s+/, '').trim()); continue; } } finalizeCurrent(); const issues = []; packages.forEach(pkg => { if (!pkg.hasMaterialsSection) { issues.push(`Package "${pkg.title}" (ID ${pkg.id || 'unknown'}) has no Materialer section.`); } if (!pkg.hasTasksSection) { issues.push(`Package "${pkg.title}" (ID ${pkg.id || 'unknown'}) has no Opgaver section.`); } if (pkg.materialCount === 0) { issues.push(`Package "${pkg.title}" (ID ${pkg.id || 'unknown'}) has 0 listed materials.`); } if (pkg.taskCount === 0) { issues.push(`Package "${pkg.title}" (ID ${pkg.id || 'unknown'}) has 0 listed tasks.`); } if (!pkg.timer) { pkg.warnings.push('Missing timer estimate.'); } if (!pkg.auto) { pkg.warnings.push('Missing auto-beregning description.'); } }); console.log('🏗️ Smart Package Catalog Analysis'); console.log(` - Parsed ${packages.length} packages from SMART_PACKAGES_COMPLETE_CATALOG.md`); console.log(` - Total issues detected: ${issues.length}`); if (issues.length) { issues.forEach(issue => console.log(` • ${issue}`)); } const packagesWithWarnings = packages.filter(pkg => pkg.warnings.length); if (packagesWithWarnings.length) { console.log(` - ${packagesWithWarnings.length} packages have extra warnings:`); packagesWithWarnings.forEach(pkg => { console.log(` • ${pkg.title} (ID ${pkg.id || 'unknown'}): ${pkg.warnings.join('; ')}`); }); } const totalTasks = packages.reduce((sum, pkg) => sum + pkg.taskCount, 0); const totalMaterials = packages.reduce((sum, pkg) => sum + pkg.materialCount, 0); console.log(` - Average tasks per package: ${(totalTasks / packages.length).toFixed(1)}`); console.log(` - Average materials per package: ${(totalMaterials / packages.length).toFixed(1)}`);