#!/usr/bin/env tsx import { execSync } from 'child_process' import { existsSync, readFileSync } from 'fs' function generateQualitySummary(): string { let markdown = '# Quality Metrics Summary\n\n' const reportPath = 'quality-reports/' const sections = [ { name: '๐Ÿ” Code Quality', files: ['code-quality-reports/code-quality-reports'], icon: '๐Ÿ“Š' }, { name: '๐Ÿงช Test Coverage', files: ['coverage-reports/coverage-metrics.json'], icon: 'โœ“' }, { name: '๐Ÿ” Security', files: ['security-reports/security-report.json'], icon: '๐Ÿ›ก๏ธ' }, { name: '๐Ÿ“š Documentation', files: ['documentation-reports/jsdoc-report.json'], icon: '๐Ÿ“–' }, { name: 'โšก Performance', files: ['performance-reports/bundle-analysis.json'], icon: '๐Ÿš€' }, { name: '๐Ÿ“ฆ Dependencies', files: ['dependency-reports/license-report.json'], icon: '๐Ÿ“ฆ' }, { name: '๐ŸŽฏ Type Safety', files: ['type-reports/ts-strict-report.json'], icon: 'โœ”๏ธ' } ] markdown += '## Overview\n\n' markdown += '| Metric | Status | Details |\n' markdown += '|--------|--------|----------|\n' for (const section of sections) { let status = 'โš ๏ธ No data' let details = 'Report not available' for (const file of section.files) { const fullPath = `${reportPath}${file}` if (existsSync(fullPath)) { try { const content = readFileSync(fullPath, 'utf8') const data = JSON.parse(content) if (data.coverage) { status = data.coverage >= 80 ? 'โœ… Pass' : 'โš ๏ธ Warning' details = `${data.coverage}% coverage` } else if (data.totalIssues !== undefined) { status = data.critical === 0 ? 'โœ… Pass' : 'โŒ Issues' details = `${data.totalIssues} issues (${data.critical} critical)` } else if (data.averageCoverage) { status = data.averageCoverage >= 70 ? 'โœ… Good' : 'โš ๏ธ Needs work' details = `${data.averageCoverage.toFixed(1)}% documented` } break } catch (e) { // Continue to next file } } } markdown += `| ${section.icon} ${section.name} | ${status} | ${details} |\n` } markdown += '\n## Detailed Metrics\n\n' // Code Complexity markdown += '### Code Complexity\n\n' const complexityPath = `${reportPath}code-quality-reports/code-quality-reports/complexity-report.json` if (existsSync(complexityPath)) { try { const complexity = JSON.parse(readFileSync(complexityPath, 'utf8')) markdown += `- **Total files analyzed**: ${complexity.totalFilesAnalyzed}\n` markdown += `- **Average complexity**: ${complexity.avgMaxComplexity?.toFixed(2) || 'N/A'}\n` markdown += `- **Violations**: ${complexity.totalViolations || 0}\n\n` } catch (e) { markdown += 'No data available\n\n' } } // Security Issues markdown += '### Security Scan Results\n\n' const securityPath = `${reportPath}security-reports/security-reports/security-report.json` if (existsSync(securityPath)) { try { const security = JSON.parse(readFileSync(securityPath, 'utf8')) markdown += `- **Critical Issues**: ${security.critical || 0} โŒ\n` markdown += `- **High Severity**: ${security.high || 0} โš ๏ธ\n` markdown += `- **Medium Severity**: ${security.medium || 0} โ„น๏ธ\n` markdown += `- **Total Issues**: ${security.totalIssues || 0}\n\n` } catch (e) { markdown += 'No data available\n\n' } } // File Size Analysis markdown += '### File Size Metrics\n\n' const filesizePath = `${reportPath}size-reports/size-reports/file-sizes-report.json` if (existsSync(filesizePath)) { try { const filesize = JSON.parse(readFileSync(filesizePath, 'utf8')) markdown += `- **Files analyzed**: ${filesize.totalFilesAnalyzed}\n` markdown += `- **Violations**: ${filesize.totalViolations || 0}\n` if (filesize.largestFiles) { markdown += `- **Largest file**: ${filesize.largestFiles[0]?.file || 'N/A'} (${filesize.largestFiles[0]?.lines || 0} lines)\n` } markdown += '\n' } catch (e) { markdown += 'No data available\n\n' } } // Performance Metrics markdown += '### Performance Budget\n\n' const perfPath = `${reportPath}performance-reports/performance-reports/bundle-analysis.json` if (existsSync(perfPath)) { try { const perf = JSON.parse(readFileSync(perfPath, 'utf8')) markdown += `- **Total bundle size**: ${perf.totalBundleSize?.mb || 'N/A'}MB\n` markdown += `- **Gzip size**: ${perf.gzipSize?.mb || 'N/A'}MB\n` markdown += `- **Status**: ${perf.budgetStatus?.status === 'ok' ? 'โœ…' : 'โš ๏ธ'}\n\n` } catch (e) { markdown += 'No data available\n\n' } } markdown += '---\n\n' markdown += '## Recommendations\n\n' markdown += '- ๐ŸŽฏ Maintain test coverage above 80%\n' markdown += '- ๐Ÿ“š Add JSDoc comments to exported functions\n' markdown += '- ๐Ÿ” Address complexity warnings for better maintainability\n' markdown += '- โšก Monitor bundle size to prevent performance degradation\n' markdown += '- ๐Ÿ” Fix any security issues before merging\n' markdown += '- ๐Ÿ“– Keep documentation up to date\n\n' markdown += `**Report generated**: ${new Date().toISOString()}\n` return markdown } console.log(generateQualitySummary())