Files
tilbudgivern/scripts/analyze-smart-packages.js
2026-07-05 08:10:59 +00:00

143 lines
4.1 KiB
JavaScript

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)}`);